Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓to navigate, Ctrl+🖱️to focus. On Mac, use Cmdinstead of Ctrl.
import Pretty.Defs.Factory
import Pretty.Supports.FactoryMath

/-!
## Basic definitions

### Layout
-/

/--
Layout definition. We encode it as a pair of `String` and `List String` 
so that the layout always has at least one line (Section 3.1)
-/ 
structure 
Layout: StringList StringLayout
Layout
where
fst: LayoutString
fst
:
String: Type
String
rst: LayoutList String
rst
:
List: Type ?u.6 → Type ?u.6
List
String: Type
String
def
Layout.max_with_offset: Layout
Layout.max_with_offset
:
: Type
Layout: Type
Layout
: Type
|
col_pos:
col_pos
, { fst :=
fst: String
fst
, rst := rst } =>
max: {α : Type ?u.381} → [self : Max α] → ααα
max
(
col_pos:
col_pos
+
fst: String
fst
.
length: String
length
) ((rst.
map: {α : Type ?u.438} → {β : Type ?u.437} → (αβ) → List αList β
map
String.length: String
String.length
).
foldl: {α : Type ?u.450} → {β : Type ?u.449} → (αβα) → αList βα
foldl
max: {α : Type ?u.458} → [self : Max α] → ααα
max
0: ?m.492
0
) /-! ### Document -/ /-- Document definition (syntax of $\Sigma_e$, Figure 4) -/ inductive
Doc: Sort ?u.760
Doc
where |
text: StringDoc
text
(s :
String: Type
String
) :
Doc: Sort ?u.760
Doc
|
nl: Doc
nl
:
Doc: Sort ?u.760
Doc
|
concat: DocDocDoc
concat
(
d₁: Doc
d₁
d₂: Doc
d₂
:
Doc: Sort ?u.760
Doc
) :
Doc: Sort ?u.760
Doc
|
nest: DocDoc
nest
(
n:
n
:
Nat: Type
Nat
) (
d: Doc
d
:
Doc: Sort ?u.760
Doc
) :
Doc: Sort ?u.760
Doc
|
align: DocDoc
align
(
d: Doc
d
:
Doc: Sort ?u.760
Doc
) :
Doc: Sort ?u.760
Doc
|
choice: DocDocDoc
choice
(
d₁: Doc
d₁
d₂: Doc
d₂
:
Doc: Sort ?u.760
Doc
) :
Doc: Sort ?u.760
Doc
def
Doc.size: Doc
Doc.size
:
Doc: Type
Doc
: Type
|
Doc.text: StringDoc
Doc.text
_ =>
1: ?m.1939
1
|
Doc.nl: Doc
Doc.nl
=>
1: ?m.1954
1
|
Doc.concat: DocDocDoc
Doc.concat
d₁: Doc
d₁
d₂: Doc
d₂
=>
Doc.size: Doc
Doc.size
d₁: Doc
d₁
+
Doc.size: Doc
Doc.size
d₂: Doc
d₂
+
1: ?m.1979
1
|
Doc.nest: DocDoc
Doc.nest
_
d: Doc
d
=>
Doc.size: Doc
Doc.size
d: Doc
d
+
1: ?m.2072
1
|
Doc.align: DocDoc
Doc.align
d: Doc
d
=>
Doc.size: Doc
Doc.size
d: Doc
d
+
1: ?m.2132
1
|
Doc.choice: DocDocDoc
Doc.choice
d₁: Doc
d₁
d₂: Doc
d₂
=>
Doc.size: Doc
Doc.size
d₁: Doc
d₁
+
Doc.size: Doc
Doc.size
d₂: Doc
d₂
+
1: ?m.2201
1
/-- Choiceless document definition (Section 3.2) We make it a predicate of `Doc`, since it's a subset of `Doc`. -/ inductive
Choiceless: DocProp
Choiceless
:
Doc: Type
Doc
Prop: Type
Prop
where |
text: ∀ (s : String), Choiceless (Doc.text s)
text
(s :
String: Type
String
) :
Choiceless: DocProp
Choiceless
(
Doc.text: StringDoc
Doc.text
s) | nl :
Choiceless: DocProp
Choiceless
Doc.nl: Doc
Doc.nl
|
concat: ∀ (d₁ d₂ : Doc), Choiceless d₁Choiceless d₂Choiceless (Doc.concat d₁ d₂)
concat
(
d₁: Doc
d₁
d₂: Doc
d₂
:
Doc: Type
Doc
) (
h₁: Choiceless d₁
h₁
:
Choiceless: DocProp
Choiceless
d₁: Doc
d₁
) (
h₂: Choiceless d₂
h₂
:
Choiceless: DocProp
Choiceless
d₂: Doc
d₂
) :
Choiceless: DocProp
Choiceless
(
Doc.concat: DocDocDoc
Doc.concat
d₁: Doc
d₁
d₂: Doc
d₂
) |
nest: ∀ (n : ) (d : Doc), Choiceless dChoiceless (Doc.nest n d)
nest
(
n:
n
:
Nat: Type
Nat
) (
d: Doc
d
:
Doc: Type
Doc
) (
h: Choiceless d
h
:
Choiceless: DocProp
Choiceless
d: Doc
d
) :
Choiceless: DocProp
Choiceless
(
Doc.nest: DocDoc
Doc.nest
n:
n
d: Doc
d
) |
align: ∀ (d : Doc), Choiceless dChoiceless (Doc.align d)
align
(
d: Doc
d
:
Doc: Type
Doc
) (
h: Choiceless d
h
:
Choiceless: DocProp
Choiceless
d: Doc
d
) :
Choiceless: DocProp
Choiceless
(
Doc.align: DocDoc
Doc.align
d: Doc
d
) /-! ### Rendering and widening -/ /-- Rendering relation definition ($⇓_\mathcal{R}$, Figure 6) -/ inductive
Render: DocLayoutProp
Render
:
Doc: Type
Doc
: Type
: Type
Layout: Type
Layout
Prop: Type
Prop
where |
text: ∀ {s : String} {c i : }, Render (Doc.text s) c i { fst := s, rst := [] }
text
:
Render: DocLayoutProp
Render
(
Doc.text: StringDoc
Doc.text
s: ?m.3210
s
)
c: ?m.3214
c
i: ?m.3218
i
(
Layout.mk: StringList StringLayout
Layout.mk
s: ?m.3210
s
[]: List ?m.3222
[]
) |
nl: ∀ {c i : }, Render Doc.nl c i { fst := "", rst := [List.asString (List.replicate i (Char.ofNat 32))] }
nl
:
Render: DocLayoutProp
Render
Doc.nl: Doc
Doc.nl
c: ?m.3229
c
i: ?m.3233
i
(
Layout.mk: StringList StringLayout
Layout.mk
"": String
""
[
List.asString: List CharString
List.asString
(
List.replicate: {α : Type ?u.3238} → αList α
List.replicate
i: ?m.3233
i
' ': Char
' '
)]) |
concat_one: ∀ {d₁ : Doc} {c i : } {s : String} {d₂ : Doc} {t : String} {ts : List String}, Render d₁ c i { fst := s, rst := [] }Render d₂ (c + String.length s) i { fst := t, rst := ts }Render (Doc.concat d₁ d₂) c i { fst := s ++ t, rst := ts }
concat_one
(
h₁: Render d₁ c i { fst := s, rst := [] }
h₁
:
Render: DocLayoutProp
Render
d₁: ?m.3246
d₁
c: ?m.3250
c
i: ?m.3254
i
(
Layout.mk: StringList StringLayout
Layout.mk
s: ?m.3258
s
[]: List ?m.3352
[]
)) (
h₂: Render d₂ (c + String.length s) i { fst := t, rst := ts }
h₂
:
Render: DocLayoutProp
Render
d₂: ?m.3266
d₂
(
c: ?m.3250
c
+
s: ?m.3258
s
.
length: String
length
)
i: ?m.3254
i
(
Layout.mk: StringList StringLayout
Layout.mk
t: ?m.3315
t
ts: ?m.3348
ts
)) :
Render: DocLayoutProp
Render
(
Doc.concat: DocDocDoc
Doc.concat
d₁: ?m.3246
d₁
d₂: ?m.3266
d₂
)
c: ?m.3250
c
i: ?m.3254
i
(
Layout.mk: StringList StringLayout
Layout.mk
(
s: ?m.3258
s
++
t: ?m.3315
t
)
ts: ?m.3348
ts
) |
concat_multi: ∀ {ss : List String} {slast : String} {d₁ : Doc} {c i : } {s : String} {d₂ : Doc} {t : String} {ts : List String} (h_non_empty : ss []), slast = List.getLast ss h_non_emptyRender d₁ c i { fst := s, rst := ss }Render d₂ (String.length slast) i { fst := t, rst := ts }Render (Doc.concat d₁ d₂) c i { fst := s, rst := List.dropLast ss ++ [slast ++ t] ++ ts }
concat_multi
(
h_non_empty: ss []
h_non_empty
:
ss: ?m.3429
ss
[]: List ?m.3610
[]
) (
h_last: unknown metavariable '?_uniq.3523'
h_last
:
slast: ?m.3442
slast
=
List.getLast: {α : Type ?u.3616} → (as : List α) → as []α
List.getLast
ss: ?m.3429
ss
(

Goals accomplished! 🐙
ss: List String

slast: String

d₁: Doc

c, i:

s: String

d₂: Doc

t: String

ts: List String

h_non_empty: ss []


ss []

Goals accomplished! 🐙
)) (
h₁: Render d₁ c i { fst := s, rst := ss }
h₁
:
Render: DocLayoutProp
Render
d₁: ?m.3464
d₁
c: ?m.3486
c
i: ?m.3508
i
(
Layout.mk: StringList StringLayout
Layout.mk
s: ?m.3530
s
ss: ?m.3429
ss
)) (
h₂: Render d₂ (String.length slast) i { fst := t, rst := ts }
h₂
:
Render: DocLayoutProp
Render
d₂: ?m.3554
d₂
slast: ?m.3442
slast
.
length: String
length
i: ?m.3508
i
(
Layout.mk: StringList StringLayout
Layout.mk
t: ?m.3579
t
ts: ?m.3604
ts
)) :
Render: DocLayoutProp
Render
(
Doc.concat: DocDocDoc
Doc.concat
d₁: ?m.3464
d₁
d₂: ?m.3554
d₂
)
c: ?m.3486
c
i: ?m.3508
i
(
Layout.mk: StringList StringLayout
Layout.mk
s: ?m.3530
s
((
List.dropLast: {α : Type ?u.3636} → List αList α
List.dropLast
ss: ?m.3429
ss
) ++ [
slast: ?m.3442
slast
++
t: ?m.3579
t
] ++
ts: ?m.3604
ts
)) |
nest: ∀ {d : Doc} {c i n : } {L : Layout}, Render d c (i + n) LRender (Doc.nest n d) c i L
nest
(
h: Render d c (i + n) L
h
:
Render: DocLayoutProp
Render
d: ?m.3727
d
c: ?m.3731
c
(
i: ?m.3738
i
+
n: ?m.3745
n
)
L: ?m.3773
L
) :
Render: DocLayoutProp
Render
(
Doc.nest: DocDoc
Doc.nest
n: ?m.3745
n
d: ?m.3727
d
)
c: ?m.3731
c
i: ?m.3738
i
L: ?m.3773
L
|
align: ∀ {d : Doc} {c : } {L : Layout} {i : }, Render d c c LRender (Doc.align d) c i L
align
(
h: Render d c c L
h
:
Render: DocLayoutProp
Render
d: ?m.3810
d
c: ?m.3814
c
c: ?m.3814
c
L: ?m.3818
L
) :
Render: DocLayoutProp
Render
(
Doc.align: DocDoc
Doc.align
d: ?m.3810
d
)
c: ?m.3814
c
i: ?m.3824
i
L: ?m.3818
L
/-- Widening relation definition ($⇓_\mathcal{W}$, Figure 6) -/ inductive
Widen: DocList DocProp
Widen
:
Doc: Type
Doc
List: Type ?u.4563 → Type ?u.4563
List
Doc: Type
Doc
Prop: Type
Prop
where |
text: ∀ (s : String), Widen (Doc.text s) [Doc.text s]
text
(s :
String: Type
String
) :
Widen: DocList DocProp
Widen
(
Doc.text: StringDoc
Doc.text
s) [
Doc.text: StringDoc
Doc.text
s] | nl :
Widen: DocList DocProp
Widen
Doc.nl: Doc
Doc.nl
[
Doc.nl: Doc
Doc.nl
] |
concat: ∀ {d₁ : Doc} {L₁ : List Doc} {d₂ : Doc} {L₂ : List Doc}, Widen d₁ L₁Widen d₂ L₂Widen (Doc.concat d₁ d₂) (List.join (List.map (fun d₁ => List.map (fun d₂ => Doc.concat d₁ d₂) L₂) L₁))
concat
(
h₁: Widen d₁ L₁
h₁
:
Widen: DocList DocProp
Widen
d₁: ?m.4584
d₁
L₁: ?m.4588
L₁
) (
h₂: Widen d₂ L₂
h₂
:
Widen: DocList DocProp
Widen
d₂: ?m.4594
d₂
L₂: ?m.4600
L₂
) :
Widen: DocList DocProp
Widen
(
Doc.concat: DocDocDoc
Doc.concat
d₁: ?m.4584
d₁
d₂: ?m.4594
d₂
) (
L₁: ?m.4588
L₁
.
map: {α : Type ?u.4608} → {β : Type ?u.4607} → (αβ) → List αList β
map
(fun
d₁: ?m.4616
d₁
=>
L₂: ?m.4600
L₂
.
map: {α : Type ?u.4619} → {β : Type ?u.4618} → (αβ) → List αList β
map
(fun
d₂: ?m.4628
d₂
=>
Doc.concat: DocDocDoc
Doc.concat
d₁: ?m.4616
d₁
d₂: ?m.4628
d₂
))).
join: {α : Type ?u.4634} → List (List α)List α
join
|
nest: ∀ {d : Doc} {L : List Doc} {n : }, Widen d LWiden (Doc.nest n d) (List.map (fun d => Doc.nest n d) L)
nest
(
h: Widen d L
h
:
Widen: DocList DocProp
Widen
d: ?m.4646
d
L: ?m.4650
L
) :
Widen: DocList DocProp
Widen
(
Doc.nest: DocDoc
Doc.nest
n: ?m.4656
n
d: ?m.4646
d
) (
L: ?m.4650
L
.
map: {α : Type ?u.4662} → {β : Type ?u.4661} → (αβ) → List αList β
map
(fun
d: ?m.4670
d
=>
Doc.nest: DocDoc
Doc.nest
n: ?m.4656
n
d: ?m.4670
d
)) |
align: ∀ {d : Doc} {L : List Doc}, Widen d LWiden (Doc.align d) (List.map (fun d => Doc.align d) L)
align
(
h: Widen d L
h
:
Widen: DocList DocProp
Widen
d: ?m.4680
d
L: ?m.4684
L
) :
Widen: DocList DocProp
Widen
(
Doc.align: DocDoc
Doc.align
d: ?m.4680
d
) (
L: ?m.4684
L
.
map: {α : Type ?u.4690} → {β : Type ?u.4689} → (αβ) → List αList β
map
(fun
d: ?m.4698
d
=>
Doc.align: DocDoc
Doc.align
d: ?m.4698
d
)) |
choice: ∀ {d₁ : Doc} {L₁ : List Doc} {d₂ : Doc} {L₂ : List Doc}, Widen d₁ L₁Widen d₂ L₂Widen (Doc.choice d₁ d₂) (L₁ ++ L₂)
choice
(
h₁: Widen d₁ L₁
h₁
:
Widen: DocList DocProp
Widen
d₁: ?m.4707
d₁
L₁: ?m.4711
L₁
) (
h₂: Widen d₂ L₂
h₂
:
Widen: DocList DocProp
Widen
d₂: ?m.4717
d₂
L₂: ?m.4723
L₂
) :
Widen: DocList DocProp
Widen
(
Doc.choice: DocDocDoc
Doc.choice
d₁: ?m.4707
d₁
d₂: ?m.4717
d₂
) (
L₁: ?m.4711
L₁
++
L₂: ?m.4723
L₂
) section Meas /-! ### Measure -/ variable {
α: Type
α
:
Type: Type 1
Type
} variable (
F: Factory α
F
:
Factory: TypeType
Factory
α: Type
α
) /-- Measure definition (Figure 10) -/ structure
Meas: {α : Type} → Type
Meas
where
last: {α : Type} → Meas
last
:
: Type
cost: {α : Type} → Measα
cost
:
α: Type
α
doc: {α : Type} → MeasDoc
doc
:
Doc: Type
Doc
x: {α : Type} → Meas
x
:
: Type
y: {α : Type} → Meas
y
:
: Type
/-! ### Various measure operations (Figure 10) -/ /-- - adjustAlign; -/ def
Meas.adjust_align: MeasMeas
Meas.adjust_align
(
i:
i
:
: Type
): @
Meas: {α : Type} → Type
Meas
α: Type
α
→ @
Meas: {α : Type} → Type
Meas
α: Type
α
| ⟨
last:
last
,
cost: α
cost
,
doc: Doc
doc
,
x:
x
,
y:
y
⟩ => ⟨
last:
last
,
cost: α
cost
,
Doc.align: DocDoc
Doc.align
doc: Doc
doc
,
x:
x
,
max: {α : Type ?u.6044} → [self : Max α] → ααα
max
i:
i
y:
y
⟩ /-- - adjustNest; -/ def
Meas.adjust_nest: {α : Type} → MeasMeas
Meas.adjust_nest
(
n:
n
:
: Type
): @
Meas: {α : Type} → Type
Meas
α: Type
α
→ @
Meas: {α : Type} → Type
Meas
α: Type
α
| ⟨
last:
last
,
cost: α
cost
,
doc: Doc
doc
,
x:
x
,
y:
y
⟩ => ⟨
last:
last
,
cost: α
cost
,
Doc.nest: DocDoc
Doc.nest
n:
n
doc: Doc
doc
,
x:
x
,
y:
y
⟩ /-- - concatenation (∘); and -/ @[reducible] def
Meas.concat: {α : Type} → Factory αMeasMeasMeas
Meas.concat
: @
Meas: {α : Type} → Type
Meas
α: Type
α
→ @
Meas: {α : Type} → Type
Meas
α: Type
α
→ @
Meas: {α : Type} → Type
Meas
α: Type
α
| ⟨_,
cost₁: α
cost₁
,
d₁: Doc
d₁
,
x₁:
x₁
,
y₁:
y₁
⟩, ⟨
last₂:
last₂
,
cost₂: α
cost₂
,
d₂: Doc
d₂
,
x₂:
x₂
,
y₂:
y₂
⟩ => ⟨
last₂:
last₂
,
F: Factory α
F
.
concat: {α : Type} → Factory αααα
concat
cost₁: α
cost₁
cost₂: α
cost₂
,
Doc.concat: DocDocDoc
Doc.concat
d₁: Doc
d₁
d₂: Doc
d₂
,
max: {α : Type ?u.6748} → [self : Max α] → ααα
max
x₁:
x₁
x₂:
x₂
,
max: {α : Type ?u.6775} → [self : Max α] → ααα
max
y₁:
y₁
y₂:
y₂
⟩ /-- - domination (≼) -/ def
dominates: MeasMeasBool
dominates
(
m₁: Meas
m₁
m₂: Meas
m₂
: @
Meas: {α : Type} → Type
Meas
α: Type
α
) :
Bool: Type
Bool
:=
m₁: Meas
m₁
.
last: {α : Type} → Meas
last
m₂: Meas
m₂
.
last: {α : Type} → Meas
last
F: Factory α
F
.
le: {α : Type} → Factory αααBool
le
m₁: Meas
m₁
.
cost: {α : Type} → Measα
cost
m₂: Meas
m₂
.
cost: {α : Type} → Measα
cost
/-! ### Measure computation/rendering -/ /-- Measure computation/rendering definition (Figure 11) -/ inductive
MeasRender: DocMeasProp
MeasRender
:
Doc: Type
Doc
: Type
: Type
Meas: {α : Type} → Type
Meas
Prop: Type
Prop
where |
text: ∀ {α : Type} {F : Factory α} {c i : } (s : String), MeasRender F (Doc.text s) c i { last := c + String.length s, cost := Factory.text F c (String.length s), doc := Doc.text s, x := c + String.length s, y := i }
text
(s :
String: Type
String
) :
MeasRender: DocMeasProp
MeasRender
(
Doc.text: StringDoc
Doc.text
s)
c: ?m.7798
c
i: ?m.7804
i
(
Meas.mk: {α : Type} → αDocMeas
Meas.mk
(
c: ?m.7798
c
+ s.
length: String
length
) (
F: Factory α
F
.
text: {α : Type} → Factory αα
text
c: ?m.7798
c
s.
length: String
length
) (
Doc.text: StringDoc
Doc.text
s) (
c: ?m.7798
c
+ s.
length: String
length
)
i: ?m.7804
i
) |
nl: ∀ {α : Type} {F : Factory α} {c i : }, MeasRender F Doc.nl c i { last := i, cost := Factory.nl F i, doc := Doc.nl, x := max c i, y := i }
nl
:
MeasRender: DocMeasProp
MeasRender
Doc.nl: Doc
Doc.nl
c: ?m.7886
c
i: ?m.7890
i
(
Meas.mk: {α : Type} → αDocMeas
Meas.mk
i: ?m.7890
i
(
F: Factory α
F
.
nl: {α : Type} → Factory αα
nl
i: ?m.7890
i
)
Doc.nl: Doc
Doc.nl
(
max: {α : Type ?u.7895} → [self : Max α] → ααα
max
c: ?m.7886
c
i: ?m.7890
i
)
i: ?m.7890
i
) |
concat: ∀ {α : Type} {F : Factory α} {d₁ : Doc} {c i : } {m₁ : Meas} {d₂ : Doc} {m₂ m : Meas}, MeasRender F d₁ c i m₁MeasRender F d₂ m₁.last i m₂m = Meas.concat F m₁ m₂MeasRender F (Doc.concat d₁ d₂) c i m
concat
(
h₁: MeasRender d₁ c i m₁
h₁
:
MeasRender: DocMeasProp
MeasRender
d₁: ?m.7926
d₁
c: ?m.7930
c
i: ?m.7934
i
m₁: ?m.7938
m₁
) (
h₂: MeasRender d₂ m₁.last i m₂
h₂
:
MeasRender: DocMeasProp
MeasRender
d₂: ?m.7944
d₂
m₁: ?m.7938
m₁
.
last: {α : Type} → Meas
last
i: ?m.7934
i
m₂: ?m.7951
m₂
) (
h: m = Meas.concat F m₁ m₂
h
:
m: ?m.7961
m
=
Meas.concat: {α : Type} → Factory αMeasMeasMeas
Meas.concat
F: Factory α
F
m₁: ?m.7938
m₁
m₂: ?m.7951
m₂
) :
MeasRender: DocMeasProp
MeasRender
(
Doc.concat: DocDocDoc
Doc.concat
d₁: ?m.7926
d₁
d₂: ?m.7944
d₂
)
c: ?m.7930
c
i: ?m.7934
i
m: ?m.7961
m
|
nest: ∀ {α : Type} {F : Factory α} {d : Doc} {c i n last : } {cost : α} {x y : }, MeasRender F d c (i + n) { last := last, cost := cost, doc := d, x := x, y := y }MeasRender F (Doc.nest n d) c i { last := last, cost := cost, doc := Doc.nest n d, x := x, y := y }
nest
(
h: MeasRender d c (i + n) { last := last, cost := cost, doc := d, x := x, y := y }
h
:
MeasRender: DocMeasProp
MeasRender
d: ?m.7986
d
c: ?m.7990
c
(
i: ?m.7997
i
+
n: ?m.8004
n
) (
Meas.mk: {α : Type} → αDocMeas
Meas.mk
last: ?m.8033
last
cost: ?m.8062
cost
d: ?m.7986
d
x: ?m.8091
x
y: ?m.8120
y
)) :
MeasRender: DocMeasProp
MeasRender
(
Doc.nest: DocDoc
Doc.nest
n: ?m.8004
n
d: ?m.7986
d
)
c: ?m.7990
c
i: ?m.7997
i
(
Meas.mk: {α : Type} → αDocMeas
Meas.mk
last: ?m.8033
last
cost: ?m.8062
cost
(
Doc.nest: DocDoc
Doc.nest
n: ?m.8004
n
d: ?m.7986
d
)
x: ?m.8091
x
y: ?m.8120
y
) |
align: ∀ {α : Type} {F : Factory α} {d : Doc} {c last : } {cost : α} {x y i : }, MeasRender F d c c { last := last, cost := cost, doc := d, x := x, y := y }MeasRender F (Doc.align d) c i { last := last, cost := cost, doc := Doc.align d, x := x, y := max i y }
align
(
h: MeasRender d c c { last := last, cost := cost, doc := d, x := x, y := y }
h
:
MeasRender: DocMeasProp
MeasRender
d: ?m.8162
d
c: ?m.8166
c
c: ?m.8166
c
(
Meas.mk: {α : Type} → αDocMeas
Meas.mk
last: ?m.8171
last
cost: ?m.8176
cost
d: ?m.8162
d
x: ?m.8181
x
y: ?m.8186
y
)) :
MeasRender: DocMeasProp
MeasRender
(
Doc.align: DocDoc
Doc.align
d: ?m.8162
d
)
c: ?m.8166
c
i: ?m.8193
i
(
Meas.mk: {α : Type} → αDocMeas
Meas.mk
last: ?m.8171
last
cost: ?m.8176
cost
(
Doc.align: DocDoc
Doc.align
d: ?m.8162
d
)
x: ?m.8181
x
(
max: {α : Type ?u.8200} → [self : Max α] → ααα
max
i: ?m.8193
i
y: ?m.8186
y
)) end Meas section Pareto variable (
F: Factory α
F
:
Factory: TypeType
Factory
α: ?m.8914
α
) /-! ### Pareto frontier -/ /-- A list of measures is strictly increasing in cost -/ def
cost_increasing: {α : Type} → Factory αList MeasProp
cost_increasing
(
ms: List Meas
ms
:
List: Type ?u.8716 → Type ?u.8716
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.8711
α
)) :
Prop: Type
Prop
:= ∀
i: ?m.8722
i
(
hi: i < List.length ms
hi
:
i: ?m.8722
i
<
ms: List Meas
ms
.
length: {α : Type ?u.8726} → List α
length
) (
hj: i + 1 < List.length ms
hj
:
i: ?m.8722
i
+
1: ?m.8743
1
<
ms: List Meas
ms
.
length: {α : Type ?u.8758} → List α
length
),
F: Factory α
F
.
lt: {α : Type} → Factory αααProp
lt
(
ms: List Meas
ms
.
get: {α : Type ?u.8822} → (as : List α) → Fin (List.length as)α
get
i: ?m.8722
i
,
hi: i < List.length ms
hi
⟩).
cost: {α : Type} → Measα
cost
(
ms: List Meas
ms
.
get: {α : Type ?u.8834} → (as : List α) → Fin (List.length as)α
get
i: ?m.8722
i
+
1: ?m.8847
1
,
hj: i + 1 < List.length ms
hj
⟩).
cost: {α : Type} → Measα
cost
/-- A list of measures is (non-strictly) increasing in cost -/ def
cost_increasing_non_strict: List MeasProp
cost_increasing_non_strict
(
ms: List Meas
ms
:
List: Type ?u.8919 → Type ?u.8919
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.8914
α
)) :
Prop: Type
Prop
:= ∀
i: ?m.8925
i
(
hi: i < List.length ms
hi
:
i: ?m.8925
i
<
ms: List Meas
ms
.
length: {α : Type ?u.8929} → List α
length
) (
hj: i + 1 < List.length ms
hj
:
i: ?m.8925
i
+
1: ?m.8946
1
<
ms: List Meas
ms
.
length: {α : Type ?u.8961} → List α
length
),
F: Factory α
F
.
le: {α : Type} → Factory αααBool
le
(
ms: List Meas
ms
.
get: {α : Type ?u.9021} → (as : List α) → Fin (List.length as)α
get
i: ?m.8925
i
,
hi: i < List.length ms
hi
⟩).
cost: {α : Type} → Measα
cost
(
ms: List Meas
ms
.
get: {α : Type ?u.9033} → (as : List α) → Fin (List.length as)α
get
i: ?m.8925
i
+
1: ?m.9046
1
,
hj: i + 1 < List.length ms
hj
⟩).
cost: {α : Type} → Measα
cost
/-- A list of measures is strictly decreasing in length of last line -/ def
last_decreasing: List MeasProp
last_decreasing
(
ms: List Meas
ms
:
List: Type ?u.9132 → Type ?u.9132
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.9127
α
)) :
Prop: Type
Prop
:= ∀
i: ?m.9138
i
(
hi: i < List.length ms
hi
:
i: ?m.9138
i
<
ms: List Meas
ms
.
length: {α : Type ?u.9142} → List α
length
) (
hj: i + 1 < List.length ms
hj
:
i: ?m.9138
i
+
1: ?m.9159
1
<
ms: List Meas
ms
.
length: {α : Type ?u.9174} → List α
length
), (
ms: List Meas
ms
.
get: {α : Type ?u.9233} → (as : List α) → Fin (List.length as)α
get
i: ?m.9138
i
,
hi: i < List.length ms
hi
⟩).
last: {α : Type} → Meas
last
> (
ms: List Meas
ms
.
get: {α : Type ?u.9245} → (as : List α) → Fin (List.length as)α
get
i: ?m.9138
i
+
1: ?m.9258
1
,
hj: i + 1 < List.length ms
hj
⟩).
last: {α : Type} → Meas
last
/-- A predicate that a list of measures form a Pareto frontier (Section 5.4) This definition is not the same as the definition described in the paper, which is based on non-domination. However, they are equivalent, proven at `pareto_nondom_iff_pareto` in `Pretty.Claims.Pareto`. -/ def
pareto: List MeasProp
pareto
(
ms: List Meas
ms
:
List: Type ?u.9330 → Type ?u.9330
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.9325
α
)) :
Prop: Type
Prop
:=
last_decreasing: {α : Type} → List MeasProp
last_decreasing
ms: List Meas
ms
cost_increasing: {α : Type} → Factory αList MeasProp
cost_increasing
F: Factory α
F
ms: List Meas
ms
end Pareto section ListMeasure variable (
F: Factory α
F
:
Factory: TypeType
Factory
α: ?m.9348
α
) /-! ### Various list of measures operations (Figure 12) -/ /-- - dedup; -/ def
dedup: {α : Type} → Factory αList MeasList Meas
dedup
:
List: Type ?u.9360 → Type ?u.9360
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.9354
α
) →
List: Type ?u.9362 → Type ?u.9362
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.9354
α
) | [] =>
[]: List ?m.9378
[]
| [
m: Meas
m
] => [
m: Meas
m
] |
m₁: Meas
m₁
::
m₂: Meas
m₂
::
ms: List Meas
ms
=> if
F: Factory α
F
.
le: {α : Type} → Factory αααBool
le
m₂: Meas
m₂
.
cost: {α : Type} → Measα
cost
m₁: Meas
m₁
.
cost: {α : Type} → Measα
cost
then
dedup: List MeasList Meas
dedup
(
m₂: Meas
m₂
::
ms: List Meas
ms
) else
m₁: Meas
m₁
::
dedup: List MeasList Meas
dedup
(
m₂: Meas
m₂
::
ms: List Meas
ms
) /-- - merge (⊎); -/ def
merge: List Meas × List MeasList Meas
merge
:
List: Type ?u.10102 → Type ?u.10102
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.10094
α
) ×
List: Type ?u.10103 → Type ?u.10103
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.10094
α
) →
List: Type ?u.10105 → Type ?u.10105
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.10094
α
) | ⟨[],
ms: List Meas
ms
⟩ =>
ms: List Meas
ms
| ⟨
ms: List Meas
ms
, []⟩ =>
ms: List Meas
ms
| ⟨
m₁: Meas
m₁
::
ms₁: List Meas
ms₁
,
m₂: Meas
m₂
::
ms₂: List Meas
ms₂
⟩ => if
dominates: {α : Type} → Factory αMeasMeasBool
dominates
F: Factory α
F
m₁: Meas
m₁
m₂: Meas
m₂
then
merge: List Meas × List MeasList Meas
merge
m₁: Meas
m₁
::
ms₁: List Meas
ms₁
,
ms₂: List Meas
ms₂
else if
dominates: {α : Type} → Factory αMeasMeasBool
dominates
F: Factory α
F
m₂: Meas
m₂
m₁: Meas
m₁
then
merge: List Meas × List MeasList Meas
merge
ms₁: List Meas
ms₁
,
m₂: Meas
m₂
::
ms₂: List Meas
ms₂
else if
m₁: Meas
m₁
.
last: {α : Type} → Meas
last
>
m₂: Meas
m₂
.
last: {α : Type} → Meas
last
then
m₁: Meas
m₁
::
merge: List Meas × List MeasList Meas
merge
ms₁: List Meas
ms₁
,
m₂: Meas
m₂
::
ms₂: List Meas
ms₂
else
m₂: Meas
m₂
::
merge: List Meas × List MeasList Meas
merge
m₁: Meas
m₁
::
ms₁: List Meas
ms₁
,
ms₂: List Meas
ms₂
⟩ /-! ### Measure set -/ /-- Measure set definition (Figure 12). Unlike the definition in the paper, we carry the proof that `ms` is non-empty instead of relying on the implicit non-empty assumption everywhere. -/ inductive
MeasureSet: Type
MeasureSet
:
Type: Type 1
Type
where |
tainted: {α : Type} → MeasMeasureSet
tainted
(
m: Meas
m
: @
Meas: {α : Type} → Type
Meas
α: ?m.20391
α
) :
MeasureSet: Type
MeasureSet
|
set: {α : Type} → (ms : List Meas) → ms []MeasureSet
set
(
ms: List Meas
ms
:
List: Type ?u.20402 → Type ?u.20402
List
(@
Meas: {α : Type} → Type
Meas
α: ?m.20391
α
)) (
h: ms []
h
:
ms: List Meas
ms
[]: List ?m.20409
[]
) :
MeasureSet: Type
MeasureSet
end ListMeasure