Built with Alectryon, running Coq+SerAPI v8.13.0+0.13.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.
Notation "[ rel _ _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ : _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ & _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ | _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ rel _ _ in _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "_ + _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ - _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ >= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ > _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ * _" was already used in scope nat_scope. [notation-overridden,parsing]
Set Implicit Arguments. Unset Strict Implicit. (******************************************************************************) (* *) (* Extra theorems and definitions *) (* *) (******************************************************************************) (******************************************************************************) (* *) (* Extra theorems about lists *) (* *) (******************************************************************************)
A:Type
a:seq A

injective (rcons a)
2
by elim: a => /= [s1 s2 /= [] | b l IH s1 s2 [] /IH]. Qed.
5
a:A

injective (rcons^~ a)
a
5
a, b:A
s1:seq A
IH:forall x2 : seq A, rcons s1 a = rcons x2 a -> s1 = x2

rcons s1 a = [::] -> a :: s1 = [::]
by case: (s1) => // [] []. Qed.
4
injective (cat a)
19
by elim: a => // b l IH s1 s2 /= [] /IH. Qed.
4
injective (cat^~ a)
1e
5
b:A
l:seq A
IH:injective (cat^~ l)
s1, s2:seq A

s1 ++ b :: l = s2 ++ b :: l -> s1 = s2
by rewrite -!cat_rcons => /IH; apply: rcons_injr. Qed.
A:eqType
d
l:seq_predType A

a \in l -> exists l1 l2 : seq A, l = l1 ++ a :: l2
2c
2f1427
IH:a \in l -> exists l1 l2 : seq A, l = l1 ++ a :: l2

exists l1 l2 : seq A, a :: l = l1 ++ a :: l2
2f142737
aIl:a \in l
exists l1 l2 : seq A, b :: l = l1 ++ a :: l2
3b
3d
2f1427373c
l1, l2:seq A
lE:l = l1 ++ a :: l2

3d
by exists (b :: l1); exists l2; rewrite /= lE. Qed.
2f27
P:pred A

~~ all [predC P] l -> {bl1l2 : A * seq A * seq A | [/\ all [predC P] bl1l2.1.2, P bl1l2.1.1 & l = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}
48
2f4b2627
IH:~~ all [predC P] l -> {bl1l2 : A * seq A * seq A | [/\ all [predC P] bl1l2.1.2, P bl1l2.1.1 & l = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}

~~ ((b \notin P) && all [predC P] l) -> {bl1l2 : A * seq A * seq A | [/\ all [predC P] bl1l2.1.2, P bl1l2.1.1 & b :: l = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}
2f4b262752
bIP:b \in P

{bl1l2 : A * seq A * seq A | [/\ all [predC P] bl1l2.1.2, P bl1l2.1.1 & b :: l = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}
2f4b262752
bNIP:b \notin P
c:A
45
H1:all [predC P] (c, l1, l2).1.2
H2:P (c, l1, l2).1.1
{bl1l2 : A * seq A * seq A | [/\ all [predC P] bl1l2.1.2, P bl1l2.1.1 & b :: (c, l1, l2).1.2 ++ (c, l1, l2).1.1 :: (c, l1, l2).2 = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}
5c
61
by exists (c, b :: l1, l2); split; rewrite /= ?bNIP. Qed.
4a
~~ all [predC P] l -> {bl1l2 : A * seq A * seq A | [/\ P bl1l2.1.1, all [predC P] bl1l2.2 & l = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}
66
2f274b
lA:~~ all [predC P] l

{bl1l2 : A * seq A * seq A | [/\ P bl1l2.1.1, all [predC P] bl1l2.2 & l = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}
6d
forall x : A * seq A * seq A, [/\ all [predC P] x.1.2, P x.1.1 & rev l = x.1.2 ++ x.1.1 :: x.2] -> {bl1l2 : A * seq A * seq A | [/\ P bl1l2.1.1, all [predC P] bl1l2.2 & l = bl1l2.1.2 ++ bl1l2.1.1 :: bl1l2.2]}
2f274b6e2645
H1:all [predC P] (b, l1, l2).1.2
H2:P (b, l1, l2).1.1
H3:rev l = (b, l1, l2).1.2 ++ (b, l1, l2).1.1 :: (b, l1, l2).2

6f
77
l = (b, rev l2, rev l1).1.2 ++ (b, rev l2, rev l1).1.1 :: (b, rev l2, rev l1).2
by rewrite -{1}[l]revK H3 rev_cat /= rev_cons cat_rcons. Qed.
2f14
l1, l2, l3, l4:seq A

l1 ++ a :: l2 = l3 ++ b :: l4 -> [\/ [/\ l1 = l3, a = b & l2 = l4], exists l5 : seq A, l3 = l1 ++ a :: l5 | exists l5 : seq A, l1 = l3 ++ b :: l5]
80
2f14
l2, l4:seq A

[\/ [/\ [::] = [::], a = a & l2 = l2], exists l5 : seq A, [::] = a :: l5 | exists l5 : seq A, [::] = a :: l5]
2f148a5e
l3:seq A
[\/ [/\ [::] = a :: l3, a = b & l3 ++ b :: l4 = l4], exists l5 : seq A, a :: l3 = a :: l5 | exists l5 : seq A, [::] = a :: l3 ++ b :: l5]
2f148a5e
l1:seq A
IH:forall l3 : seq A, l1 ++ a :: l2 = l3 ++ b :: l4 -> [\/ [/\ l1 = l3, a = b & l2 = l4], exists l5 : seq A, l3 = l1 ++ a :: l5 | exists l5 : seq A, l1 = l3 ++ b :: l5]
[\/ [/\ c :: l1 = [::], a = c & l2 = l1 ++ a :: l2], exists l5 : seq A, [::] = c :: l1 ++ a :: l5 | exists l5 : seq A, c :: l1 = [::] ++ c :: l5]
2f148a5e9394
d:A
8f
l1 ++ a :: l2 = l3 ++ b :: l4 -> [\/ [/\ c :: l1 = c :: l3, a = b & l2 = l4], exists l5 : seq A, c :: l3 = c :: l1 ++ a :: l5 | exists l5 : seq A, c :: l1 = c :: l3 ++ b :: l5]
87
8e
90
9196
9c
92
95
96
a1
97
99
97
[\/ [/\ c :: l1 = c :: l1, a = a & l2 = l2], exists l5 : seq A, c :: l1 = c :: l1 ++ a :: l5 | exists l5 : seq A, c :: l1 = c :: l1 ++ a :: l5]
2f148a5e939498
l3, l5:seq A
[\/ [/\ c :: l1 = c :: l1 ++ a :: l5, a = b & l2 = l4], exists l6 : seq A, c :: l1 ++ a :: l5 = c :: l1 ++ a :: l6 | exists l6 : seq A, c :: l1 = c :: (l1 ++ a :: l5) ++ b :: l6]
97
(exists l5 : seq A, l1 = l3 ++ b :: l5) -> [\/ [/\ c :: l1 = c :: l3, a = b & l2 = l4], exists l5 : seq A, c :: l3 = c :: l1 ++ a :: l5 | exists l5 : seq A, c :: l1 = c :: l3 ++ b :: l5]
a9
ae
b0
b1
b5
97
b2
by case=> l5 ->; apply: Or33; exists l5. Qed.
82
l1 ++ a :: l2 = l3 ++ b :: l4 -> [\/ [/\ l1 = l3, a = b & l2 = l4], exists l5 : seq A, l4 = l5 ++ a :: l2 | exists l5 : seq A, l2 = l5 ++ b :: l4]
bd
2f14
l1, l3, l4:seq A

l1 ++ [:: a] = l3 ++ b :: l4 -> [\/ [/\ l1 = l3, a = b & [::] = l4], exists l5 : seq A, l4 = l5 ++ [:: a] | exists l5 : seq A, [::] = l5 ++ b :: l4]
2f14
l1, l3, l2:seq A
5e
IH:forall l4 : seq A, l1 ++ a :: l2 = l3 ++ b :: l4 -> [\/ [/\ l1 = l3, a = b & l2 = l4], exists l5 : seq A, l4 = l5 ++ a :: l2 | exists l5 : seq A, l2 = l5 ++ b :: l4]
l4:seq A
l1 ++ a :: rcons l2 c = l3 ++ b :: l4 -> [\/ [/\ l1 = l3, a = b & rcons l2 c = l4], exists l5 : seq A, l4 = l5 ++ a :: rcons l2 c | exists l5 : seq A, rcons l2 c = l5 ++ b :: l4]
c4
l1 ++ [:: a] = l3 ++ [:: b] -> [\/ [/\ l1 = l3, a = b & [::] = [::]], exists l5 : seq A, [::] = l5 ++ [:: a] | exists l5 : seq A, [::] = l5 ++ [:: b]]
2f14
l1, l3, l4, l5:seq A
5e
l1 ++ [:: a] = l3 ++ b :: rcons l5 c -> [\/ [/\ l1 = l3, a = b & [::] = rcons l5 c], exists l6 : seq A, rcons l5 c = l6 ++ [:: a] | exists l6 : seq A, [::] = l6 ++ b :: rcons l5 c]
c8
c4
[\/ [/\ l1 = l1, a = a & [::] = [::]], exists l5 : seq A, [::] = l5 ++ [:: a] | exists l5 : seq A, [::] = l5 ++ [:: a]]
d2
d4
d6
c7
d4
[\/ [/\ l3 ++ b :: l5 = l3, a = b & [::] = rcons l5 a], exists l6 : seq A, rcons l5 a = l6 ++ [:: a] | exists l6 : seq A, [::] = l6 ++ rcons (b :: l5) a]
c7
c9
cd
c9
l1 ++ a :: rcons l2 c = l3 ++ [:: b] -> [\/ [/\ l1 = l3, a = b & rcons l2 c = [::]], exists l5 : seq A, [::] = l5 ++ a :: rcons l2 c | exists l5 : seq A, rcons l2 c = l5 ++ [:: b]]
2f14ca5ecb
l4, l5:seq A
98
l1 ++ a :: rcons l2 c = l3 ++ b :: rcons l5 d -> [\/ [/\ l1 = l3, a = b & rcons l2 c = rcons l5 d], exists l6 : seq A, rcons l5 d = l6 ++ a :: rcons l2 c | exists l6 : seq A, rcons l2 c = l6 ++ b :: rcons l5 d]
c9
[\/ [/\ l1 = l1 ++ a :: l2, a = b & rcons l2 b = [::]], exists l5 : seq A, [::] = l5 ++ rcons (a :: l2) b | exists l5 : seq A, rcons l2 b = l5 ++ [:: b]]
e9
eb
ed
eb
[\/ [/\ l1 = l1, a = a & rcons l2 c = rcons l2 c], exists l5 : seq A, rcons l2 c = l5 ++ rcons (a :: l2) c | exists l5 : seq A, rcons l2 c = l5 ++ rcons (a :: l2) c]
2f14ca5ecbec98
l6:seq A
[\/ [/\ l1 = l3, a = b & rcons l2 c = rcons (l6 ++ a :: l2) c], exists l5 : seq A, rcons (l6 ++ a :: l2) c = l5 ++ rcons (a :: l2) c | exists l5 : seq A, rcons l2 c = l5 ++ rcons (b :: l6 ++ a :: l2) c]
fb
[\/ [/\ l1 = l3, a = b & rcons (l6 ++ b :: l5) c = rcons l5 c], exists l7 : seq A, rcons l5 c = l7 ++ rcons (a :: l6 ++ b :: l5) c | exists l7 : seq A, rcons (l6 ++ b :: l5) c = l7 ++ rcons (b :: l5) c]
f6
fb
fd
fe
102
fb
ff
by apply: Or33; exists l6; rewrite -rcons_cat. Qed. (******************************************************************************) (* We develop a twisted version of split that fills 'I_{m + n} with *) (* first the element of 'I_n (x -> x) then the element of m (x -> x + n) *) (* This is mostly motivated to naturally get an element of 'I_n from 'I_n.+1 *) (* by removing max_ord *) (******************************************************************************)
m, n:nat
i:'I_m

i + n < m + n
10a
by rewrite ltn_add2r. Qed.
10d
i:'I_n

i < m + n
112
by apply: leq_trans (valP i) _; apply: leq_addl. Qed. Definition tlshift m n (i : 'I_m) := Ordinal (tlshift_subproof n i). Definition trshift m n (i : 'I_n) := Ordinal (trshift_subproof m i).
10d

injective (tlshift n)
119
by move=> ? ? /(f_equal val) /addIn /val_inj. Qed.
11b
injective (trshift m (n:=n))
11f
by move=> ? ? /(f_equal val) /= /val_inj. Qed.
n:nat
115

trshift 1 i = lift ord_max i
124
by apply/val_eqP; rewrite /= /bump leqNgt ltn_ord. Qed.
10d
i:'I_(m + n)

n <= i -> i - n < m
12b
by move/subSn <-; rewrite leq_subLR [n + m]addnC. Qed. Definition tsplit {m n} (i : 'I_(m + n)) : 'I_m + 'I_n := match ltnP (i) n with | LtnNotGeq lt_i_n => inr _ (Ordinal lt_i_n) | GeqNotLtn ge_i_n => inl _ (Ordinal (tsplit_subproof ge_i_n)) end. Variant tsplit_spec m n (i : 'I_(m + n)) : 'I_m + 'I_n -> bool -> Type := | TSplitLo (j : 'I_n) of i = j :> nat : tsplit_spec i (inr _ j) true | TSplitHi (k : 'I_m) of i = k + n :> nat : tsplit_spec i (inl _ k) false.
12d
tsplit_spec i (tsplit i) (i < n)
132
10d12e
lt_i_n:=i < n:bool

tsplit_spec i match ltnP i n with | LtnNotGeq lt_i_n => inr (Ordinal (n:=n) (m:=i) lt_i_n) | GeqNotLtn ge_i_n => inl (Ordinal (n:=m) (m:=i - n) (tsplit_subproof (m:=m) (n:=n) (i:=i) ge_i_n)) end lt_i_n
by case: {-}_ lt_i_n / ltnP; [left |right; rewrite subnK]. Qed. Definition tunsplit {m n} (jk : 'I_m + 'I_n) := match jk with inl j => tlshift n j | inr k => trshift m k end.
10d
jk:('I_m + 'I_n)%type

(n <= tunsplit jk) = jk
13d
by case: jk => [j|k]; rewrite /= ?ltn_ord ?leq_addl // leqNgt ltn_ord. Qed.
11b
cancel tsplit tunsplit
144
by move=> i; apply: val_inj; case: tsplitP. Qed.
11b
cancel tunsplit tsplit
149
13f
~~ (tunsplit jk < n) = jk -> tsplit (tunsplit jk) = jk
by do [case: tsplitP; case: jk => //= i j] => [|/addIn] => /ord_inj->. Qed. (******************************************************************************) (* *) (* Extra theorems about fset *) (* *) (******************************************************************************) Open Scope fset_scope. Definition sint a b : {fset nat} := [fset @nat_of_ord _ i | i in 'I_b & a <= i].
a, b:nat
i:nat_choiceType

(i \in sint a b) = (a <= i < b)
152
155156
j:ordinal_choiceType b
aLj:j \in [pred x | a <= x]

a <= j < b
155156
aLi:a <= i
iLb:i < b
exists2 x : ordinal_choiceType b, in_mem x (mem_fin (subfinset_finpred (T:=ordinal_choiceType b) (mem_fin (fin_finpred (pT:=pred_finpredType (ordinal_finType b)) 'I_b)) (fun i : 'I_b => a <= i))) & i = x
162
165
by exists (Ordinal iLb). Qed.
a, b, c:nat

a <= c -> [fset i in sint a b | c <= i] = sint c b
16a
16d
aLc:a <= c

[fset i in sint a b | c <= i] = sint c b
16d174156

(i \in [fset i | i in sint a b & c <= i]) = (i \in sint c b)
179
(i \in [fset i | i in sint a b & c <= i]) = (c <= i < b)
16d174
i, j:nat_choiceType

j \in [pred x in [eta mem_seq (T:=nat_choiceType) (sint a b)] | c <= x] -> i = j -> c <= i < b
16d174156
cLi:c <= i
164
exists2 x : nat_choiceType, in_mem x (mem_fin (subfinset_finpred (T:=nat_choiceType) (mem_fin (fset_finpred (sint a b))) (leq c))) & i = x
16d174183
aLj:a <= j
jLb:j < b
cLj:c <= j

c <= j < b
185
187
189
by exists i; rewrite //= inE mem_sint cLi iLb (leq_trans aLc). Qed.
155

sint a.+1 b = sint a b `\ a
196
a, b, i:nat

(a < i < b) = [&& i != a, a <= i & i < b]
by do 2 case: ltngtP. Qed.
198
sint a b.+1 `\ b = sint a b
1a2
19e
[&& i != b, a <= i & i <= b] = (a <= i < b)
by do 2 case: ltngtP. Qed.
198
sint a b = sint 0 b `\` sint 0 a
1ab
by apply/fsetP => /= i; rewrite !inE !mem_sint /= -leqNgt. Qed.
198
#|` sint a b| = b - a
1b0
a:nat

#|` sint a 0| = 0 - a
155
IH:#|` sint a b| = b - a
#|` sint a b.+1| = b.+1 - a
1b8156

(i \in sint a 0) = (i \in fset0)
1ba
1bc
1be
1551bd
bLa:b < a

1be
1551bd
aLb:a <= b
1be
1ca
b.+1 - a = 0
1ca
#|` sint a b.+1| = 0
1cd
1ca
1d6
1cc
1551bd1cb156

(a <= i <= b) = false
1cc
1ce
1be
1ce
(true + #|` sint a b.+1 `\ b|)%N = b.+1 - a
by rewrite sintSr IH subSn. Qed. Notation "`[ n ]" := (sint 0 n) (format "`[ n ]").

`[0] = fset0
1e7
by apply/fsetP=> i; rewrite mem_sint inE; case: ltngtP. Qed. Definition s2f n (s : {set 'I_n}) := [fset nat_of_ord i | i in s].
127
s:{set 'I_n}
115

((i : nat) \in s2f (n:=n) s) = (i \in s)
1ec
1271ef
i, j:'I_n
jIs:j \in s
iEj:i = j

i \in s
by rewrite (_ : i = j) //; apply: val_inj. Qed.
127

s2f (n:=n) (set0 : {set 'I_n}) = fset0
1fb
127156

(i \in s2f (n:=n) set0) = false
by apply/idP => /imfsetP[j /=]; rewrite inE. Qed.
1fd
s2f (n:=n) ([set: ordinal_finType n] : {set 'I_n}) = `[n]
206
203
(i \in s2f (n:=n) [set: 'I_n]) = (i < n)
127156
iLn:i < n

exists2 x : 'I_n, x \in [set: 'I_n] & i = x
by exists (Ordinal iLn). Qed.
127
s1, s2:{set 'I_n}

s2f (n:=n) (s1 :\: s2) = s2f (n:=n) s1 `\` s2f (n:=n) s2
215
127218
j:nat_choiceType

(j \in s2f (n:=n) (s1 :\: s2)) = (j \notin s2f (n:=n) s2) && (j \in s2f (n:=n) s1)
12721821f
k:'I_n

k \in s1 :\: s2 -> j = k -> j \notin s2f (n:=n) s2 /\ j \in s2f (n:=n) s1
12721821f
jDi:j \notin s2f (n:=n) s2
225
kIs:k \in s1
jEk:j = k
exists2 x : 'I_n, x \in s1 :\: s2 & j = x
229
22d
by exists k => //; rewrite !inE kIs -mem_s2f -jEk jDi. Qed.
217
s2f (n:=n) (s1 :|: s2) = s2f (n:=n) s1 `|` s2f (n:=n) s2
232
21e
(j \in s2f (n:=n) (s1 :|: s2)) = (j \in s2f (n:=n) s1) || (j \in s2f (n:=n) s2)
224
k \in s1 :|: s2 -> j = k -> j \in s2f (n:=n) s1 \/ j \in s2f (n:=n) s2
224
k \in s1 -> j = k -> exists2 x : 'I_n, x \in s1 :|: s2 & j = x
224
k \in s2 -> j = k -> exists2 x : 'I_n, x \in s1 :|: s2 & j = x
23b
224
240
241
245
224
242
by move => kIs2 ->; exists k; rewrite // inE kIs2 orbT. Qed.
217
s2f (n:=n) (s1 :&: s2) = s2f (n:=n) s1 `&` s2f (n:=n) s2
24d
21e
(j \in s2f (n:=n) (s1 :&: s2)) = (j \in s2f (n:=n) s1) && (j \in s2f (n:=n) s2)
224
k \in s1 :&: s2 -> j = k -> j \in s2f (n:=n) s1 /\ j \in s2f (n:=n) s2
12721821f
jDi:j \in s2f (n:=n) s1
225
kIs:k \in s2
22c
exists2 x : 'I_n, x \in s1 :&: s2 & j = x
25b
25e
by exists k => //; rewrite !inE kIs -mem_s2f -jEk jDi. Qed.
126
s2f (n:=n) [set i] = [fset i]
263
12711521f

(j \in s2f (n:=n) [set i]) = (j == i)
26a
exists2 x : 'I_n, x \in [set i] & i = x
by exists i; rewrite ?inE. Qed.
1271ef
P:pred nat

s2f (n:=n) [set i in s | P i] = [fset i in s2f (n:=n) s | P i]
271
1271ef274156

(i \in s2f (n:=n) [set i in s | P i]) = (i \in [eta mem_seq (T:=nat_choiceType) (s2f (n:=n) s)]) && P i
1271ef274156
j:'I_n

j \in [set i in s | P i] -> i = j -> i \in [eta mem_seq (T:=nat_choiceType) (s2f (n:=n) s)] /\ P i
27a
i \in [eta mem_seq (T:=nat_choiceType) (s2f (n:=n) s)] /\ P i -> exists2 x : 'I_n, x \in [set i in s | P i] & i = x
1271ef2741562801f7
jP:P j

j \in [eta mem_seq (T:=nat_choiceType) (s2f (n:=n) s)]
282
27a
284
288
j \in [set i in s | P i]
by rewrite inE jIs. Qed.
1271ef
i:ordinal_finType n

s2f (n:=n) (s :\ i) = s2f (n:=n) s `\ i
293
by rewrite s2fD s2f1. Qed.
1271ef

#|` s2f (n:=n) s| = #|s|
29a
n, m:nat
IH:forall s : {set 'I_n}, #|s| < m -> #|` s2f (n:=n) s| = #|s|
1ef
sLm:#|s| < m.+1

29d
2a32a41ef2a5296
iIs:i \in s

29d
2a9
#|s :\ i| < m
2a9
#|` s2f (n:=n) s| = (1 + #|` s2f (n:=n) (s :\ i)|)%N
2a9
2b1
2a9
i \in s2f (n:=n) s
2a9
(true + #|` s2f (n:=n) s `\ i|)%N = (1 + #|` s2f (n:=n) (s :\ i)|)%N
2a9
2bb
by rewrite s2fD1. Qed. (* initial section of an ordinal *) Definition isO n t := [set i | (i : 'I_n) < t].
n, t:nat

t <= n -> s2f (n:=n) (isO n t) = `[t]
2c0
2c3
tLn:t <= n

s2f (n:=n) (isO n t) = `[t]
2c32ca156

(i \in s2f (n:=n) (isO n t)) = (0 <= i < t)
2c32ca156
iLt:i < t

exists2 x : 'I_n, x \in isO n t & i = x
2c32ca1562d5212

2d6
by exists (Ordinal iLn); rewrite // inE. Qed.
2c3296

(i \in isO n t) = (i < t)
2dc
by rewrite inE. Qed.
2c2
n <= t -> isO n t = [set: ordinal_finType n]
2e2
by move=> nLt; apply/setP => í; rewrite !inE (leq_trans _ nLt). Qed.
2c2
t < n.+1 -> isO n.+1 t = [set inord i | i : 'I_t]
2e7
2c3
tLn:t < n.+1
i:ordinal_finType n.+1

(i < t) = (i \in [set inord i | i : 'I_t])
2c32ef2f02d5

exists2 x : ordinal_finType t, x \in 'I_t & i = inord x
2c32ef2f0
j:ordinal_finType t
inord j < t
2f9
2fb
by rewrite inordK // (leq_trans _ tLn) // ltnS // ltnW. Qed.
2c2
#|isO n t| = minn n t
300
2c2
minn n t = #|isO n t|
2c3
nLt:n <= t

n = #|isO n t|
2c3
tLn:t < n
t = #|isO n t|
310
312
t, n:nat
2ef

t = #|isO n.+1 t|
319
t = #|'I_t|
31a2ef
i, j:ordinal_finType t
inord i = inord j -> i = j
322
324
by rewrite !inordK ?(leq_trans _ tLn) ?ltnS 1?ltnW // => /eqP/val_eqP. Qed.
1271ef
t:nat

s2f (n:=n) (s :\: isO n t) = s2f (n:=n) s `\` `[t]
329
1271ef32c21f

(j \in s2f (n:=n) (s :\: isO n t)) = (j \notin `[t]) && (j \in s2f (n:=n) s)
1271ef32c21f225

k \in s :\: isO n t -> j = k -> j \notin `[t] /\ j \in s2f (n:=n) s
1271ef32c21f
jDi:j \notin `[t]
225
kIs:k \in s
22c
exists2 x : 'I_n, x \in s :\: isO n t & j = x
33b
33e
1271ef32c21f22533d22c
jDi:t <= j

33e
by exists k; rewrite // !inE -leqNgt kIs -jEk jDi. Qed. (******************************************************************************) (* *) (* Specific theorems for shanoi *) (* *) (******************************************************************************) Open Scope nat_scope.
A, B:finType
f:{ffun A -> B}
p1, p2:B

(codom f \subset [:: p1; p2]) = (codom f \subset [:: p2; p1])
348
by apply/subsetP/subsetP; move => sB i /sB; rewrite !inE orbC. Qed.
n, k:nat

k = 0 -> inord k = ord0
351
by move=> -> /=; apply/val_eqP; rewrite /= inordK. Qed.
1b7
(3 * a) %% 3 = 0
358
by rewrite modnMr. Qed.
1b7
(3 * a).+1 %% 3 = 1
35d
by rewrite mulnC -addn1 modnMDl. Qed.
1b7
(3 * a).+2 %% 3 = 2
362
by rewrite mulnC -addn2 modnMDl. Qed. Definition mod3E := (mod3_0, mod3_1, mod3_2).
1b7
(3 * a) %/ 3 = a
367
by rewrite mulKn. Qed.
1b7
(3 * a).+1 %/ 3 = a
36c
by rewrite mulnC -addn1 divnMDl // divn_small // addn0. Qed.
1b7
(3 * a).+2 %/ 3 = a
371
by rewrite mulnC -addn2 divnMDl // divn_small // addn0. Qed. Definition div3E := (div3_0, div3_1, div3_2).
127
f:nat -> nat

\sum_(i < 3 * n) f i = \sum_(i < n) (f (3 * i) + f (3 * i).+1 + f (3 * i).+2)
376
379127
IH:\sum_(i < 3 * n) f i = \sum_(i < n) (f (3 * i) + f (3 * i).+1 + f (3 * i).+2)

\sum_(i < 3 * n.+1) f i = \sum_(i < n.+1) (f (3 * i) + f (3 * i).+1 + f (3 * i).+2)
by rewrite mulnS !big_ord_recr /= IH !addnA. Qed.
127
x, y:'I_n

(x == y) = (val x == val y)
383
by apply/eqP/val_eqP. Qed.
1fd
odd n.+1 = ~~ odd n
38a
by []. Qed.
k, m:nat

~~ odd m -> (k * m)./2 = k * m./2
38f
392
mE:~~ odd m

(k * m)./2 = k * m./2
398
(k * (m./2).*2)./2 = k * m./2
by rewrite -doubleMr doubleK. Qed.
391
~~ odd m -> (m * k)./2 = m./2 * k
3a0
398
(m * k)./2 = m./2 * k
398
((m./2).*2 * k)./2 = m./2 * k
by rewrite -doubleMl doubleK. Qed.
11b
~~ odd m -> ~~ odd n -> (m + n)./2 = m./2 + n./2
3ad
10d399
nE:~~ odd n

(m + n)./2 = m./2 + n./2
3b4
((m./2).*2 + n)./2 = m./2 + n./2
3b4
((m./2).*2 + (n./2).*2)./2 = m./2 + n./2
by rewrite -doubleD doubleK. Qed.
11b
~~ odd m -> ~~ odd n -> (m - n)./2 = m./2 - n./2
3c0
3b4
(m - n)./2 = m./2 - n./2
3b4
((m./2).*2 - n)./2 = m./2 - n./2
3b4
((m./2).*2 - (n./2).*2)./2 = m./2 - n./2
by rewrite -doubleB doubleK. Qed.
11b
m <= n -> m.-1 <= n.-1
3d1
by case: m; case: n => //=. Qed.

left_distributive subn minn
3d6
m, n, p:nat
nLm:n <= m

n - p = (if m - p < n - p then m - p else n - p)
3de
mLn:m < n
m - p = (if m - p < n - p then m - p else n - p)
3e3
3e5
3de3e4
nLp:n <= p

3e5
3ec
m - p == (if m - p < 0 then m - p else 0)
by rewrite ltnNge //= subn_eq0 (leq_trans (ltnW mLn)). Qed.

left_distributive subn maxn
3f3
3dd
m - p = (if m - p < n - p then n - p else m - p)
3e3
n - p = (if m - p < n - p then n - p else m - p)
3e3
3fd
3ec
3fd
3ec
0 == (if m - p < 0 then 0 else m - p)
by rewrite ltnNge //= eq_sym subn_eq0 (leq_trans (ltnW mLn)). Qed.
3de

m <= n -> minn m p <= minn n p
409
3de
mLn:m <= n

(if m < p then m else p) <= (if n < p then n else p)
3de412
pLm:p <= m

n < p -> p <= n
3de412
pLm:m < p
p <= n -> m <= p
41c
41e
by move=> _; rewrite ltnW. Qed.
40b
m <= n -> minn p m <= minn p n
423
411
(if p < m then p else m) <= (if p < n then p else n)
3de412
pLm:p < m

n <= p -> p <= n
by move=> _; rewrite (leq_trans (ltnW pLm)). Qed. (******************************************************************************) (* Definiion of discrete convex and concave version *) (* it contains just what is needed for shanoi4 *) (******************************************************************************) Section Convex. Definition increasing (f : nat -> nat) := forall n, f n <= f n.+1. Definition decreasing (f : nat -> nat) := forall n, f n.+1 <= f n.
f1, f2:nat -> nat

f1 =1 f2 -> increasing f1 -> increasing f2
432
by move=> fE fI i; rewrite -!fE. Qed.
37910d

increasing f -> m <= n -> f m <= f n
439
37910d
fI:increasing f
412

f m <= f (n - m + m)
37910d442412
d:nat
fL:f m <= f (d + m)

f m <= f (d.+1 + m)
by apply: leq_trans (fI (d + m)). Qed.
43b
decreasing f -> m <= n -> f n <= f m
44c
37910d
fI:decreasing f
412

f (n - m + m) <= f m
37910d454412448
fL:f (d + m) <= f m

f (d.+1 + m) <= f m
by apply: leq_trans (fI _) fL. Qed. Definition delta (f : nat -> nat) n := f n.+1 - f n.
434
f1 =1 f2 -> delta f1 =1 delta f2
45d
by move=> fE i; rewrite /delta !fE. Qed. Definition fnorm (f : nat -> nat) n := f n - f 0.
379

increasing f -> increasing (fnorm f)
462
by move=> fI n; rewrite leq_sub2r. Qed.
379127

increasing f -> delta (fnorm f) n = delta f n
468
by move=> fI; rewrite /delta /fnorm -subnDA addnC subnK // increasingE. Qed.
46a
increasing f -> fnorm f n = \sum_(i < n) delta (fnorm f) i
46e
379127
iF:increasing f

fnorm f n = \sum_(i < n) delta (fnorm f) i
379476127
IH:fnorm f n = \sum_(i < n) delta (fnorm f) i

fnorm f n.+1 = \sum_(i < n.+1) delta (fnorm f) i
by rewrite big_ord_recr /= -IH addnC subnK // increasing_fnorm. Qed. (* we restrict this to increasing function because of the behavior -*) Definition convex f := increasing f /\ increasing (delta f). (* we restrict this to increasing function because of the behavior -*) Definition concave f := increasing f /\ decreasing (delta f).
464
increasing f -> (forall i : nat, f i + f i.+2 <= (f i.+1).*2) -> concave f
47f
379442
fH:forall i : nat, f i + f i.+2 <= (f i.+1).*2
i:nat

delta f i.+1 <= delta f i
486
f i.+2 - f i.+1 <= f i.+1 - f i
486
f i.+2 + f i <= f i.+1 + f i.+1
by rewrite addnn addnC. Qed.
379
i, k:nat

concave f -> k <= i -> f (i - k) + f (i + k) <= (f i).*2
493
379496442
dfD:decreasing (delta f)

k <= i -> f (i - k) + f (i + k) <= (f i).*2
37948844249d
k:nat
IH:k <= i -> f (i - k) + f (i + k) <= (f i).*2
kLi:k < i

f (i - k.+1) + f (i + k.+1) <= (f i).*2
4a2
i - k.+1 <= i + k
37948844249d4a34a44a5
H:i - k.+1 <= i + k
4a6
4ad
4a6
4ad
f (i - k.+1) <= f (i - k)
37948844249d4a34a44a54ae
fk1Lfk:f (i - k.+1) <= f (i - k)
4a6
4b8
4a6
4b8
delta f (i + k) + (f (i - k) + f (i + k)) <= delta f (i - k.+1) + (f i).*2 -> f (i - k.+1) + f (i + k.+1) <= (f i).*2
4b8
f (i - k) + f (i + k).+1 <= f (i - k.+1).+1 - f (i - k.+1) + (f i).*2 -> f (i - k.+1) + f (i + k.+1) <= (f i).*2
4b8
f (i - k.+1) + (f (i - k) + f (i + k).+1) <= f (i - k) + (f i).*2 -> f (i - k.+1) + f (i + k.+1) <= (f i).*2
4b8
f (i - k.+1) <= f (i - k) + (f i).*2
4b8
4cb
by apply: leq_trans fk1Lfk (leq_addr _ _). Qed.
379
i, k1, k2:nat

concave f -> f (i + k1 + k2) + f i <= f (i + k2) + f (i + k1)
4d0
3794d3
fC:concave f
44249d

f (i + k1 + k2) + f i <= f (i + k2) + f (i + k1)
3794da44249d
k2:nat
IHH:forall k1 i : nat, f (i + k1 + k2) + f i <= f (i + k2) + f (i + k1)
k1, i:nat

f (i + k1 + k2.+1) + f i <= f (i + k2.+1) + f (i + k1)
4df
f (i + k1 + k2).+1 - f (i + k1 + k2) + f (i + k1 + k2) + f i <= f (i + k2).+1 - f (i + k2) + f (i + k2) + f (i + k1)
4df
f (i + k1 + k2).+1 - f (i + k1 + k2) <= f (i + k2).+1 - f (i + k2)
by apply: (decreasingE dfD); rewrite addnAC leq_addr. Qed.
464
increasing f -> (forall i : nat, (f i.+1).*2 <= f i + f i.+2) -> convex f
4ed
379442
fH:forall i : nat, (f i.+1).*2 <= f i + f i.+2
488

delta f i <= delta f i.+1
4f4
f i.+1 - f i <= f i.+2 - f i.+1
4f4
f i.+1 + f i.+1 <= f i.+2 - f i.+1 + (f i + f i.+1)
by rewrite addnn [f i + _]addnC addnA subnK // addnC. Qed.
495
convex f -> k <= i -> (f i).*2 <= f (i - k) + f (i + k)
500
379496442
dfI:increasing (delta f)

k <= i -> (f i).*2 <= f (i - k) + f (i + k)
3794884425084a3
IH:k <= i -> (f i).*2 <= f (i - k) + f (i + k)
4a5

(f i).*2 <= f (i - k.+1) + f (i + k.+1)
50d
4aa
3794884425084a350e4a54ae
50f
515
50f
515
4b5
3794884425084a350e4a54ae4b9
50f
51e
50f
51e
delta f (i - k.+1) + (f i).*2 <= delta f (i + k) + (f (i - k) + f (i + k)) -> (f i).*2 <= f (i - k.+1) + f (i + k.+1)
51e
(f i).*2 + (f (i - k.+1).+1 - f (i - k.+1)) <= f (i + k).+1 + f (i - k) -> (f i).*2 <= f (i - k.+1) + f (i + k.+1)
by rewrite -subSn // subSS addnS addnBA // leq_subLR addnA leq_add2r. Qed. (* Ad-hoc bigmin operator *) Fixpoint bigmin f n := if n is n1.+1 then minn (f n) (bigmin f n1) else f 0. Notation "\min_ ( i <= n ) F" := (bigmin (fun i => F) n) (at level 41, F at level 41, i, n at level 50, format "\min_ ( i <= n ) F").
379354

\min_(i <= n) (f i + k) = \min_(i <= n) f i + k
52b
by elim: n => //= n ->; rewrite addn_minl. Qed.
52d
\min_(i <= n) (f i - k) = \min_(i <= n) f i - k
531
by elim: n => //= n ->; rewrite subn_minr. Qed.
46a
{i0 : 'I_n.+1 | \min_(i <= n) f i = f i0}
536
379127
i:'I_n.+1

{i0 : 'I_n.+2 | minn (f n.+1) (f i) = f i0}
37912753e
H:f i <= f n.+1

{i0 : 'I_n.+2 | f i = f i0}
37912753e
H:f n.+1 < f i
{i0 : 'I_n.+2 | f n.+1 = f i0}
548
54a
by exists ord_max. Qed.
3792a3

reflect (forall i : nat, i <= n -> m <= f i) (m <= \min_(i <= n) f i)
54f
379
m:nat

reflect (forall i : nat, i <= 0 -> m <= f i) (m <= f 0)
37910d
IH:reflect (forall i : nat, i <= n -> m <= f i) (m <= \min_(i <= n) f i)
reflect (forall i : nat, i <= n.+1 -> m <= f i) (m <= minn (f n.+1) (\min_(i <= n) f i))
55c
55e
55c
m <= minn (f n.+1) (\min_(i <= n) f i) -> forall i : nat, i <= n.+1 -> m <= f i
37910d55d
H:forall i : nat, i <= n.+1 -> m <= f i
m <= minn (f n.+1) (\min_(i <= n) f i)
37910d55d
mLf:m <= f n.+1
mLmin:m <= \min_(i <= n) f i
488

i <= n.+1 -> m <= f i
566
37910d55d56f570488
iLn:i < n.+1

m <= f i
566
568
56a
568
m <= \min_(i <= n) f i
by apply/IH => i iLn; rewrite H // (leq_trans iLn). Qed.
379
n, i0, m:nat

i0 <= n -> f i0 <= m -> \min_(i <= n) f i <= m
580
379583
i0Ln:i0 <= n

\min_(i <= n) f i <= f i0
379
i0, m, n:nat
IH:i0 <= n -> \min_(i <= n) f i <= f i0

i0 <= n.+1 -> minn (f n.+1) (\min_(i <= n) f i) <= f i0
by case: ltngtP => // [i0Ln _| -> _]; rewrite geq_min ?leqnn ?IH ?orbT. Qed.
46a
\min_(i <= n) fnorm f i = fnorm (bigmin f) n
594
by elim: n => //= n ->; rewrite -subn_minr. Qed.
435127

(forall i : nat, i <= n -> f1 i = f2 i) -> \min_(i <= n) f1 i = \min_(i <= n) f2 i
599
435127
IH:(forall i : nat, i <= n -> f1 i = f2 i) -> \min_(i <= n) f1 i = \min_(i <= n) f2 i
H:forall i : nat, i <= n.+1 -> f1 i = f2 i

minn (f1 n.+1) (\min_(i <= n) f1 i) = minn (f2 n.+1) (\min_(i <= n) f2 i)
by rewrite H // IH // => i iH; rewrite H // (leq_trans iH). Qed.
52d
\min_(i <= n) f i * k = (\min_(i <= n) f i) * k
5a6
by elim: n => //= n ->; rewrite minnMl. Qed. (* Convolution *) Definition conv (f g : nat -> nat) n := \min_(i <= n) (f i + g (n - i)).
f, g:nat -> nat

conv f g 0 = f 0 + g 0
5ab
by []. Qed.
5ad
conv f g 1 = minn (f 1 + g 0) (f 0 + g 1)
5b2
by []. Qed.
5ad
increasing f -> increasing g -> conv (fnorm f) (fnorm g) =1 fnorm (conv f g)
5b7
5ae442
gI:increasing g
488

conv (fnorm f) (fnorm g) i = fnorm (conv f g) i
5be
\min_(i0 <= i) (f i0 - f 0 + (g (i - i0) - g 0)) = \min_(i0 <= i) (f i0 + g (i - i0) - (f 0 + g 0))
5ae4425bf
i, j:nat

j <= i -> f j - f 0 + (g (i - j) - g 0) = f j + g (i - j) - (f 0 + g 0)
by rewrite addnBA ?increasingE // addnBAC ?increasingE // subnDA. Qed.
f1, g1, f2, g2:nat -> nat

f1 =1 f2 -> g1 =1 g2 -> conv f1 g1 =1 conv f2 g2
5cc
by move=> fE gE i; apply: bigmin_ext => j; rewrite fE gE. Qed.
5ad
conv f g =1 conv g f
5d3
5ae127

\min_(i <= n) (f i + g (n - i)) <= \min_(i <= n) (g i + f (n - i))
5da
\min_(i <= n) (g i + f (n - i)) <= \min_(i <= n) (f i + g (n - i))
5ae
n, i:nat
iLn:i <= n

\min_(i <= n) (f i + g (n - i)) <= g i + f (n - i)
5dc
5e2
\min_(i <= n) (f i + g (n - i)) <= f (n - i) + g (n - (n - i))
5dc
5da
5de
5e2
\min_(i <= n) (g i + f (n - i)) <= f i + g (n - i)
5e2
\min_(i <= n) (g i + f (n - i)) <= g (n - i) + f (n - (n - i))
by apply: bigmin_inf (leq_subr _ _) (leqnn _). Qed.
5ad
increasing f -> increasing g -> increasing (conv f g)
5f6
5be
conv f g i <= conv f g i.+1
5c8
j <= i.+1 -> conv f g i <= f j + g (i.+1 - j)
5ae4425bf5c9
jLi:j < i.+1

conv f g i <= f j + g (i.+1 - j)
5c8
conv f g i <= f i.+1 + g (i.+1 - i.+1)
5c8
60a
5c8
conv f g i <= f i.+1 + g 0
by apply: bigmin_inf (leqnn i) _; rewrite subnn leq_add2r. Qed. (* merging increasing functions *) Fixpoint fmerge_aux (f g : nat -> nat) i j n := if n is n1.+1 then if f i < g j then fmerge_aux f g i.+1 j n1 else fmerge_aux f g i j.+1 n1 else minn (f i) (g j). Definition fmerge f g n := fmerge_aux f g 0 0 n.
f1, f2, g1, g2:nat -> nat
5c9

f1 =1 f2 -> g1 =1 g2 -> fmerge_aux f1 g1 i j =1 fmerge_aux f2 g2 i j
613
616
fE:f1 =1 f2
gE:g1 =1 g2
127
IH:forall i j : nat, fmerge_aux f1 g1 i j n = fmerge_aux f2 g2 i j n
5c9

(if f1 i < g1 j then fmerge_aux f1 g1 i.+1 j n else fmerge_aux f1 g1 i j.+1 n) = (if f2 i < g2 j then fmerge_aux f2 g2 i.+1 j n else fmerge_aux f2 g2 i j.+1 n)
by rewrite !(fE, gE, IH). Qed.
616

f1 =1 f2 -> g1 =1 g2 -> fmerge f1 g1 =1 fmerge f2 g2
622
by move=> fE gE n; apply: fmerge_aux_ext. Qed.
5ae
i, j, n:nat

increasing f -> increasing g -> forall k : nat, k <= n -> minn (f (i + k)) (g (j + (n - k))) <= fmerge_aux f g i j n
628
5ae62b4425bf

forall k : nat, k <= n -> minn (f (i + k)) (g (j + (n - k))) <= fmerge_aux f g i j n
5c8
minn (f (i + 0)) (g (j + (0 - 0))) <= minn (f i) (g j)
5ae4425bf127
IH:forall i j k : nat, k <= n -> minn (f (i + k)) (g (j + (n - k))) <= fmerge_aux f g i j n
i, j, k:nat
kLn:k <= n.+1
minn (f (i + k)) (g (j + (n.+1 - k))) <= (if f i < g j then fmerge_aux f g i.+1 j n else fmerge_aux f g i j.+1 n)
639
63d
5ae4425bf12763a63b63c
gLf:g j <= f i

minn (f (i + k)) (g (j + (n.+1 - k))) <= fmerge_aux f g i j.+1 n
5ae4425bf12763a63b63c
fLg:f i < g j
minn (f (i + k)) (g (j + (n.+1 - k))) <= fmerge_aux f g i.+1 j n
5ae4425bf12763a63b645

minn (f (i + n.+1)) (g (j + (n.+1 - n.+1))) <= fmerge_aux f g i j.+1 n
5ae4425bf12763a63b645
kLn:k < n.+1
646
648
64f
g j <= f (i + n.+1)
64f
g j <= fmerge_aux f g i j.+1 n
652648
64f
65b
651
64f
g j <= minn (f (i + n)) (g (j.+1 + (n - n)))
651
64f
f i <= f (i + n)
651
653
646
647
649
64b
5ae4425bf12763a5c964a

minn (f (i + 0)) (g (j + (n.+1 - 0))) <= fmerge_aux f g i.+1 j n
5ae4425bf12763a5c964a4a3654
minn (f (i + k.+1)) (g (j + (n.+1 - k.+1))) <= fmerge_aux f g i.+1 j n
670
f i <= g (j + n.+1)
670
f i <= fmerge_aux f g i.+1 j n
673
670
67c
672
670
f i <= minn (f (i.+1 + 0)) (g (j + (n - 0)))
672
670
g j <= g (j + (n - 0))
672
674
675
by rewrite subSS -addSnnS IH. Qed.
62a
exists2 k : nat, k <= n & fmerge_aux f g i j n = minn (f (i + k)) (g (j + (n - k)))
68c
5ae127
IH:forall i j : nat, exists2 k : nat, k <= n & fmerge_aux f g i j n = minn (f (i + k)) (g (j + (n - k)))
5c9

exists2 k : nat, k <= n.+1 & (if f i < g j then fmerge_aux f g i.+1 j n else fmerge_aux f g i j.+1 n) = minn (f (i + k)) (g (j + (n.+1 - k)))
5ae1276945c964a

exists2 k : nat, k <= n.+1 & fmerge_aux f g i.+1 j n = minn (f (i + k)) (g (j + (n.+1 - k)))
5ae1276945c9645
exists2 k : nat, k <= n.+1 & fmerge_aux f g i j.+1 n = minn (f (i + k)) (g (j + (n.+1 - k)))
69d
69e
5ae1276945c9645
kLn:0 <= n

exists2 k : nat, k <= n.+1 & minn (f (i + 0)) (g (j.+1 + (n - 0))) = minn (f (i + k)) (g (j + (n.+1 - k)))
5ae1276945c96454a3
kLn:k < n
ex2 (fun k : nat => k <= n.+1) (fun k0 : nat => minn (f (i + k.+1)) (g (j.+1 + (n - k.+1))) = minn (f (i + k0)) (g (j + (n.+1 - k0))))
6aa
6ac
by exists k.+1; rewrite ?(leq_trans kLn) // addSnnS -subSn. Qed.
5da
increasing f -> increasing g -> fmerge f g n = \max_(i < n.+1) minn (f i) (g (n - i))
6b1
5ae1274425bf

fmerge f g n = \max_(i < n.+1) minn (f i) (g (n - i))
6b8
fmerge_aux f g 0 0 n <= \max_(i < n.+1) minn (f i) (g (n - i))
6b8
\max_(i < n.+1) minn (f i) (g (n - i)) <= fmerge_aux f g 0 0 n
5ae1274425bf
i1:nat
i1Ln:i1 <= n

minn (f (0 + i1)) (g (0 + (n - i1))) <= \max_(i < n.+1) minn (f i) (g (n - i))
6be
6b8
6c0
5ae1274425bf53e

minn (f i) (g (n - i)) <= fmerge_aux f g 0 0 n
by apply: fmerge_aux_correct; rewrite -1?ltnS. Qed.
5ad
increasing f -> increasing g -> increasing (fmerge f g)
6d1
5ae4425bf127

\max_(i < n.+1) minn (f i) (g (n - i)) <= \max_(i < n.+2) minn (f i) (g (n.+1 - i))
5ae4425bf12753e

minn (f i) (g (n - i)) <= \max_(i < n.+2) minn (f i) (g (n.+1 - i))
6dd
minn (f i) (g (n - i)) <= minn (f (inord i)) (g (n.+1 - inord i))
6dd
minn (f i) (g (n - i)) <= minn (f i) (g (n.+1 - i))
6dd
g (n - i) <= g (n.+1 - i)
5ae44212753e

n - i <= n.+1 - i
by rewrite leq_sub2r. Qed.
5ad
fmerge f g 0 = minn (f 0) (g 0)
6f1
by []. Qed. Fixpoint sum_fmerge_aux (f g : nat -> nat) i j n := if n is n1.+1 then if f i < g j then f i + sum_fmerge_aux f g i.+1 j n1 else g j + sum_fmerge_aux f g i j.+1 n1 else minn (f i) (g j). Definition sum_fmerge f g n := sum_fmerge_aux f g 0 0 n.
5ae
n, i, j:nat

sum_fmerge_aux f g i j n = \sum_(k < n.+1) fmerge_aux f g i j k
6f6
5ae127
IH:forall i j : nat, sum_fmerge_aux f g i j n = \sum_(k < n.+1) fmerge_aux f g i j k
5c9

(if f i < g j then f i + sum_fmerge_aux f g i.+1 j n else g j + sum_fmerge_aux f g i j.+1 n) = \sum_(k < n.+2) fmerge_aux f g i j k
by rewrite big_ord_recl /= /minn; case: leqP; rewrite IH. Qed.
5da
sum_fmerge f g n = \sum_(k < n.+1) fmerge f g k
703
by apply: sum_fmerge_aux_correct. Qed.
62a
increasing f -> increasing g -> forall k : nat, k <= n.+1 -> sum_fmerge_aux f g i j n <= \sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j + l)
708
631
forall k : nat, k <= n.+1 -> sum_fmerge_aux f g i j n <= \sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j + l)
5c8
minn (f i) (g j) <= \sum_(l < 0) f (i + l) + \sum_(l < 1 - 0) g (j + l)
5c8
minn (f i) (g j) <= \sum_(l < 1) f (i + l) + \sum_(l < 1 - 1) g (j + l)
5ae4425bf127
IH:forall i j k : nat, k <= n.+1 -> sum_fmerge_aux f g i j n <= \sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j + l)
63b
kLn:k <= n.+2
(if f i < g j then f i + sum_fmerge_aux f g i.+1 j n else g j + sum_fmerge_aux f g i j.+1 n) <= \sum_(l < k) f (i + l) + \sum_(l < n.+2 - k) g (j + l)
711
5c8
716
717
71e
718
71b
5ae4425bf12771963b71a645

g j + sum_fmerge_aux f g i j.+1 n <= \sum_(l < k) f (i + l) + \sum_(l < n.+2 - k) g (j + l)
5ae4425bf12771963b71a64a
f i + sum_fmerge_aux f g i.+1 j n <= \sum_(l < k) f (i + l) + \sum_(l < n.+2 - k) g (j + l)
5ae4425bf12771963b645

g j + sum_fmerge_aux f g i j.+1 n <= \sum_(l < n.+2) f (i + l) + \sum_(l < n.+2 - n.+2) g (j + l)
5ae4425bf12771963b645
kLn:k < n.+2
729
72b
731
g j + sum_fmerge_aux f g i j.+1 n <= f i + \sum_(i0 < n.+1) f (i + bump 0 i0)
733
731
sum_fmerge_aux f g i j.+1 n <= \sum_(i0 < n.+1) f (i + bump 0 i0)
733
731
sum_fmerge_aux f g i j.+1 n <= \sum_(i0 < n.+1) f (i + (1 + i0))
733
731
\sum_(l < n.+1) f (i + l) + \sum_(l < n.+1 - n.+1) g (j.+1 + l) <= \sum_(i0 < n.+1) f (i + (1 + i0))
733
5ae4425bf12771963b645
l:'I_n.+1

f (i + l) <= f (i + (1 + l))
733
735
729
72a
735
sum_fmerge_aux f g i j.+1 n <= \sum_(l < k) f (i + l) + \sum_(i < n.+1 - k) g (j + lift ord0 i)
72a
735
\sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j.+1 + l) <= \sum_(l < k) f (i + l) + \sum_(i < n.+1 - k) g (j + lift ord0 i)
72a
5ae4425bf12771963b645736
l:'I_(n.+1 - k)

g (j.+1 + l) <= g (j + lift ord0 l)
72a
72c
72d
5ae4425bf12771963b64a

f i + sum_fmerge_aux f g i.+1 j n <= \sum_(l < n.+2) f (i + l) + \sum_(l < n.+2 - n.+2) g (j + l)
5ae4425bf12771963b64a736
72d
764
sum_fmerge_aux f g i.+1 j n <= \sum_(i0 < n.+1) f (i + (1 + i0))
766
764
\sum_(l < n.+1) f (i.+1 + l) + \sum_(l < n.+1 - n.+1) g (j + l) <= \sum_(i0 < n.+1) f (i + (1 + i0))
766
5ae4425bf12771963b64a74b

f (i.+1 + l) <= f (i + (1 + l))
766
768
72d
5ae4425bf1277195c964a4a3
kLn:k.+1 < n.+2

f i + sum_fmerge_aux f g i.+1 j n <= \sum_(l < k.+1) f (i + l) + \sum_(l < n.+2 - k.+1) g (j + l)
5ae4425bf1277195c964a
f i + sum_fmerge_aux f g i.+1 j n <= \sum_(l < 0) f (i + l) + \sum_(l < n.+2 - 0) g (j + l)
77c
f i + sum_fmerge_aux f g i.+1 j n <= \sum_(l < k.+1) f (i + l) + \sum_(l < n.+1 - k) g (j + l)
77f
77c
k <= n.+1
77c
f i + (\sum_(l < k) f (i.+1 + l) + \sum_(l < n.+1 - k) g (j + l)) <= \sum_(l < k.+1) f (i + l) + \sum_(l < n.+1 - k) g (j + l)
780
77c
78d
77f
5ae4425bf1277195c964a4a377d
l:'I_k

f (i.+1 + l) <= f (i + lift ord0 l)
77f
781
782
781
f i + sum_fmerge_aux f g i.+1 j n <= \sum_(l < n.+2) g (j + l)
781
f i + (\sum_(l < 0) f (i.+1 + l) + \sum_(l < n.+1 - 0) g (j + l)) <= \sum_(l < n.+2) g (j + l)
781
f i <= g (j + ord_max)
781
g j <= g (j + ord_max)
by rewrite increasingE // leq_addr. Qed.
5ae
k, n:nat

increasing f -> increasing g -> k <= n -> \sum_(i < n) fmerge f g i <= \sum_(i < k) f i + \sum_(i < n - k) g i
7ab
5ae4a34425bf

k <= 0 -> \sum_(i < 0) fmerge f g i <= \sum_(i < k) f i + \sum_(i < 0 - k) g i
5ae4a34425bf12763c
\sum_(i < n.+1) fmerge f g i <= \sum_(i < k) f i + \sum_(i < n.+1 - k) g i
7b8
7b9
7b8
sum_fmerge f g n <= \sum_(i < k) f i + \sum_(i < n.+1 - k) g i
exact: (sum_fmerge_aux_conv_correct 0 0 fI gI kLn). Qed.
62a
exists2 k : nat, k <= n.+1 & sum_fmerge_aux f g i j n = \sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j + l)
7c2
5ae5c9

exists2 k : nat, k <= 1 & minn (f i) (g j) = \sum_(l < k) f (i + l) + \sum_(l < 1 - k) g (j + l)
5ae127
IH:forall i j : nat, exists2 k : nat, k <= n.+1 & sum_fmerge_aux f g i j n = \sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j + l)
5c9
exists2 k : nat, k <= n.+2 & (if f i < g j then f i + sum_fmerge_aux f g i.+1 j n else g j + sum_fmerge_aux f g i j.+1 n) = \sum_(l < k) f (i + l) + \sum_(l < n.+2 - k) g (j + l)
5ae5c9645

exists2 k : nat, k <= 1 & g j = \sum_(l < k) f (i + l) + \sum_(l < 1 - k) g (j + l)
5ae5c964a
exists2 k : nat, k <= 1 & f i = \sum_(l < k) f (i + l) + \sum_(l < 1 - k) g (j + l)
7cc
7d7
7d8
7cb
7cd
7cf
5ae1277ce5c9645

exists2 k : nat, k <= n.+2 & g j + sum_fmerge_aux f g i j.+1 n = \sum_(l < k) f (i + l) + \sum_(l < n.+2 - k) g (j + l)
5ae1277ce5c964a
exists2 k : nat, k <= n.+2 & f i + sum_fmerge_aux f g i.+1 j n = \sum_(l < k) f (i + l) + \sum_(l < n.+2 - k) g (j + l)
5ae1277ce5c96454a363c

ex2 (fun k : nat => k <= n.+2) (fun k0 : nat => g j + (\sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j.+1 + l)) = \sum_(l < k0) f (i + l) + \sum_(l < n.+2 - k0) g (j + l))
7e4
7eb
g j + (\sum_(l < k) f (i + l) + \sum_(l < n.+1 - k) g (j.+1 + l)) = \sum_(l < k) f (i + l) + \sum_(l < n.+2 - k) g (j + l)
7e4
7eb
\sum_(l < k) f (i + l) + (g j + \sum_(l < n.+1 - k) g (j.+1 + l)) = \sum_(l < k) f (i + l) + (g j + \sum_(i < n.+1 - k) g (j + lift ord0 i))
7e4
7e6
7e7
5ae1277ce5c964a4a363c

f i + (\sum_(l < k) f (i.+1 + l) + \sum_(l < n.+1 - k) g (j + l)) = \sum_(l < k.+1) f (i + l) + \sum_(l < n.+2 - k.+1) g (j + l)
7fb
f i + (\sum_(l < k) f (i.+1 + l) + \sum_(l < n.+1 - k) g (j + l)) = f i + (\sum_(i0 < k) f (i + lift ord0 i0) + \sum_(l < n.+1 - k) g (j + l))
by congr (_ + (_ + _)); apply: eq_bigr => l _; rewrite addnCA. Qed.
5da
exists2 k : nat, k <= n & \sum_(i < n) fmerge f g i = \sum_(i < k) f i + \sum_(i < n - k) g i
802
5da
exists2 k : nat, k <= n.+1 & \sum_(i < n.+1) fmerge f g i = \sum_(i < k) f i + \sum_(i < n.+1 - k) g i
5ae35463c
sE:sum_fmerge_aux f g 0 0 n = \sum_(l < k) f (0 + l) + \sum_(l < n.+1 - k) g (0 + l)

809
by exists k; rewrite // -sum_fmerge_correct [LHS]sE. Qed.
5da
increasing f -> increasing g -> \sum_(i < n) fmerge f g i = conv (fun n : nat => \sum_(i < n) f i) (fun n : nat => \sum_(i < n) g i) n
810
6b8
\sum_(i < n) fmerge f g i = conv (fun n : nat => \sum_(i < n) f i) (fun n : nat => \sum_(i < n) g i) n
6b8
conv (fun n : nat => \sum_(i < n) f i) (fun n : nat => \sum_(i < n) g i) n <= \sum_(i < n) fmerge f g i
6b8
\sum_(i < n) fmerge f g i <= conv (fun n : nat => \sum_(i < n) f i) (fun n : nat => \sum_(i < n) g i) n
5ae1274425bf4a3
kLn:k <= n

conv (fun n : nat => \sum_(i < n) f i) (fun n : nat => \sum_(i < n) g i) n <= \sum_(i < k) f i + \sum_(i < n - k) g i
81c
6b8
81e
822
\sum_(i < n) fmerge f g i <= \sum_(i < k) f i + \sum_(i < n - k) g i
by apply: leq_sum_fmerge_conv. Qed. (* This is 3.2 *)
5ad
convex f -> convex g -> delta (conv f g) =1 fmerge (delta f) (delta g)
82d
5ae4425085bf
dgI:increasing (delta g)
127

delta (conv f g) n = fmerge (delta f) (delta g) n
834
delta (fnorm (conv f g)) n = fmerge (delta f) (delta g) n
834
delta (conv (fnorm f) (fnorm g)) n = fmerge (delta f) (delta g) n
834
conv (fnorm f) (fnorm g) =1 conv (fun n : nat => \sum_(i < n) delta (fnorm f) i) (fun n : nat => \sum_(i < n) delta (fnorm g) i)
834
delta (conv (fun n : nat => \sum_(i < n) delta (fnorm f) i) (fun n : nat => \sum_(i < n) delta (fnorm g) i)) n = fmerge (delta f) (delta g) n
834
845
834
conv (fun n : nat => \sum_(i < n) delta (fnorm f) i) (fun n : nat => \sum_(i < n) delta (fnorm g) i) =1 (fun n : nat => \sum_(i < n) fmerge (delta (fnorm f)) (delta (fnorm g)) i)
834
delta (fun n : nat => \sum_(i < n) fmerge (delta (fnorm f)) (delta (fnorm g)) i) n = fmerge (delta f) (delta g) n
5ae4425085bf835354

increasing (delta (fnorm f))
853
increasing (delta (fnorm g))
84e
853
857
84d
834
84f
834
fmerge (fun n : nat => fnorm f n.+1 - fnorm f n) (fun n : nat => fnorm g n.+1 - fnorm g n) n = fmerge (fun n : nat => f n.+1 - f n) (fun n : nat => g n.+1 - g n) n
by apply: fmerge_aux_ext => i; apply: delta_fnorm. Qed.
5ad
convex f -> convex g -> convex (conv f g)
863
5ae4425085bf835

increasing (delta (conv f g))
86a
increasing (fmerge (delta f) (delta g))
by apply: increasing_fmerge. Qed. End Convex. Notation "\min_ ( i <= n ) F" := (bigmin (fun i => F) n) (at level 41, F at level 41, i, n at level 50, format "\min_ ( i <= n ) F"). (* Mimic AC match for leq_trans *) Ltac is_num term := match term with | 0 => true | S ?X => is_num X | _ => false end. Ltac split_term term := match term with | ?X * ?Y => match is_num X with true => constr:((X, Y)) | false => let v := once (split_term X) in constr:((fst v, snd v * Y)) end | ?X => match is_num X with true => constr:((X, 1)) | _ => constr:((1, X)) end | _ => false end. Ltac delta_term n1 n2 t2 := let n := constr:(n1 - n2) in let n1 := eval compute in n in let vt2 := eval lazy delta [fst snd] iota beta in t2 in let r := match n1 with | 0 => constr:(0) | 1 => constr:(t2) | ?X => match vt2 with | 1 => X | _ => constr:(X * vt2) end end in eval lazy delta [fst snd] iota beta in r. Ltac delta_lterm2 n1 t1 lt2 := match lt2 with | ?X2 + ?Y2 => let v2 := split_term Y2 in let n2 := constr:(fst v2) in let t2 := constr:(snd v2) in let t := constr:((t1, t2)) in let vt := eval lazy delta [fst snd] iota beta in t in match vt with | (?X, ?X) => delta_term n1 n2 t2 | _ => delta_lterm2 n1 t1 X2 end | ?Y2 => let v2 := split_term Y2 in let n2 := constr:(fst v2) in let t2 := constr:(snd v2) in let t := constr:((t1, t2)) in let vt := eval lazy delta [fst snd] iota beta in t in match vt with | (?X, ?X) => delta_term n1 n2 t2 | _ => delta_term n1 0 t1 end end. Ltac make_sum t1 t2 := match t1 with 0 => t2 | _ => match t2 with 0 => t1 | _ => constr:(t1 + t2) end end. Ltac delta_lterm1 lt1 lt2 := match lt1 with | ?X1 + ?Y1 => let v1 := split_term Y1 in let n1 := constr:(fst v1) in let t1 := constr:(snd v1) in let r1 := delta_lterm1 X1 lt2 in let r2 := delta_lterm2 n1 t1 lt2 in make_sum r1 r2 | ?Y1 => let v1 := split_term Y1 in let n1 := constr:(fst v1) in let t1 := constr:(snd v1) in delta_lterm2 n1 t1 lt2 end. Ltac test t1 t2 := let xx := delta_lterm1 t1 t2 in pose kk := xx. Ltac applyr H := rewrite -?mul2n in H |- *; match goal with H: is_true (leq _ ?X) |- is_true (leq _ ?Y) => ring_simplify X Y in H; ring_simplify X Y; rewrite ?[nat_of_bin _]/= in H |- * end; let Z := fresh "Z" in match goal with H: is_true (leq _ ?X1) |- is_true (leq _ ?Y1) => let v := delta_lterm1 Y1 X1 in (try (rewrite [Z in _ <= Z](_ : _ = v + X1))); [ apply: leq_trans (leq_add (leqnn _) H); rewrite {H}// ?(add0n,addn0) | ring] end. Ltac applyl H := rewrite -?mul2n in H |- *; match goal with H: is_true (leq ?X _) |- is_true (leq ?Y _) => ring_simplify X Y; ring_simplify X Y in H; rewrite ?[nat_of_bin _]/= in H |- * end; let Z := fresh "Z" in match goal with H: is_true (leq ?X1 _) |- is_true (leq ?Y1 _) => let v := delta_lterm1 Y1 X1 in (try rewrite [Z in Z <= _](_ : Y1 = v + X1)); [apply: leq_trans (leq_add (leqnn _) H) _; rewrite {H}// ?(add0n,addn0) | ring] end. Ltac gsimpl := rewrite -?mul2n in |- *; match goal with |- is_true (leq ?X ?Y) => ring_simplify X Y; rewrite ?[nat_of_bin _]/= end; let Z := fresh "Z" in match goal with |- is_true (leq ?X1 ?Y1) => let v := delta_lterm1 Y1 X1 in match v with | 0 => let v := delta_lterm1 X1 Y1 in let v1 := delta_lterm1 X1 v in let v2 := delta_lterm1 Y1 v1 in (try (rewrite [Z in _ <= Z](_ : Y1 = v2 + v1); last by ring)); (try (rewrite [Z in Z <= _](_ : X1 = v + v1); last by ring)); rewrite ?leq_add2r | _ => let v1 := delta_lterm1 Y1 v in let v2 := delta_lterm1 X1 v1 in (try (rewrite [Z in _ <= Z](_ : Y1 = v + v1); last by ring)); (try (rewrite [Z in Z <= _](_ : X1 = v2 + v1); last by ring)); rewrite ?leq_add2r end end. Ltac sring := rewrite -!mul2n; ring. Ltac changel t := let X := fresh "X" in rewrite [X in X <= _](_ : _ = t); last by (ring || sring). Ltac changer t := let X := fresh "X" in rewrite [X in _ <= X](_ : _ = t); last by (ring || sring).