Update from HH
[Flyspeck/.git] / jHOLLight / Examples / seq-compiled.hl
1 needs "Examples/ssrnat-compiled.hl";;
2
3 (* Module Seq*)
4 module Seq = struct
5
6 open Ssrfun;;
7 open Ssrbool;;
8 open Ssrnat;;
9 prioritize_num();;
10
11 (* Section Sequences *)
12 Sections.begin_section "Sequences";;
13 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
14 (Sections.add_section_var (mk_var ("x0", (`:A`))));;
15 (Sections.add_section_type (mk_var ("x", (`:A`))); Sections.add_section_type (mk_var ("y", (`:A`))); Sections.add_section_type (mk_var ("z", (`:A`))));;
16 (Sections.add_section_type (mk_var ("m", (`:num`))); Sections.add_section_type (mk_var ("n", (`:num`))));;
17 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
18 let size = new_definition `sizel = LENGTH`;;
19
20 (* Lemma size0nil *)
21 let size0nil = Sections.section_proof ["s"]
22 `sizel s = 0 ==> s = []`
23 [
24    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN (BETA_TAC THEN ((TRY done_tac))) THEN ((((use_arg_then2 ("size", [size]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (arith_tac) THEN (done_tac));
25 ];;
26 let nilp = new_definition `!(s:(A)list). nilp s <=> (sizel s = 0)`;;
27
28 (* Lemma nilP *)
29 let nilP = Sections.section_proof ["s"]
30 `s = [] <=> nilp s`
31 [
32    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN ((((use_arg_then2 ("nilp", [nilp]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("NOT_SUC", [NOT_SUC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
33 ];;
34 let head = define `!(x0:A) h t. headl x0 [] = x0 /\ headl x0 (CONS h t) = h`;;
35 let behead = define `!(h:A) t. behead [] = [] /\ behead (CONS h t) = t`;;
36
37 (* Lemma size_behead *)
38 let size_behead = Sections.section_proof ["s"]
39 `sizel (behead s) = (sizel s) - 1`
40 [
41    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN ((((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size", [size]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("SUC_SUB1", [SUC_SUB1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sub0n", [sub0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
42 ];;
43 let ncons = new_definition `!n (x:A). ncons n x = iter n (CONS x)`;;
44 let nseq = new_definition `!n (x:A). nseq n x = ncons n x []`;;
45
46 (* Lemma size_nil *)
47 let size_nil = Sections.section_proof []
48 `sizel ([]:(A)list) = 0`
49 [
50    (((((use_arg_then2 ("size", [size]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
51 ];;
52
53 (* Lemma size_cons *)
54 let size_cons = Sections.section_proof ["h";"t"]
55 `sizel (CONS (h:A) t) = SUC (sizel t)`
56 [
57    (((((use_arg_then2 ("size", [size]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
58 ];;
59
60 (* Lemma size_ncons *)
61 let size_ncons = Sections.section_proof ["n";"x";"s"]
62 `sizel (ncons n x s) = n + sizel s`
63 [
64    ((((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ncons", [ncons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((repeat_tactic 0 10 (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (move ["n"]) THEN (move ["IH"])));
65    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addSn", [addSn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
66 ];;
67
68 (* Lemma size_nseq *)
69 let size_nseq = Sections.section_proof ["n";"x"]
70 `sizel (nseq n (x:A)) = n`
71 [
72    (((((use_arg_then2 ("nseq", [nseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_ncons", [size_ncons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
73 ];;
74 parse_as_infix ("::", (12, "right"));;
75 override_interface ("::", `CONS`);;
76 make_overloadable "++" `:A -> A -> A`;;
77 let cat = define `!(x:A) t s2. cat [] s2 = s2 /\ cat (CONS x t) s2 = x :: cat t s2`;;
78 overload_interface ("++", `cat`);;
79
80 (* Lemma cat0s *)
81 let cat0s = Sections.section_proof ["s"]
82 `[] ++ (s:(A)list) = s`
83 [
84    ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
85 ];;
86
87 (* Lemma cat1s *)
88 let cat1s = Sections.section_proof ["x";"s"]
89 `[x:A] ++ s = x :: s`
90 [
91    ((repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
92 ];;
93
94 (* Lemma cat_cons *)
95 let cat_cons = Sections.section_proof ["x";"s1";"s2"]
96 `(x :: s1) ++ s2 = x :: s1 ++ s2`
97 [
98    ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
99 ];;
100
101 (* Lemma cat_nseq *)
102 let cat_nseq = Sections.section_proof ["n";"x";"s"]
103 `nseq n (x:A) ++ s = ncons n x s`
104 [
105    ((((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) THEN (((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (move ["n"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
106 ];;
107
108 (* Lemma cats0 *)
109 let cats0 = Sections.section_proof ["s"]
110 `s ++ [] = (s:(A)list)`
111 [
112    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]))]) THEN (((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
113 ];;
114
115 (* Lemma catA *)
116 let catA = Sections.section_proof ["s1";"s2";"s3"]
117 `s1 ++ s2 ++ s3 = (s1 ++ s2) ++ s3:(A)list`
118 [
119    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]))]) THEN (((repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((TRY done_tac))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
120 ];;
121
122 (* Lemma size_cat *)
123 let size_cat = Sections.section_proof ["s1";"s2"]
124 `sizel (s1 ++ s2) = sizel s1 + sizel (s2:(A)list)`
125 [
126    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]))]) THEN (((repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("addSn", [addSn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
127 ];;
128 let rcons = define `!x t (z:A). rcons [] z = [z] /\ rcons (x :: t) z = x :: rcons t z`;;
129
130 (* Lemma rcons_cons *)
131 let rcons_cons = Sections.section_proof ["x";"s";"z"]
132 `rcons (x :: s) z = x:A :: rcons s z`
133 [
134    ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
135 ];;
136
137 (* Lemma cats1 *)
138 let cats1 = Sections.section_proof ["s";"z"]
139 `s ++ [z:A] = rcons s z`
140 [
141    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]))]) THEN (((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
142 ];;
143 let last = define `!(x:A) h t. last x [] = x /\ last x (h :: t) = last h t`;;
144 let belast = define `!(x:A) h t. belast x [] = [] /\ belast x (h :: t) = x :: (belast h t)`;;
145
146 (* Lemma lastI *)
147 let lastI = Sections.section_proof ["x";"s"]
148 `(x:A :: s) = rcons (belast x s) (last x s)`
149 [
150    (((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (BETA_TAC THEN (move ["x"])) THEN ((((use_arg_then2 ("belast", [belast]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
151 ];;
152
153 (* Lemma last_cons *)
154 let last_cons = Sections.section_proof ["x";"y";"s"]
155 `last x (y:A :: s) = last y s`
156 [
157    ((((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
158 ];;
159
160 (* Lemma size_rcons *)
161 let size_rcons = Sections.section_proof ["s";"x"]
162 `sizel (rcons s (x:A)) = SUC (sizel s)`
163 [
164    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addnS", [addnS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
165 ];;
166
167 (* Lemma size_belast *)
168 let size_belast = Sections.section_proof ["x";"s"]
169 `sizel (belast (x:A) s) = sizel s`
170 [
171    (((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (BETA_TAC THEN (move ["x"])) THEN ((((use_arg_then2 ("belast", [belast]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
172 ];;
173
174 (* Lemma last_cat *)
175 let last_cat = Sections.section_proof ["x";"s1";"s2"]
176 `last (x:A) (s1 ++ s2) = last (last x s1) s2`
177 [
178    (((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN (BETA_TAC THEN (move ["x"])) THEN ((((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
179 ];;
180
181 (* Lemma last_rcons *)
182 let last_rcons = Sections.section_proof ["x";"s";"z"]
183 `last x (rcons s z) = z:A`
184 [
185    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("last_cat", [last_cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
186 ];;
187
188 (* Lemma belast_cat *)
189 let belast_cat = Sections.section_proof ["x";"s1";"s2"]
190 `belast x (s1 ++ s2) = belast x s1 ++ belast (last (x:A) s1) s2`
191 [
192    (((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN (BETA_TAC THEN (move ["x"])) THEN ((((use_arg_then2 ("belast", [belast]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("belast", [belast]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
193 ];;
194
195 (* Lemma belast_rcons *)
196 let belast_rcons = Sections.section_proof ["x";"s";"z"]
197 `belast x (rcons s z) = x:A :: s`
198 [
199    (((((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("belast_cat", [belast_cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("belast", [belast]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
200 ];;
201
202 (* Lemma cat_rcons *)
203 let cat_rcons = Sections.section_proof ["x";"s1";"s2"]
204 `rcons s1 x ++ s2 = s1 ++ (x:A :: s2)`
205 [
206    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("catA", [catA]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
207 ];;
208
209 (* Lemma rcons_cat *)
210 let rcons_cat = Sections.section_proof ["x";"s1";"s2"]
211 `rcons (s1 ++ s2) x = s1 ++ rcons s2 (x:A)`
212 [
213    (((repeat_tactic 1 9 (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
214 ];;
215
216 (* Lemma last_ind *)
217 let last_ind = Sections.section_proof ["P"]
218 `P [] ==> (!s (x : A). P s ==> P (rcons s x)) ==> (!s. P s)`
219 [
220    (BETA_TAC THEN (move ["Hnil"]) THEN (move ["Hlast"]) THEN (move ["s"]));
221    (((fun arg_tac -> (use_arg_then2 ("cat0s", [cat0s])) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [])))));
222    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("Hnil", [])) (disch_tac [])) THEN (clear_assumption "Hnil") THEN ((fun arg_tac -> arg_tac (Arg_term (`[]`))) (disch_tac [])) THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s2"]) THEN (move ["IHs"]))]) ((((use_arg_then2 ("cats0", [cats0]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
223    (((((use_arg_then2 ("cat_rcons", [cat_rcons]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (move ["s1"]) THEN (move ["Ps1"])) THEN (((use_arg_then2 ("IHs", [])) (disch_tac [])) THEN (clear_assumption "IHs") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("Hlast", [])) (disch_tac [])) THEN (clear_assumption "Hlast") THEN (exact_tac)) THEN (done_tac));
224 ];;
225 let nth = define `!(x0:A) h t n. nth x0 [] n = x0 /\ nth x0 (h :: t) 0 = h /\ nth x0 (h :: t) (SUC n) = nth x0 t n`;;
226 let set_nth = define `!(x0:A) h t n y. 
227         set_nth x0 [] n y = ncons n x0 [y] /\
228         set_nth x0 (h :: t) 0 y = y :: t /\
229         set_nth x0 (h :: t) (SUC n) y = h :: set_nth x0 t n y`;;
230
231 (* Lemma nth0 *)
232 let nth0 = Sections.section_proof ["s"]
233 `nth x0 s 0 = headl x0 s`
234 [
235    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("head", [head]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
236 ];;
237
238 (* Lemma nth_default *)
239 let nth_default = Sections.section_proof ["s";"n"]
240 `sizel s <= n ==> nth x0 s n = x0`
241 [
242    ((((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) case [ALL_TAC; (move ["n"])])) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
243    (((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", [])) (disch_tac [])) THEN (clear_assumption "IHs") THEN (exact_tac)) THEN (done_tac));
244 ];;
245
246 (* Lemma nth_nil *)
247 let nth_nil = Sections.section_proof ["n"]
248 `nth x0 [] n = x0`
249 [
250    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
251 ];;
252
253 (* Lemma last_nth *)
254 let last_nth = Sections.section_proof ["x";"s"]
255 `last x s = nth x0 (x :: s) (sizel s)`
256 [
257    ((THENL_FIRST) (((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (BETA_TAC THEN (move ["x"])) THEN ((((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) (done_tac));
258    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
259 ];;
260
261 (* Lemma nth_last *)
262 let nth_last = Sections.section_proof ["s"]
263 `nth x0 s (sizel s - 1) = last x0 s`
264 [
265    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["t"]) THEN (move ["h"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("succnK", [succnK]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("last_nth", [last_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
266 ];;
267
268 (* Lemma nth_behead *)
269 let nth_behead = Sections.section_proof ["s";"n"]
270 `nth x0 (behead s) n = nth x0 s (SUC n)`
271 [
272    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
273 ];;
274
275 (* Lemma nth_cat *)
276 let nth_cat = Sections.section_proof ["s1";"s2";"n"]
277 `nth x0 (s1 ++ s2) n = if n < sizel s1 then nth x0 s1 n else nth x0 s2 (n - sizel s1)`
278 [
279    ((THENL) (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sub0n", [sub0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("subn0", [subn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) [(arith_tac); (arith_tac); BETA_TAC]);
280    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
281 ];;
282
283 (* Lemma nth_rcons *)
284 let nth_rcons = Sections.section_proof ["s";"x";"n"]
285 `nth x0 (rcons s x) n =
286     if n < sizel s then nth x0 s n else if n = sizel s then x else x0`
287 [
288    ((THENL_FIRST) (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0Sn", [ltn0Sn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac))) ((arith_tac) THEN (done_tac)));
289    (((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
290 ];;
291
292 (* Lemma nth_ncons *)
293 let nth_ncons = Sections.section_proof ["m";"x";"s";"n"]
294 `nth x0 (ncons m x s) n = if n < m then x else nth x0 s (n - m)`
295 [
296    ((((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN elim) [ALL_TAC; ((move ["m"]) THEN (move ["IHm"]))]) THEN ((THENL) case [ALL_TAC; (move ["n"])])) THEN ((((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("subn0", [subn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ncons", [ncons]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (TRY ((arith_tac))));
297    (((((use_arg_then2 ("IHm", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
298 ];;
299
300 (* Lemma nth_nseq *)
301 let nth_nseq = Sections.section_proof ["m";"x";"n"]
302 `nth x0 (nseq m x) n = (if n < m then x else x0)`
303 [
304    ((((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN elim) [ALL_TAC; ((move ["m"]) THEN (move ["IHm"]))]) THEN ((THENL) case [ALL_TAC; (move ["n"])])) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (TRY ((arith_tac))));
305    (((((use_arg_then2 ("ncons", [ncons]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nseq", [nseq]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHm", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
306 ];;
307
308 (* Lemma eq_from_nth *)
309 let eq_from_nth = Sections.section_proof ["s1";"s2"]
310 `sizel s1 = sizel s2 ==> (!i. i < sizel s1 ==> nth x0 s1 i = nth x0 s2 i) ==>
311   s1 = s2`
312 [
313    ((((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x1"]) THEN (move ["s1"]) THEN (move ["IHs1"]))]) THEN ((THENL) case [ALL_TAC; ((move ["x2"]) THEN (move ["s2"]))])) THEN ((((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("NOT_SUC", [NOT_SUC]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
314    ((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq_sz"]) THEN (move ["eq_s12"]));
315    ((((fun arg_tac -> (use_arg_then2 ("eq_s12", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (((((use_arg_then2 ("ltn0Sn", [ltn0Sn]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 2 0 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (move ["_"])) THEN (((((fun arg_tac -> (use_arg_then2 ("IHs1", [])) (fun fst_arg -> (use_arg_then2 ("s2", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("eq_sz", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (move ["i"])));
316    ((((fun arg_tac -> (use_arg_then2 ("eq_s12", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`SUC i`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 2 0 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
317 ];;
318
319 (* Lemma size_set_nth *)
320 let size_set_nth = Sections.section_proof ["s";"n";"y"]
321 `sizel (set_nth x0 s n y) = maxn (SUC n) (sizel s)`
322 [
323    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN (((use_arg_then2 ("set_nth", [set_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))));
324    (((((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("maxn", [maxn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (arith_tac) THEN (done_tac));
325    (((((use_arg_then2 ("size_ncons", [size_ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ONE", [ONE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("addn1", [addn1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("maxn", [maxn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (arith_tac) THEN (done_tac));
326    ((((use_arg_then2 ("add_sub_maxn", [add_sub_maxn]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (arith_tac) THEN (done_tac));
327    (((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("add1n", [add1n]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("addn_maxr", [addn_maxr]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("add1n", [add1n]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
328 ];;
329
330 (* Lemma set_nth_nil *)
331 let set_nth_nil = Sections.section_proof ["n";"y"]
332 `set_nth x0 [] n y = ncons n x0 [y]`
333 [
334    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN (((use_arg_then2 ("set_nth", [set_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
335 ];;
336
337 (* Lemma ltS0 *)
338 let ltS0 = Sections.section_proof ["n"]
339 `SUC n < 0 <=> F`
340 [
341    ((arith_tac) THEN (done_tac));
342 ];;
343
344 (* Lemma eqS0 *)
345 let eqS0 = Sections.section_proof ["n"]
346 `SUC n = 0 <=> F`
347 [
348    ((arith_tac) THEN (done_tac));
349 ];;
350
351 (* Lemma eq0S *)
352 let eq0S = Sections.section_proof ["n"]
353 `0 = SUC n <=> F`
354 [
355    ((arith_tac) THEN (done_tac));
356 ];;
357
358 (* Lemma gtS0 *)
359 let gtS0 = Sections.section_proof ["n"]
360 `0 < SUC n`
361 [
362    ((arith_tac) THEN (done_tac));
363 ];;
364
365 (* Lemma ltSS *)
366 let ltSS = Sections.section_proof ["m";"n"]
367 `SUC m < SUC n <=> m < n`
368 [
369    ((arith_tac) THEN (done_tac));
370 ];;
371
372 (* Lemma nth_set_nth *)
373 let nth_set_nth = Sections.section_proof ["s";"n";"y";"i"]
374 `nth x0 (set_nth x0 s n y) i = if i = n then y else nth x0 s i`
375 [
376    ((THENL_ROT (-1)) (((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["m"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("set_nth", [set_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth_nil", [nth_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth_ncons", [nth_ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sub0n", [sub0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltS0", [ltS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("eqS0", [eqS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("eq0S", [eq0S]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("subn0", [subn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))))));
377    (((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
378    ((((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))));
379    ((THENL_LAST) ((THENL) (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltngtP", [ltngtP])) (fun fst_arg -> (use_arg_then2 ("m", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [(move ["lt_mn"]); ((THENL) case [(move ["lt_nm"]); (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))])]) (((((use_arg_then2 ("subnn", [subnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (done_tac)));
380    (((((use_arg_then2 ("lt_mn", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((fun arg_tac -> arg_tac (Arg_theorem (ARITH_RULE `m < n ==> (m = n <=> F)`)))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
381    ((THENL_LAST) ((((use_arg_then2 ("nth_default", [nth_default]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("if_same", [if_same]))(thm_tac (new_rewrite [] [])))))) ((((fun arg_tac -> arg_tac (Arg_theorem (ARITH_RULE `n < m ==> (m = n <=> F)`)))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
382    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("subn_gt0", [subn_gt0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
383 ];;
384
385 (* Lemma set_set_nth *)
386 let set_set_nth = Sections.section_proof ["s";"n1";"y1";"n2";"y2"]
387 `set_nth x0 (set_nth x0 s n1 y1) n2 y2 = 
388         if n1 = n2 then set_nth x0 s n2 y2 else set_nth x0 (set_nth x0 s n2 y2) n1 y1`
389 [
390    ((THENL) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`n1 = n2:num`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (move ["ne_n12"])]);
391    ((THENL_FIRST) ((((fun arg_tac -> arg_tac (Arg_theorem (REWRITE_RULE[IMP_IMP] eq_from_nth))) (disch_tac [])) THEN (DISCH_THEN apply_tac)) THEN (split_tac)) (((repeat_tactic 1 9 (((use_arg_then2 ("size_set_nth", [size_set_nth]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("maxnA", [maxnA]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("maxnn", [maxnn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
392    ((BETA_TAC THEN (move ["i"]) THEN (move ["_"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("nth_set_nth", [nth_set_nth]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (done_tac));
393    ((THENL_FIRST) ((((fun arg_tac -> arg_tac (Arg_theorem (REWRITE_RULE[IMP_IMP] eq_from_nth))) (disch_tac [])) THEN (DISCH_THEN apply_tac)) THEN (split_tac)) (((((use_arg_then2 ("ne_n12", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("size_set_nth", [size_set_nth]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("maxnCA", [maxnCA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
394    ((BETA_TAC THEN (move ["i"]) THEN (move ["_"])) THEN (((simp_tac THEN TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth_set_nth", [nth_set_nth]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN ((((use_arg_then2 ("ne_n12", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
395    (((THENL) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`i = n2:num`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [(((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))); (move ["ne_i2"])]) THEN (simp_tac));
396    (((((use_arg_then2 ("nth_set_nth", [nth_set_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ne_n12", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("nth_set_nth", [nth_set_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
397    (((((use_arg_then2 ("ne_i2", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth_set_nth", [nth_set_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ne_i2", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
398 ];;
399
400 (* Section SeqFind *)
401 Sections.begin_section "SeqFind";;
402 (Sections.add_section_var (mk_var ("a", (`:A -> bool`))));;
403 let find = define `!a (x:A) s'. find a [] = 0 /\ 
404         find a (x :: s') = if a x then 0 else SUC(find a s')`;;
405 let filter = define `!a (x:A) s'. filter a [] = [] /\
406         filter a (x :: s') = if a x then x :: filter a s' else filter a s'`;;
407 let count = define `!a (x:A) s'. count a [] = 0 /\
408         count a (x :: s') = (if a x then 1 else 0) + count a s'`;;
409 let has = define `!a (x:A) s'. has a [] = F /\
410         has a (x :: s') = (a x \/ has a s')`;;
411 let all = define `!a (x:A) s'. all a [] = T /\
412         all a (x :: s') = (a x /\ all a s')`;;
413
414 (* Lemma find_nil *)
415 let find_nil = Sections.section_proof []
416 `find a [] = 0`
417 [
418    ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
419 ];;
420
421 (* Lemma find_cons *)
422 let find_cons = Sections.section_proof ["x";"t"]
423 `find a (x::t) = if a x then 0 else SUC (find a t)`
424 [
425    ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
426 ];;
427
428 (* Lemma filter_nil *)
429 let filter_nil = Sections.section_proof []
430 `filter a [] = []`
431 [
432    ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
433 ];;
434
435 (* Lemma filter_cons *)
436 let filter_cons = Sections.section_proof ["x";"t"]
437 `filter a (x::t) = if a x then x :: filter a t else filter a t`
438 [
439    ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
440 ];;
441
442 (* Lemma count_nil *)
443 let count_nil = Sections.section_proof []
444 `count a [] = 0`
445 [
446    ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
447 ];;
448
449 (* Lemma count_cons *)
450 let count_cons = Sections.section_proof ["x";"t"]
451 `count a (x::t) = (if a x then 1 else 0) + count a t`
452 [
453    ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
454 ];;
455
456 (* Lemma has_nil *)
457 let has_nil = Sections.section_proof []
458 `has a [] = F`
459 [
460    ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
461 ];;
462
463 (* Lemma has_cons *)
464 let has_cons = Sections.section_proof ["x";"t"]
465 `has a (x::t) <=> a x \/ has a t`
466 [
467    ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
468 ];;
469
470 (* Lemma all_nil *)
471 let all_nil = Sections.section_proof []
472 `all a [] = T`
473 [
474    ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
475 ];;
476
477 (* Lemma all_cons *)
478 let all_cons = Sections.section_proof ["x";"t"]
479 `all a (x::t) <=> a x /\ all a t`
480 [
481    ((((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
482 ];;
483
484 (* Lemma count_filter *)
485 let count_filter = Sections.section_proof ["s"]
486 `count a s = sizel (filter a s)`
487 [
488    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]))]) THEN (((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))));
489    (((THENL) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (move ["nax"])]) THEN ((((use_arg_then2 ("add1n", [add1n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
490    (((((use_arg_then2 ("nax", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
491 ];;
492
493 (* Lemma has_count *)
494 let has_count = Sections.section_proof ["s"]
495 `has a s = (0 < count a s)`
496 [
497    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]))]) THEN (((((use_arg_then2 ("has", [has]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltnn", [ltnn]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> arg_tac (Arg_term (`a x`))) (disch_tac [])) THEN case THEN (simp_tac)) THEN (arith_tac) THEN (done_tac));
498 ];;
499
500 (* Lemma count_size *)
501 let count_size = Sections.section_proof ["s"]
502 `count a s <= sizel s`
503 [
504    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]))]) THEN ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("leqnn", [leqnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
505    ((((fun arg_tac -> arg_tac (Arg_term (`a x`))) (disch_tac [])) THEN case THEN (simp_tac)) THEN ((((fun arg_tac ->(use_arg_then2 ("add1n", [add1n]))(fun tmp_arg1 -> (use_arg_then2 ("add0n", [add0n]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("leqW", [leqW])) (disch_tac [])) THEN (clear_assumption "leqW") THEN (exact_tac)));
506 ];;
507
508 (* Lemma all_count *)
509 let all_count = Sections.section_proof ["s"]
510 `all a s = (count a s = sizel s)`
511 [
512    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]))]) THEN ((((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
513    ((THENL_FIRST) ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"]) THEN (move ["_"])) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) ((arith_tac) THEN (done_tac)));
514    (((((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqn_leq", [eqn_leq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_size", [count_size]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
515 ];;
516
517 (* Lemma filter_all *)
518 let filter_all = Sections.section_proof ["s"]
519 `all a (filter a s)`
520 [
521    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
522    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
523 ];;
524
525 (* Lemma all_filterP *)
526 let all_filterP = Sections.section_proof ["s"]
527 `(filter a s = s) <=> (all a s)`
528 [
529    ((THENL_FIRST) ((THENL) (EQ_TAC) [(((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] []))))); ALL_TAC]) ((((use_arg_then2 ("filter_all", [filter_all]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
530    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN ALL_TAC THEN (case THEN ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (move ["Hs"]))) THEN (simp_tac)));
531    ((((fun arg_tac -> (use_arg_then2 ("IHs", [])) (fun fst_arg -> (use_arg_then2 ("Hs", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
532 ];;
533
534 (* Lemma filter_id *)
535 let filter_id = Sections.section_proof ["s"]
536 `filter a (filter a s) = filter a s`
537 [
538    (((((use_arg_then2 ("all_filterP", [all_filterP]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("filter_all", [filter_all]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
539 ];;
540
541 (* Lemma has_find *)
542 let has_find = Sections.section_proof ["s"]
543 `has a s <=> (find a s < sizel s)`
544 [
545    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((simp_tac THEN TRY done_tac))));
546    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
547 ];;
548
549 (* Lemma find_size *)
550 let find_size = Sections.section_proof ["s"]
551 `find a s <= sizel s`
552 [
553    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("leqnn", [leqnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
554    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("leq0n", [leq0n]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
555 ];;
556
557 (* Lemma find_cat *)
558 let find_cat = Sections.section_proof ["s1";"s2"]
559 `find a (s1 ++ s2) = if has a s1 then find a s1 else sizel s1 + find a s2`
560 [
561    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
562    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"]));
563    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("fun_if", [fun_if]))(thm_tac (new_rewrite [] [(`SUC _1`)])))) THEN (((use_arg_then2 ("addSn", [addSn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
564 ];;
565
566 (* Lemma has_nil *)
567 let has_nil = Sections.section_proof []
568 `has a [] = F`
569 [
570    ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
571 ];;
572
573 (* Lemma has_seq1 *)
574 let has_seq1 = Sections.section_proof ["x"]
575 `has a [x] = a x`
576 [
577    ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
578 ];;
579
580 (* Lemma has_seqb *)
581 let has_seqb = Sections.section_proof ["b";"x"]
582 `has a (nseq (if b then 1 else 0) x) <=> (b /\ a x)`
583 [
584    ((((use_arg_then2 ("b", [])) (disch_tac [])) THEN (clear_assumption "b") THEN case THEN (simp_tac)) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ONE", [ONE]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("has_nil", [has_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("has_seq1", [has_seq1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
585 ];;
586
587 (* Lemma all_nil *)
588 let all_nil = Sections.section_proof []
589 `all a [] = T`
590 [
591    ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
592 ];;
593
594 (* Lemma all_seq1 *)
595 let all_seq1 = Sections.section_proof ["x"]
596 `all a [x] = a x`
597 [
598    ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
599 ];;
600
601 (* Lemma nth_find *)
602 let nth_find = Sections.section_proof ["s"]
603 `has a s ==> a (nth x0 s (find a s))`
604 [
605    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
606    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
607 ];;
608
609 (* Lemma before_find *)
610 let before_find = Sections.section_proof ["s";"i"]
611 `i < find a s ==> (a (nth x0 s i) <=> F)`
612 [
613    (((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
614    ((THENL_FIRST) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["ax"])) ((((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
615    (((THENL) elim [ALL_TAC; ((move ["i"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ax", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltSS", [ltSS]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
616    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac));
617 ];;
618
619 (* Lemma filter_cat *)
620 let filter_cat = Sections.section_proof ["s1";"s2"]
621 `filter a (s1 ++ s2) = filter a s1 ++ filter a s2`
622 [
623    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["Ihs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
624    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"])) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
625 ];;
626
627 (* Lemma filter_rcons *)
628 let filter_rcons = Sections.section_proof ["s";"x"]
629 `filter a (rcons s x) = if a x then rcons (filter a s) x else filter a s`
630 [
631    (((repeat_tactic 1 9 (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("filter_cat", [filter_cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
632    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"])) THEN (((use_arg_then2 ("cats0", [cats0]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
633 ];;
634
635 (* Lemma count_cat *)
636 let count_cat = Sections.section_proof ["s1";"s2"]
637 `count a (s1 ++ s2) = count a s1 + count a s2`
638 [
639    (((repeat_tactic 1 9 (((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("filter_cat", [filter_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
640 ];;
641
642 (* Lemma has_cat *)
643 let has_cat = Sections.section_proof ["s1";"s2"]
644 `has a (s1 ++ s2) = (has a s1 \/ has a s2)`
645 [
646    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
647    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbA", [orbA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
648 ];;
649
650 (* Lemma has_rcons *)
651 let has_rcons = Sections.section_proof ["s";"x"]
652 `has a (rcons s x) = (a x \/ has a s)`
653 [
654    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_cat", [has_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_seq1", [has_seq1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbC", [orbC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
655 ];;
656
657 (* Lemma all_cat *)
658 let all_cat = Sections.section_proof ["s1";"s2"]
659 `all a (s1 ++ s2) = (all a s1 /\ all a s2)`
660 [
661    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
662    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbA", [andbA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
663 ];;
664
665 (* Lemma all_rcons *)
666 let all_rcons = Sections.section_proof ["s";"x"]
667 `all a (rcons s x) = (a x /\ all a s)`
668 [
669    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("all_cat", [all_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("all_seq1", [all_seq1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
670 ];;
671
672 (* Finalization of the section SeqFind *)
673 let find_nil = Sections.finalize_theorem find_nil;;
674 let find_cons = Sections.finalize_theorem find_cons;;
675 let filter_nil = Sections.finalize_theorem filter_nil;;
676 let filter_cons = Sections.finalize_theorem filter_cons;;
677 let count_nil = Sections.finalize_theorem count_nil;;
678 let count_cons = Sections.finalize_theorem count_cons;;
679 let has_nil = Sections.finalize_theorem has_nil;;
680 let has_cons = Sections.finalize_theorem has_cons;;
681 let all_nil = Sections.finalize_theorem all_nil;;
682 let all_cons = Sections.finalize_theorem all_cons;;
683 let count_filter = Sections.finalize_theorem count_filter;;
684 let has_count = Sections.finalize_theorem has_count;;
685 let count_size = Sections.finalize_theorem count_size;;
686 let all_count = Sections.finalize_theorem all_count;;
687 let filter_all = Sections.finalize_theorem filter_all;;
688 let all_filterP = Sections.finalize_theorem all_filterP;;
689 let filter_id = Sections.finalize_theorem filter_id;;
690 let has_find = Sections.finalize_theorem has_find;;
691 let find_size = Sections.finalize_theorem find_size;;
692 let find_cat = Sections.finalize_theorem find_cat;;
693 let has_nil = Sections.finalize_theorem has_nil;;
694 let has_seq1 = Sections.finalize_theorem has_seq1;;
695 let has_seqb = Sections.finalize_theorem has_seqb;;
696 let all_nil = Sections.finalize_theorem all_nil;;
697 let all_seq1 = Sections.finalize_theorem all_seq1;;
698 let nth_find = Sections.finalize_theorem nth_find;;
699 let before_find = Sections.finalize_theorem before_find;;
700 let filter_cat = Sections.finalize_theorem filter_cat;;
701 let filter_rcons = Sections.finalize_theorem filter_rcons;;
702 let count_cat = Sections.finalize_theorem count_cat;;
703 let has_cat = Sections.finalize_theorem has_cat;;
704 let has_rcons = Sections.finalize_theorem has_rcons;;
705 let all_cat = Sections.finalize_theorem all_cat;;
706 let all_rcons = Sections.finalize_theorem all_rcons;;
707 Sections.end_section "SeqFind";;
708 let pred1 = new_definition `pred1 (a:A) = (\x. x = a)`;;
709 let predD1 = new_definition `predD1 a x = predD a (pred1 x)`;;
710
711 (* Lemma eq_find *)
712 let eq_find = Sections.section_proof ["a1";"a2"]
713 `(!x:A. a1 x = a2 x) ==> (!s. find a1 s = find a2 s)`
714 [
715    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("EQ_EXT", [EQ_EXT])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
716 ];;
717
718 (* Lemma eq_filter *)
719 let eq_filter = Sections.section_proof ["a1";"a2"]
720 `(!x:A. a1 x = a2 x) ==> (!s. filter a1 s = filter a2 s)`
721 [
722    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("EQ_EXT", [EQ_EXT])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
723 ];;
724
725 (* Lemma eq_count *)
726 let eq_count = Sections.section_proof ["a1";"a2"]
727 `(!x:A. a1 x = a2 x) ==> (!s. count a1 s = count a2 s)`
728 [
729    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("EQ_EXT", [EQ_EXT])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
730 ];;
731
732 (* Lemma eq_has *)
733 let eq_has = Sections.section_proof ["a1";"a2"]
734 `(!x. a1 x = a2 x) ==> (!s. has a1 s = has a2 s)`
735 [
736    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("EQ_EXT", [EQ_EXT])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
737 ];;
738
739 (* Lemma eq_all *)
740 let eq_all = Sections.section_proof ["a1";"a2"]
741 `(!x. a1 x = a2 x) ==> (!s. all a1 s = all a2 s)`
742 [
743    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("EQ_EXT", [EQ_EXT])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
744 ];;
745
746 (* Lemma filter_pred0 *)
747 let filter_pred0 = Sections.section_proof ["s"]
748 `filter pred0 s = []`
749 [
750    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("pred0", [pred0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
751    (((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("pred0", [pred0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
752 ];;
753
754 (* Lemma filter_predT *)
755 let filter_predT = Sections.section_proof ["s"]
756 `filter predT s = s`
757 [
758    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("predT", [predT]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
759    (((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [2] []))))) THEN (((use_arg_then2 ("predT", [predT]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
760 ];;
761
762 (* Lemma filter_predI *)
763 let filter_predI = Sections.section_proof ["a1";"a2";"s"]
764 `filter (predI a1 a2) s = filter a1 (filter a2 s)`
765 [
766    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("predI", [predI]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
767    ((THENL_LAST) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a2:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"])) (((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("predI", [predI]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
768    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a1:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["a1x"])) THEN (((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))));
769    (((((use_arg_then2 ("a1x", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("IHs", []))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("predI", [predI]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
770    (((((use_arg_then2 ("a1x", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("IHs", []))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("predI", [predI]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
771 ];;
772
773 (* Lemma count_pred0 *)
774 let count_pred0 = Sections.section_proof ["s"]
775 `count pred0 s = 0`
776 [
777    (((((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("filter_pred0", [filter_pred0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
778 ];;
779
780 (* Lemma count_predT *)
781 let count_predT = Sections.section_proof ["s"]
782 `count predT s = sizel s`
783 [
784    (((((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("filter_predT", [filter_predT]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
785 ];;
786
787 (* Lemma count_predUI *)
788 let count_predUI = Sections.section_proof ["a1";"a2";"s"]
789 `count (predU a1 a2) s + count (predI a1 a2) s = count a1 s + count a2 (s:(A)list)`
790 [
791    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("predI", [predI]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("predU", [predU]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
792    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a1:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["a1x"])) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a2:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["a2x"])) THEN ((((use_arg_then2 ("predI", [predI]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("predU", [predU]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("IHs", [])) (disch_tac [])) THEN (clear_assumption "IHs") THEN BETA_TAC) THEN (arith_tac));
793 ];;
794
795 (* Lemma count_predC *)
796 let count_predC = Sections.section_proof ["a";"s"]
797 `count a s + count (predC a) s = sizel (s:(A)list)`
798 [
799    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
800    ((((use_arg_then2 ("addnCA", [addnCA]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addnA", [addnA]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))));
801    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["ax"])) THEN (arith_tac));
802 ];;
803
804 (* Lemma has_pred0 *)
805 let has_pred0 = Sections.section_proof ["s"]
806 `has pred0 s = F`
807 [
808    (((((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_pred0", [count_pred0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
809 ];;
810
811 (* Lemma has_predT *)
812 let has_predT = Sections.section_proof ["s"]
813 `has predT s = (0 < sizel s)`
814 [
815    (((((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_predT", [count_predT]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
816 ];;
817
818 (* Lemma has_predC *)
819 let has_predC = Sections.section_proof ["a";"s"]
820 `has (predC a) s = ~ all a s`
821 [
822    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))));
823    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("negb_and", [negb_and]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
824 ];;
825
826 (* Lemma has_predU *)
827 let has_predU = Sections.section_proof ["a1";"a2";"s"]
828 `has (predU a1 a2) s <=> (has a1 s \/ has a2 s)`
829 [
830    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
831    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predU", [predU]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (repeat_tactic 1 9 (((use_arg_then2 ("orbA", [orbA]))(gsym_then (thm_tac (new_rewrite [] [])))))));
832    ((((use_arg_then2 ("orbCA", [orbCA]))(thm_tac (new_rewrite [] [(`has a1 s \/ _ \/ _1`)])))) THEN (done_tac));
833 ];;
834
835 (* Lemma all_pred0 *)
836 let all_pred0 = Sections.section_proof ["s"]
837 `all pred0 s = (sizel s = 0)`
838 [
839    (((((use_arg_then2 ("all_count", [all_count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_pred0", [count_pred0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`0 = _`)]))))) THEN (done_tac));
840 ];;
841
842 (* Lemma all_predT *)
843 let all_predT = Sections.section_proof ["s"]
844 `all predT s`
845 [
846    (((((use_arg_then2 ("all_count", [all_count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_predT", [count_predT]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
847 ];;
848
849 (* Lemma all_predC *)
850 let all_predC = Sections.section_proof ["a";"s"]
851 `all (predC a) s = ~ has a s`
852 [
853    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))));
854    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negb_or", [negb_or]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
855 ];;
856
857 (* Lemma can_inj *)
858 let can_inj = Sections.section_proof ["f";"g"]
859 `(!x. g (f x) = x) ==> (!x y. f x = f y ==> x = y)`
860 [
861    (BETA_TAC THEN (move ["h"]) THEN (move ["x"]) THEN (move ["y"]) THEN (move ["f_eq"]));
862    (((((fun arg_tac -> (use_arg_then2 ("h", [])) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("h", [])) (fun fst_arg -> (use_arg_then2 ("y", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("f_eq", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
863 ];;
864
865 (* Lemma all_predI *)
866 let all_predI = Sections.section_proof ["a1";"a2";"s"]
867 `all (predI a1 a2) s <=> all a1 s /\ all a2 s`
868 [
869    ((((fun arg_tac -> (use_arg_then2 ("can_inj", [can_inj])) (fun fst_arg -> (use_arg_then2 ("negbK", [negbK])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (DISCH_THEN apply_tac)) THEN ((((use_arg_then2 ("negb_and", [negb_and]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("has_predC", [has_predC]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("has_predU", [has_predU]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("predU", [predU]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predI", [predI]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (((use_arg_then2 ("negb_and", [negb_and]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
870 ];;
871 let drop = define `!n x s. dropl (SUC n) (x :: s) = dropl n s /\ 
872         dropl n [] = [] /\ dropl 0 s = s`;;
873
874 (* Lemma eq_ext *)
875 let eq_ext = Sections.section_proof ["f";"g"]
876 `(!x. f x = g x) <=> f = g`
877 [
878    ((THENL_FIRST) ((split_tac) THEN (move ["h"])) ((MATCH_MP_TAC EQ_EXT) THEN (done_tac)));
879    ((((use_arg_then2 ("h", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
880 ];;
881
882 (* Lemma drop_nil *)
883 let drop_nil = Sections.section_proof ["n"]
884 `dropl n [] = []`
885 [
886    ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
887 ];;
888
889 (* Lemma drop0 *)
890 let drop0 = Sections.section_proof []
891 `dropl 0 = I`
892 [
893    (((((use_arg_then2 ("eq_ext", [eq_ext]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("I_THM", [I_THM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
894 ];;
895
896 (* Lemma drop_cons *)
897 let drop_cons = Sections.section_proof ["n";"x";"s"]
898 `dropl (SUC n) (x :: s) = dropl n s`
899 [
900    ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
901 ];;
902
903 (* Lemma drop_behead *)
904 let drop_behead = Sections.section_proof []
905 `dropl n0 = iter n0 behead`
906 [
907    ((THENL_FIRST) (((THENL) (((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((((use_arg_then2 ("eq_ext", [eq_ext]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) ((((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)));
908    (((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("iterSr", [iterSr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHn", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
909 ];;
910
911 (* Lemma drop0 *)
912 let drop0 = Sections.section_proof ["s"]
913 `dropl 0 s = s`
914 [
915    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
916 ];;
917
918 (* Lemma drop1 *)
919 let drop1 = Sections.section_proof ["s"]
920 `dropl 1 s = behead s`
921 [
922    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("ONE", [ONE]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("drop0", [drop0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
923 ];;
924
925 (* Lemma drop_oversize *)
926 let drop_oversize = Sections.section_proof ["n";"s"]
927 `sizel s <= n ==> dropl n s = []`
928 [
929    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
930    (((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHn", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac));
931 ];;
932
933 (* Lemma drop_size *)
934 let drop_size = Sections.section_proof ["s"]
935 `dropl (sizel s) s = []`
936 [
937    (((((use_arg_then2 ("drop_oversize", [drop_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
938 ];;
939
940 (* Lemma size_drop *)
941 let size_drop = Sections.section_proof ["s"]
942 `sizel (dropl n0 s) = sizel s - n0`
943 [
944    (((THENL) (((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("subn0", [subn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sub0n", [sub0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
945    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
946 ];;
947
948 (* Lemma drop_cat *)
949 let drop_cat = Sections.section_proof ["s1";"s2"]
950 `dropl n0 (s1 ++ s2) =
951     if n0 < sizel s1 then dropl n0 s1 ++ s2 else dropl (n0 - sizel s1) s2`
952 [
953    (((THENL) (((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sub0n", [sub0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("if_same", [if_same]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("subn0", [subn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
954    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
955 ];;
956
957 (* Lemma drop_size_cat *)
958 let drop_size_cat = Sections.section_proof ["n";"s1";"s2"]
959 `sizel s1 = n ==> dropl n (s1 ++ s2) = s2`
960 [
961    ((BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("drop0", [drop0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
962    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop_cons", [drop_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
963 ];;
964
965 (* Lemma nconsK *)
966 let nconsK = Sections.section_proof ["n";"x";"s"]
967 `dropl n (ncons n x s) = s`
968 [
969    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (done_tac));
970 ];;
971 let take = define `!x s n. take (SUC n) (x :: s) = x :: take n s /\
972         take 0 s = [] /\ take n [] = []`;;
973
974 (* Lemma take0 *)
975 let take0 = Sections.section_proof ["s"]
976 `take 0 s = []`
977 [
978    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
979 ];;
980
981 (* Lemma take_oversize *)
982 let take_oversize = Sections.section_proof ["n";"s"]
983 `sizel s <= n ==> take n s = s`
984 [
985    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
986    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
987    ((((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN (move ["Hsn"])) THEN (((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
988 ];;
989
990 (* Lemma take_size *)
991 let take_size = Sections.section_proof ["s"]
992 `take (sizel s) s = s`
993 [
994    (((((use_arg_then2 ("take_oversize", [take_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
995 ];;
996
997 (* Lemma take_cons *)
998 let take_cons = Sections.section_proof ["x";"s"]
999 `take (SUC n0) (x :: s) = x :: (take n0 s)`
1000 [
1001    ((((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1002 ];;
1003
1004 (* Lemma drop_rcons *)
1005 let drop_rcons = Sections.section_proof ["s"]
1006 `n0 <= sizel s ==>
1007   !x. dropl n0 (rcons s x) = rcons (dropl n0 s) x`
1008 [
1009    (((THENL) (((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1010    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop_cons", [drop_cons]))(thm_tac (new_rewrite [] []))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
1011 ];;
1012
1013 (* Lemma congr1 *)
1014 let congr1 = Sections.section_proof ["f";"x";"y"]
1015 `x = y ==> f x = f y`
1016 [
1017    ((BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1018 ];;
1019
1020 (* Lemma cat_take_drop *)
1021 let cat_take_drop = Sections.section_proof ["s"]
1022 `take n0 s ++ dropl n0 s = s`
1023 [
1024    (((THENL) (((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1025    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1026 ];;
1027
1028 (* Lemma size_takel *)
1029 let size_takel = Sections.section_proof ["s"]
1030 `n0 <= sizel s ==> sizel (take n0 s) = n0`
1031 [
1032    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("subnKC", [subnKC])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN ((((fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [2] []))))) THEN (((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] []))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("addIn", [addIn])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
1033 ];;
1034
1035 (* Lemma size_take *)
1036 let size_take = Sections.section_proof ["s"]
1037 `sizel (take n0 s) = if n0 < sizel s then n0 else sizel s`
1038 [
1039    (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("leqP", [leqP])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel (s:(A)list)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC THEN ((THENL) case [(move ["le_sn"]); (move ["lt_ns"])]));
1040    (((((use_arg_then2 ("take_oversize", [take_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("le_sn", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
1041    (((((use_arg_then2 ("lt_ns", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("size_takel", [size_takel]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltnW", [ltnW]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1042 ];;
1043
1044 (* Lemma take_cat *)
1045 let take_cat = Sections.section_proof ["s1";"s2"]
1046 `take n0 (s1 ++ s2) =
1047    if n0 < sizel s1 then take n0 s1 else s1 ++ take (n0 - sizel s1) s2`
1048 [
1049    (((THENL) (((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("subn0", [subn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1050    (((((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("fun_if", [fun_if]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1051 ];;
1052
1053 (* Lemma take_size_cat *)
1054 let take_size_cat = Sections.section_proof ["n";"s1";"s2"]
1055 `sizel s1 = n ==> take n (s1 ++ s2) = s1`
1056 [
1057    ((BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
1058    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1059 ];;
1060
1061 (* Lemma takel_cat *)
1062 let takel_cat = Sections.section_proof ["s1"]
1063 `n0 <= sizel (s1:(A)list) ==> (!s2. take n0 (s1 ++ s2) = take n0 s1)`
1064 [
1065    (BETA_TAC THEN (move ["Hn0"]) THEN (move ["s2"]));
1066    ((((use_arg_then2 ("take_cat", [take_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn_neqAle", [ltn_neqAle]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hn0", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbT", [andbT]))(thm_tac (new_rewrite [] [])))));
1067    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`n0 = sizel (s1:(A)list)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["eq"]));
1068    (((((use_arg_then2 ("subnn", [subnn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take0", [take0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats0", [cats0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take_size", [take_size]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1069 ];;
1070
1071 (* Lemma nth_drop *)
1072 let nth_drop = Sections.section_proof ["s";"i"]
1073 `nth x0 (dropl n0 s) i = nth x0 s (n0 + i)`
1074 [
1075    (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltnP", [ltnP])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel (s:(A)list)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC THEN ((THENL) case [(move ["lt_n0_s"]); (move ["le_s_n0"])]));
1076    ((((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(gsym_then (thm_tac (new_rewrite [2] [(`s`)]))))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lt_n0_s", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("addKn", [addKn]))(thm_tac (new_rewrite [] [])))));
1077    (((((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_addr", [leq_addr]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1078    ((repeat_tactic 1 9 (((use_arg_then2 ("nth_default", [nth_default]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)));
1079    ((((use_arg_then2 ("le_s_n0", [])) (disch_tac [])) THEN (clear_assumption "le_s_n0") THEN BETA_TAC) THEN (((((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("leqE", [leqE]))(thm_tac (new_rewrite [] [])))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("sub0n", [sub0n]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1080    ((((fun arg_tac -> (use_arg_then2 ("leq_trans", [leq_trans])) (fun fst_arg -> (use_arg_then2 ("le_s_n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("leq_addr", [leq_addr]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1081 ];;
1082
1083 (* Lemma nth_take *)
1084 let nth_take = Sections.section_proof ["i"]
1085 `i < n0 ==> !s. nth x0 (take n0 s) i = nth x0 s i`
1086 [
1087    ((BETA_TAC THEN (move ["lt_i_n0"]) THEN (move ["s"])) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`n0 < sizel (s:(A)list)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (move ["lt_n0_s"])));
1088    (((((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(gsym_then (thm_tac (new_rewrite [2] [(`s`)]))))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lt_n0_s", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("lt_i_n0", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1089    (((((use_arg_then2 ("cats0", [cats0]))(gsym_then (thm_tac (new_rewrite [1] [(`s`)]))))) THEN (((use_arg_then2 ("take_cat", [take_cat]))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("lt_n0_s", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cats0", [cats0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1090 ];;
1091
1092 (* Lemma drop_nth *)
1093 let drop_nth = Sections.section_proof ["n";"s"]
1094 `n < sizel s ==> dropl n s = nth x0 s n :: dropl (SUC n) s`
1095 [
1096    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1097    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac));
1098 ];;
1099
1100 (* Lemma take_nth *)
1101 let take_nth = Sections.section_proof ["n";"s"]
1102 `n < sizel s ==> take (SUC n) s = rcons (take n s) (nth x0 s n)`
1103 [
1104    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1105    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1106 ];;
1107 let rot = new_definition `rot n s = dropl n s ++ take n s`;;
1108
1109 (* Lemma rot0 *)
1110 let rot0 = Sections.section_proof ["s"]
1111 `rot 0 s = s`
1112 [
1113    (((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop0", [drop0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take0", [take0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats0", [cats0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1114 ];;
1115
1116 (* Lemma size_rot *)
1117 let size_rot = Sections.section_proof ["s"]
1118 `sizel (rot n0 s) = sizel s`
1119 [
1120    (((((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(gsym_then (thm_tac (new_rewrite [2] [(`s`)]))))) THEN (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("addnC", [addnC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1121 ];;
1122
1123 (* Lemma rot_oversize *)
1124 let rot_oversize = Sections.section_proof ["n";"s"]
1125 `sizel s <= n ==> rot n s = s`
1126 [
1127    ((BETA_TAC THEN (move ["le_s_n"])) THEN ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take_oversize", [take_oversize]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("drop_oversize", [drop_oversize]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1128 ];;
1129
1130 (* Lemma rot_size *)
1131 let rot_size = Sections.section_proof ["s"]
1132 `rot (sizel s) s = s`
1133 [
1134    ((((use_arg_then2 ("rot_oversize", [rot_oversize])) (disch_tac [])) THEN (clear_assumption "rot_oversize") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1135 ];;
1136
1137 (* Lemma has_rot *)
1138 let has_rot = Sections.section_proof ["s";"a"]
1139 `has a (rot n0 s) = has a s`
1140 [
1141    (((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_cat", [has_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbC", [orbC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_cat", [has_cat]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1142 ];;
1143
1144 (* Lemma rot_size_cat *)
1145 let rot_size_cat = Sections.section_proof ["s1";"s2"]
1146 `rot (sizel s1) (s1 ++ s2) = s2 ++ s1`
1147 [
1148    (((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take_size_cat", [take_size_cat]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("drop_size_cat", [drop_size_cat]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
1149 ];;
1150 let rotr = new_definition `rotr n s = rot (sizel s - n) s`;;
1151
1152 (* Lemma rotK *)
1153 let rotK = Sections.section_proof ["s"]
1154 `rotr n0 (rot n0 s) = s`
1155 [
1156    ((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [(`rot n0 _`)])))));
1157    (((((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1158 ];;
1159
1160 (* Lemma rot_inj *)
1161 let rot_inj = Sections.section_proof ["s1";"s2"]
1162 `rot n0 (s1:(A)list) = rot n0 s2 ==> s1 = s2`
1163 [
1164    ((((fun arg_tac -> (fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("can_inj", [can_inj])) (fun fst_arg -> (use_arg_then2 ("rotK", [rotK])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s1", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s2", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (done_tac));
1165 ];;
1166
1167 (* Lemma rot1_cons *)
1168 let rot1_cons = Sections.section_proof ["x";"s"]
1169 `rot 1 (x :: s) = rcons s x`
1170 [
1171    (((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ONE", [ONE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop_cons", [drop_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take0", [take0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop0", [drop0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
1172 ];;
1173
1174 (* Finalization of the section Sequences *)
1175 let size0nil = Sections.finalize_theorem size0nil;;
1176 let nilP = Sections.finalize_theorem nilP;;
1177 let size_behead = Sections.finalize_theorem size_behead;;
1178 let size_nil = Sections.finalize_theorem size_nil;;
1179 let size_cons = Sections.finalize_theorem size_cons;;
1180 let size_ncons = Sections.finalize_theorem size_ncons;;
1181 let size_nseq = Sections.finalize_theorem size_nseq;;
1182 let cat0s = Sections.finalize_theorem cat0s;;
1183 let cat1s = Sections.finalize_theorem cat1s;;
1184 let cat_cons = Sections.finalize_theorem cat_cons;;
1185 let cat_nseq = Sections.finalize_theorem cat_nseq;;
1186 let cats0 = Sections.finalize_theorem cats0;;
1187 let catA = Sections.finalize_theorem catA;;
1188 let size_cat = Sections.finalize_theorem size_cat;;
1189 let rcons_cons = Sections.finalize_theorem rcons_cons;;
1190 let cats1 = Sections.finalize_theorem cats1;;
1191 let lastI = Sections.finalize_theorem lastI;;
1192 let last_cons = Sections.finalize_theorem last_cons;;
1193 let size_rcons = Sections.finalize_theorem size_rcons;;
1194 let size_belast = Sections.finalize_theorem size_belast;;
1195 let last_cat = Sections.finalize_theorem last_cat;;
1196 let last_rcons = Sections.finalize_theorem last_rcons;;
1197 let belast_cat = Sections.finalize_theorem belast_cat;;
1198 let belast_rcons = Sections.finalize_theorem belast_rcons;;
1199 let cat_rcons = Sections.finalize_theorem cat_rcons;;
1200 let rcons_cat = Sections.finalize_theorem rcons_cat;;
1201 let last_ind = Sections.finalize_theorem last_ind;;
1202 let nth0 = Sections.finalize_theorem nth0;;
1203 let nth_default = Sections.finalize_theorem nth_default;;
1204 let nth_nil = Sections.finalize_theorem nth_nil;;
1205 let last_nth = Sections.finalize_theorem last_nth;;
1206 let nth_last = Sections.finalize_theorem nth_last;;
1207 let nth_behead = Sections.finalize_theorem nth_behead;;
1208 let nth_cat = Sections.finalize_theorem nth_cat;;
1209 let nth_rcons = Sections.finalize_theorem nth_rcons;;
1210 let nth_ncons = Sections.finalize_theorem nth_ncons;;
1211 let nth_nseq = Sections.finalize_theorem nth_nseq;;
1212 let eq_from_nth = Sections.finalize_theorem eq_from_nth;;
1213 let size_set_nth = Sections.finalize_theorem size_set_nth;;
1214 let set_nth_nil = Sections.finalize_theorem set_nth_nil;;
1215 let ltS0 = Sections.finalize_theorem ltS0;;
1216 let eqS0 = Sections.finalize_theorem eqS0;;
1217 let eq0S = Sections.finalize_theorem eq0S;;
1218 let gtS0 = Sections.finalize_theorem gtS0;;
1219 let ltSS = Sections.finalize_theorem ltSS;;
1220 let nth_set_nth = Sections.finalize_theorem nth_set_nth;;
1221 let set_set_nth = Sections.finalize_theorem set_set_nth;;
1222 let find_nil = Sections.finalize_theorem find_nil;;
1223 let find_cons = Sections.finalize_theorem find_cons;;
1224 let filter_nil = Sections.finalize_theorem filter_nil;;
1225 let filter_cons = Sections.finalize_theorem filter_cons;;
1226 let count_nil = Sections.finalize_theorem count_nil;;
1227 let count_cons = Sections.finalize_theorem count_cons;;
1228 let has_nil = Sections.finalize_theorem has_nil;;
1229 let has_cons = Sections.finalize_theorem has_cons;;
1230 let all_nil = Sections.finalize_theorem all_nil;;
1231 let all_cons = Sections.finalize_theorem all_cons;;
1232 let count_filter = Sections.finalize_theorem count_filter;;
1233 let has_count = Sections.finalize_theorem has_count;;
1234 let count_size = Sections.finalize_theorem count_size;;
1235 let all_count = Sections.finalize_theorem all_count;;
1236 let filter_all = Sections.finalize_theorem filter_all;;
1237 let all_filterP = Sections.finalize_theorem all_filterP;;
1238 let filter_id = Sections.finalize_theorem filter_id;;
1239 let has_find = Sections.finalize_theorem has_find;;
1240 let find_size = Sections.finalize_theorem find_size;;
1241 let find_cat = Sections.finalize_theorem find_cat;;
1242 let has_nil = Sections.finalize_theorem has_nil;;
1243 let has_seq1 = Sections.finalize_theorem has_seq1;;
1244 let has_seqb = Sections.finalize_theorem has_seqb;;
1245 let all_nil = Sections.finalize_theorem all_nil;;
1246 let all_seq1 = Sections.finalize_theorem all_seq1;;
1247 let nth_find = Sections.finalize_theorem nth_find;;
1248 let before_find = Sections.finalize_theorem before_find;;
1249 let filter_cat = Sections.finalize_theorem filter_cat;;
1250 let filter_rcons = Sections.finalize_theorem filter_rcons;;
1251 let count_cat = Sections.finalize_theorem count_cat;;
1252 let has_cat = Sections.finalize_theorem has_cat;;
1253 let has_rcons = Sections.finalize_theorem has_rcons;;
1254 let all_cat = Sections.finalize_theorem all_cat;;
1255 let all_rcons = Sections.finalize_theorem all_rcons;;
1256 let eq_find = Sections.finalize_theorem eq_find;;
1257 let eq_filter = Sections.finalize_theorem eq_filter;;
1258 let eq_count = Sections.finalize_theorem eq_count;;
1259 let eq_has = Sections.finalize_theorem eq_has;;
1260 let eq_all = Sections.finalize_theorem eq_all;;
1261 let filter_pred0 = Sections.finalize_theorem filter_pred0;;
1262 let filter_predT = Sections.finalize_theorem filter_predT;;
1263 let filter_predI = Sections.finalize_theorem filter_predI;;
1264 let count_pred0 = Sections.finalize_theorem count_pred0;;
1265 let count_predT = Sections.finalize_theorem count_predT;;
1266 let count_predUI = Sections.finalize_theorem count_predUI;;
1267 let count_predC = Sections.finalize_theorem count_predC;;
1268 let has_pred0 = Sections.finalize_theorem has_pred0;;
1269 let has_predT = Sections.finalize_theorem has_predT;;
1270 let has_predC = Sections.finalize_theorem has_predC;;
1271 let has_predU = Sections.finalize_theorem has_predU;;
1272 let all_pred0 = Sections.finalize_theorem all_pred0;;
1273 let all_predT = Sections.finalize_theorem all_predT;;
1274 let all_predC = Sections.finalize_theorem all_predC;;
1275 let can_inj = Sections.finalize_theorem can_inj;;
1276 let all_predI = Sections.finalize_theorem all_predI;;
1277 let eq_ext = Sections.finalize_theorem eq_ext;;
1278 let drop_nil = Sections.finalize_theorem drop_nil;;
1279 let drop0 = Sections.finalize_theorem drop0;;
1280 let drop_cons = Sections.finalize_theorem drop_cons;;
1281 let drop_behead = Sections.finalize_theorem drop_behead;;
1282 let drop0 = Sections.finalize_theorem drop0;;
1283 let drop1 = Sections.finalize_theorem drop1;;
1284 let drop_oversize = Sections.finalize_theorem drop_oversize;;
1285 let drop_size = Sections.finalize_theorem drop_size;;
1286 let size_drop = Sections.finalize_theorem size_drop;;
1287 let drop_cat = Sections.finalize_theorem drop_cat;;
1288 let drop_size_cat = Sections.finalize_theorem drop_size_cat;;
1289 let nconsK = Sections.finalize_theorem nconsK;;
1290 let take0 = Sections.finalize_theorem take0;;
1291 let take_oversize = Sections.finalize_theorem take_oversize;;
1292 let take_size = Sections.finalize_theorem take_size;;
1293 let take_cons = Sections.finalize_theorem take_cons;;
1294 let drop_rcons = Sections.finalize_theorem drop_rcons;;
1295 let congr1 = Sections.finalize_theorem congr1;;
1296 let cat_take_drop = Sections.finalize_theorem cat_take_drop;;
1297 let size_takel = Sections.finalize_theorem size_takel;;
1298 let size_take = Sections.finalize_theorem size_take;;
1299 let take_cat = Sections.finalize_theorem take_cat;;
1300 let take_size_cat = Sections.finalize_theorem take_size_cat;;
1301 let takel_cat = Sections.finalize_theorem takel_cat;;
1302 let nth_drop = Sections.finalize_theorem nth_drop;;
1303 let nth_take = Sections.finalize_theorem nth_take;;
1304 let drop_nth = Sections.finalize_theorem drop_nth;;
1305 let take_nth = Sections.finalize_theorem take_nth;;
1306 let rot0 = Sections.finalize_theorem rot0;;
1307 let size_rot = Sections.finalize_theorem size_rot;;
1308 let rot_oversize = Sections.finalize_theorem rot_oversize;;
1309 let rot_size = Sections.finalize_theorem rot_size;;
1310 let has_rot = Sections.finalize_theorem has_rot;;
1311 let rot_size_cat = Sections.finalize_theorem rot_size_cat;;
1312 let rotK = Sections.finalize_theorem rotK;;
1313 let rot_inj = Sections.finalize_theorem rot_inj;;
1314 let rot1_cons = Sections.finalize_theorem rot1_cons;;
1315 Sections.end_section "Sequences";;
1316 let catrev = define `catrev (x :: s1) s2 = catrev s1 (x :: s2) /\ catrev [] s2 = s2`;;
1317 let rev = new_definition `rev s = catrev s []`;;
1318
1319 (* Section Rev *)
1320 Sections.begin_section "Rev";;
1321 (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("t", (`:(A)list`))));;
1322
1323 (* Lemma catrev_catl *)
1324 let catrev_catl = Sections.section_proof ["s";"t";"u"]
1325 `catrev (s ++ t) u = catrev t (catrev s u)`
1326 [
1327    ((((use_arg_then2 ("u", [])) (disch_tac [])) THEN (clear_assumption "u") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1328 ];;
1329
1330 (* Lemma catrev_catr *)
1331 let catrev_catr = Sections.section_proof ["s";"t";"u"]
1332 `catrev s (t ++ u) = catrev s t ++ u`
1333 [
1334    (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (BETA_TAC THEN (move ["t"])) THEN ((((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1335    (((((use_arg_then2 ("IHs", []))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1336 ];;
1337
1338 (* Lemma catrevE *)
1339 let catrevE = Sections.section_proof ["s";"t"]
1340 `catrev s t = rev s ++ t`
1341 [
1342    (((((use_arg_then2 ("rev", [rev]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("catrev_catr", [catrev_catr]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1343 ];;
1344
1345 (* Lemma rev_cons *)
1346 let rev_cons = Sections.section_proof ["x";"s"]
1347 `rev (x :: s) = rcons (rev s) x`
1348 [
1349    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("catrevE", [catrevE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rev", [rev]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1350 ];;
1351
1352 (* Lemma size_rev *)
1353 let size_rev = Sections.section_proof ["s"]
1354 `sizel (rev s) = sizel s`
1355 [
1356    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("rev", [rev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1357    (((((use_arg_then2 ("catrevE", [catrevE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats1", [cats1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rcons", [size_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1358 ];;
1359
1360 (* Lemma rev_cat *)
1361 let rev_cat = Sections.section_proof ["s";"t"]
1362 `rev (s ++ t) = rev t ++ rev s`
1363 [
1364    (((repeat_tactic 1 9 (((use_arg_then2 ("rev", [rev]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("catrev_catr", [catrev_catr]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("catrev_catl", [catrev_catl]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
1365 ];;
1366
1367 (* Lemma rev_rcons *)
1368 let rev_rcons = Sections.section_proof ["s";"x"]
1369 `rev (rcons s x) = x :: rev s`
1370 [
1371    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rev_cat", [rev_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rev", [rev]))(thm_tac (new_rewrite [] []))))) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (done_tac));
1372 ];;
1373
1374 (* Lemma revK *)
1375 let revK = Sections.section_proof ["s"]
1376 `rev (rev s) = s`
1377 [
1378    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) ((repeat_tactic 1 9 (((use_arg_then2 ("rev", [rev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (simp_tac)));
1379    (((((use_arg_then2 ("rev_cons", [rev_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rev_rcons", [rev_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1380 ];;
1381
1382 (* Lemma nth_rev *)
1383 let nth_rev = Sections.section_proof ["x0";"n";"s"]
1384 `n < sizel s ==> nth x0 (rev s) n = nth x0 s (sizel s - SUC n)`
1385 [
1386    ((((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN BETA_TAC) THEN (((fun arg_tac -> arg_tac (Arg_theorem (REWRITE_RULE[IMP_IMP] last_ind))) (disch_tac [])) THEN (DISCH_THEN apply_tac)));
1387    (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["s"]) THEN (move ["x"]) THEN (move ["IHs"]) THEN (move ["n"]));
1388    ((((use_arg_then2 ("rev_rcons", [rev_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rcons", [size_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnS", [ltnS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))));
1389    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) (((((use_arg_then2 ("subn0", [subn0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("subnn", [subnn]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth0", [nth0]))(thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("head", [head]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)));
1390    (BETA_TAC THEN (move ["lt_n_s"]));
1391    ((((fun arg_tac -> (use_arg_then2 ("subnK", [subnK])) (fun fst_arg -> (use_arg_then2 ("lt_n_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [2] []))))) THEN (((use_arg_then2 ("addSnnS", [addSnnS]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_addr", [leq_addr]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)));
1392    ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1393 ];;
1394
1395 (* Finalization of the section Rev *)
1396 let catrev_catl = Sections.finalize_theorem catrev_catl;;
1397 let catrev_catr = Sections.finalize_theorem catrev_catr;;
1398 let catrevE = Sections.finalize_theorem catrevE;;
1399 let rev_cons = Sections.finalize_theorem rev_cons;;
1400 let size_rev = Sections.finalize_theorem size_rev;;
1401 let rev_cat = Sections.finalize_theorem rev_cat;;
1402 let rev_rcons = Sections.finalize_theorem rev_rcons;;
1403 let revK = Sections.finalize_theorem revK;;
1404 let nth_rev = Sections.finalize_theorem nth_rev;;
1405 Sections.end_section "Rev";;
1406
1407 (* Section EqSeq *)
1408 Sections.begin_section "EqSeq";;
1409 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
1410 (Sections.add_section_var (mk_var ("x0", (`:A`))));;
1411 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
1412 (Sections.add_section_type (mk_var ("x", (`:A`))); Sections.add_section_type (mk_var ("y", (`:A`))); Sections.add_section_type (mk_var ("z", (`:A`))));;
1413
1414 (* Lemma eqseq_cons *)
1415 let eqseq_cons = Sections.section_proof ["x1";"x2";"s1";"s2"]
1416 `((x1 :: s1) = x2 :: s2) <=> (x1 = x2 /\ s1 = s2)`
1417 [
1418    ((((fun arg_tac -> arg_tac (Arg_theorem (injectivity "list")))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1419 ];;
1420
1421 (* Lemma eqseq_cat *)
1422 let eqseq_cat = Sections.section_proof ["s1";"s2";"s3";"s4"]
1423 `sizel s1 = sizel s2 ==> (s1 ++ s3 = s2 ++ s4 <=> (s1 = s2 /\ s3 = s4))`
1424 [
1425    ((THENL) (((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x1"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x2"]) THEN (move ["s2"]) THEN (move ["_"]))]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) [(arith_tac); (arith_tac); BETA_TAC]);
1426    (((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("eqseq_cons", [eqseq_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("andbA", [andbA]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1427 ];;
1428
1429 (* Lemma eqseq_rcons *)
1430 let eqseq_rcons = Sections.section_proof ["s1";"s2";"x1";"x2"]
1431 `(rcons s1 x1 = rcons s2 x2) <=> (s1 = s2 /\ x1 = x2)`
1432 [
1433    ((THENL_ROT (-1)) (((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["y1"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y2"]) THEN (move ["s2"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("eqseq_cons", [eqseq_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac))));
1434    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbA", [andbA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1435    (((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s2"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1436    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["xx"]) THEN (move ["ss"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1437 ];;
1438
1439 (* Lemma has_filter *)
1440 let has_filter = Sections.section_proof ["a";"s"]
1441 `has a s <=> ~(filter a s = [])`
1442 [
1443    ((((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] [])))));
1444    ((fun arg_tac -> arg_tac (Arg_term (`filter a s`))) (term_tac (set_tac "l")));
1445    (((THENL) (((use_arg_then2 ("l_def", [])) (disch_tac [])) THEN (clear_assumption "l_def") THEN ((use_arg_then2 ("l", [])) (disch_tac [])) THEN (clear_assumption "l") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["l"]) THEN (move ["_"]))]) THEN (BETA_TAC THEN (move ["_"])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltnn", [ltnn]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))));
1446    (((((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1447 ];;
1448
1449 (* Lemma size_eq0 *)
1450 let size_eq0 = Sections.section_proof ["s"]
1451 `(sizel s = 0) <=> (s = [])`
1452 [
1453    (((THENL) (split_tac) [ALL_TAC; (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("size0nil", [size0nil])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac));
1454 ];;
1455 parse_as_infix("<-", (11, "right"));;
1456 override_interface("<-", `MEM`);;
1457
1458 (* Lemma in_cons *)
1459 let in_cons = Sections.section_proof ["y";"s";"x"]
1460 `(x <- y :: s) <=> (x = y \/ x <- s)`
1461 [
1462    ((repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1463 ];;
1464
1465 (* Lemma in_nil *)
1466 let in_nil = Sections.section_proof ["x"]
1467 `(x <- []) = F`
1468 [
1469    ((repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1470 ];;
1471
1472 (* Lemma mem_seq1 *)
1473 let mem_seq1 = Sections.section_proof ["x";"y"]
1474 `(x <- [y]) <=> (x = y)`
1475 [
1476    (((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbF", [orbF]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1477 ];;
1478
1479 (* Lemma mem_seq2 *)
1480 let mem_seq2 = Sections.section_proof ["x";"y1";"y2"]
1481 `(x <- [y1; y2]) <=> (x = y1 \/ x = y2)`
1482 [
1483    (((repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbF", [orbF]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1484 ];;
1485
1486 (* Lemma mem_seq3 *)
1487 let mem_seq3 = Sections.section_proof ["x";"y1";"y2";"y3"]
1488 `(x <- [y1; y2; y3]) <=> (x = y1 \/ x = y2 \/ x = y3)`
1489 [
1490    (((repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbF", [orbF]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1491 ];;
1492
1493 (* Lemma mem_seq4 *)
1494 let mem_seq4 = Sections.section_proof ["x";"y1";"y2";"y3";"y4"]
1495 `(x <- [y1; y2; y3; y4]) <=> (x = y1 \/ x = y2 \/ x = y3 \/ x = y4)`
1496 [
1497    (((repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbF", [orbF]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1498 ];;
1499
1500 (* Lemma mem_cat *)
1501 let mem_cat = Sections.section_proof ["x";"s1";"s2"]
1502 `(x <- s1 ++ s2) <=> (x <- s1 \/ x <- s2)`
1503 [
1504    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) (((((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orFb", [orFb]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
1505    (((((use_arg_then2 ("cat_cons", [cat_cons]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbA", [orbA]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
1506 ];;
1507
1508 (* Lemma mem_rcons *)
1509 let mem_rcons = Sections.section_proof ["s";"y"]
1510 `!x. x <- rcons s y <=> x <- y :: s`
1511 [
1512    ((BETA_TAC THEN (move ["x"])) THEN ((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_seq1", [mem_seq1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbC", [orbC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1513 ];;
1514
1515 (* Lemma mem_head *)
1516 let mem_head = Sections.section_proof ["x";"s"]
1517 `x <- x :: s`
1518 [
1519    (((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
1520 ];;
1521
1522 (* Lemma mem_last *)
1523 let mem_last = Sections.section_proof ["x";"s"]
1524 `last x s <- x :: s`
1525 [
1526    (((((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_rcons", [mem_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_head", [mem_head]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1527 ];;
1528
1529 (* Lemma mem_behead *)
1530 let mem_behead = Sections.section_proof ["s"]
1531 `!x. x <- behead s ==> x <- s`
1532 [
1533    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["_"]) THEN (move ["x"]))]) THEN ((((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("in_cons", [in_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1534 ];;
1535
1536 (* Lemma mem_belast *)
1537 let mem_belast = Sections.section_proof ["s";"y"]
1538 `!x. x <- belast y s ==> x <- y :: s`
1539 [
1540    ((BETA_TAC THEN (move ["x"]) THEN (move ["ys'x"])) THEN ((((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_rcons", [mem_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_behead", [mem_behead]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1541 ];;
1542
1543 (* Lemma mem_nth *)
1544 let mem_nth = Sections.section_proof ["s";"n"]
1545 `n < sizel s ==> nth x0 s n <- s`
1546 [
1547    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltS0", [ltS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("mem_head", [mem_head]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1548    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (move ["sz_s"]));
1549    ((((use_arg_then2 ("mem_behead", [mem_behead]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1550 ];;
1551
1552 (* Lemma mem_take *)
1553 let mem_take = Sections.section_proof ["s";"x"]
1554 `x <- take n0 s ==> x <- s`
1555 [
1556    ((BETA_TAC THEN (move ["s0x"])) THEN ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1557 ];;
1558
1559 (* Lemma mem_drop *)
1560 let mem_drop = Sections.section_proof ["s";"x"]
1561 `x <- dropl n0 s ==> x <- s`
1562 [
1563    ((BETA_TAC THEN (move ["s0'x"])) THEN ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1564 ];;
1565
1566 (* Lemma mem_rev *)
1567 let mem_rev = Sections.section_proof ["s"]
1568 `!x. x <- rev s <=> x <- s`
1569 [
1570    ((THENL_FIRST) ((BETA_TAC THEN (move ["y"])) THEN ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))])) (((((use_arg_then2 ("rev", [rev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac)));
1571    (((((use_arg_then2 ("rev_cons", [rev_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_rcons", [mem_rcons]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1572 ];;
1573
1574 (* Section Filters *)
1575 Sections.begin_section "Filters";;
1576 (Sections.add_section_var (mk_var ("a", (`:A -> bool`))));;
1577
1578 (* Lemma hasP *)
1579 let hasP = Sections.section_proof ["s"]
1580 `(?x. x <- s /\ a x) <=> has a s`
1581 [
1582    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))));
1583    ((THENL_FIRST) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["ay"])) (((use_arg_then2 ("y", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("mem_head", [mem_head]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
1584    ((THENL_ROT (-1)) ((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((split_tac) THEN ALL_TAC THEN (case THEN ((move ["x"]) THEN (case THEN ((move ["ysx"]) THEN (move ["ax"]))))))));
1585    (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN ((((use_arg_then2 ("mem_behead", [mem_behead]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1586    (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("ysx", [])) (disch_tac [])) THEN (clear_assumption "ysx") THEN BETA_TAC) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))));
1587    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y:A`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN ((simp_tac THEN TRY done_tac)) THEN (move ["xy"]));
1588    ((((use_arg_then2 ("ax", [])) (disch_tac [])) THEN (clear_assumption "ax") THEN BETA_TAC) THEN ((((use_arg_then2 ("xy", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ay", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1589 ];;
1590
1591 (* Lemma hasPn *)
1592 let hasPn = Sections.section_proof ["s"]
1593 `(!x. x <- s ==> ~(a x)) <=> ~has a s`
1594 [
1595    ((THENL_ROT (1)) ((split_tac) THEN (move ["not_a_s"])));
1596    ((BETA_TAC THEN (move ["x"]) THEN (move ["s_x"])) THEN (((use_arg_then2 ("not_a_s", [])) (disch_tac [])) THEN (clear_assumption "not_a_s") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (move ["a_x"])));
1597    ((((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac));
1598    ((((((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("implybF", [implybF]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (case THEN ((move ["x"]) THEN (case THEN (move ["s_x"]))))) THEN (((use_arg_then2 ("implybF", [implybF]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("not_a_s", [])) (disch_tac [])) THEN (clear_assumption "not_a_s") THEN (exact_tac)) THEN (done_tac));
1599 ];;
1600
1601 (* Lemma allP *)
1602 let allP = Sections.section_proof ["s"]
1603 `(!x. x <- s ==> a x) <=> (all a s)`
1604 [
1605    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1606    ((THENL_ROT (-1)) (((((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (split_tac)));
1607    (BETA_TAC THEN (case THEN ((move ["h"]) THEN (move ["ax"]))) THEN (move ["y"]) THEN ((THENL) case [((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); (move ["ys"])]));
1608    (((use_arg_then2 ("h", [])) (disch_tac [])) THEN (clear_assumption "h") THEN (exact_tac));
1609    (BETA_TAC THEN (move ["h"]));
1610    ((THENL_FIRST) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) (BETA_TAC THEN (move ["ax"])));
1611    ((((((use_arg_then2 ("ax", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (move ["y"]) THEN (move ["ys"])) THEN (((use_arg_then2 ("h", [])) (disch_tac [])) THEN (clear_assumption "h") THEN (exact_tac)) THEN (done_tac));
1612    (((use_arg_then2 ("h", [])) (disch_tac [])) THEN (clear_assumption "h") THEN (exact_tac));
1613 ];;
1614
1615 (* Lemma allPn *)
1616 let allPn = Sections.section_proof ["s"]
1617 `(?x. x <- s /\ ~a x) <=> ~all a s`
1618 [
1619    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("in_cons", [in_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
1620    (((((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negb_and", [negb_and]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (split_tac));
1621    (BETA_TAC THEN (case THEN ((move ["y"]) THEN (case THEN ((move ["ay"]) THEN ((THENL) case [(move ["eq"]); (move ["mem"])]))))));
1622    ((((use_arg_then2 ("ay", [])) (disch_tac [])) THEN (clear_assumption "ay") THEN BETA_TAC) THEN ((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
1623    ((DISJ2_TAC) THEN ((use_arg_then2 ("y", [])) (term_tac exists_tac)) THEN (done_tac));
1624    ((THENL_FIRST) ((THENL) case [(move ["nax"]); (case THEN ((move ["y"]) THEN (case THEN ((move ["ys"]) THEN (move ["nay"])))))]) ((((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (simp_tac)) THEN (done_tac)));
1625    (((use_arg_then2 ("y", [])) (term_tac exists_tac)) THEN (done_tac));
1626 ];;
1627
1628 (* Lemma mem_filter *)
1629 let mem_filter = Sections.section_proof ["x";"s"]
1630 `(x <- filter a s) <=> (a x /\ x <- s)`
1631 [
1632    ((((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] [])))) THEN ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1633    ((((use_arg_then2 ("fun_if", [fun_if]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))));
1634    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(a:A->bool) y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["ay"])) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y:A`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN ((simp_tac THEN TRY done_tac))) THEN (done_tac));
1635 ];;
1636
1637 (* Finalization of the section Filters *)
1638 let hasP = Sections.finalize_theorem hasP;;
1639 let hasPn = Sections.finalize_theorem hasPn;;
1640 let allP = Sections.finalize_theorem allP;;
1641 let allPn = Sections.finalize_theorem allPn;;
1642 let mem_filter = Sections.finalize_theorem mem_filter;;
1643 Sections.end_section "Filters";;
1644
1645 (* Lemma eq_in_filter *)
1646 let eq_in_filter = Sections.section_proof ["a1";"a2";"s"]
1647 `(!x. x <- s ==> a1 x = a2 x) ==> filter a1 s = filter a2 s`
1648 [
1649    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (move ["eq_a"])));
1650    (((((use_arg_then2 ("eq_a", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("mem_head", [mem_head]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (move ["y"]) THEN (move ["s_y"]));
1651    ((((use_arg_then2 ("eq_a", [])) (disch_tac [])) THEN (clear_assumption "eq_a") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("mem_behead", [mem_behead]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1652 ];;
1653
1654 (* Lemma eq_has_r *)
1655 let eq_has_r = Sections.section_proof ["s1";"s2"]
1656 `(!x. x <- s1 <=> x <- s2) ==> (!a. has a s1 <=> has a s2)`
1657 [
1658    (BETA_TAC THEN (move ["Es12"]) THEN (move ["a"]));
1659    ((split_tac) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ALL_TAC THEN (case THEN ((move ["x"]) THEN (case THEN ((move ["Hx"]) THEN (move ["Hax"])))))));
1660    (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("Es12", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac));
1661    (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("Es12", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1662 ];;
1663
1664 (* Lemma eq_all_r *)
1665 let eq_all_r = Sections.section_proof ["s1";"s2"]
1666 `(!x. x <- s1 <=> x <- s2) ==> (!a. all a s1 = all a s2)`
1667 [
1668    ((BETA_TAC THEN (move ["Es12"]) THEN (move ["a"])) THEN (repeat_tactic 1 9 (((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((split_tac) THEN (move ["Hs"]) THEN (move ["x"]) THEN (move ["Hx"])));
1669    ((((use_arg_then2 ("Hs", [])) (disch_tac [])) THEN (clear_assumption "Hs") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("Es12", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1670    ((((use_arg_then2 ("Hs", [])) (disch_tac [])) THEN (clear_assumption "Hs") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("Es12", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac));
1671 ];;
1672
1673 (* Lemma has_sym *)
1674 let has_sym = Sections.section_proof ["s1";"s2"]
1675 `has (\x. x <- s1) s2 = has (\x. x <- s2) s1`
1676 [
1677    (((repeat_tactic 1 9 (((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (simp_tac) THEN (((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1678 ];;
1679
1680 (* Lemma has_pred1 *)
1681 let has_pred1 = Sections.section_proof ["x";"s"]
1682 `has (pred1 x) s <=> x <- s`
1683 [
1684    (((((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN ((THENL) (split_tac) [((case THEN ((move ["y"]) THEN (case THEN ((move ["ys"]) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] []))))))))) THEN ((TRY done_tac))); (move ["xs"])]));
1685    (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac));
1686 ];;
1687 let constant = define `constant [] = T /\ constant (CONS x s') = all (pred1 x) s'`;;
1688
1689 (* Lemma all_pred1P *)
1690 let all_pred1P = Sections.section_proof ["x";"s"]
1691 `(s = nseq (sizel s) x) <=> (all (pred1 x) s)`
1692 [
1693    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("eqseq_cons", [eqseq_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
1694    ((THENL_ROT (-1)) ((THENL) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [(((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] []))))); (move ["ne_xy"])]));
1695    (((((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN ((((use_arg_then2 ("ne_xy", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("andFb", [andFb]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1696    (((((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [1] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nseq", [nseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ncons", [ncons]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1697 ];;
1698
1699 (* Lemma all_pred1_constant *)
1700 let all_pred1_constant = Sections.section_proof ["x";"s"]
1701 `all (pred1 x) s ==> constant s`
1702 [
1703    ((((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) THEN ((((use_arg_then2 ("constant", [constant]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1704 ];;
1705
1706 (* Lemma all_pred1_nseq *)
1707 let all_pred1_nseq = Sections.section_proof ["x";"y";"n"]
1708 `all (pred1 x) (nseq n y) <=> (n = 0 \/ x = y)`
1709 [
1710    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((simp_tac THEN TRY done_tac))));
1711    (((((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`y = x`)])))) THEN (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orFb", [orFb]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("andb_idr", [andb_idr])) (disch_tac [])) THEN (clear_assumption "andb_idr") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))));
1712    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1713 ];;
1714
1715 (* Lemma constant_nseq *)
1716 let constant_nseq = Sections.section_proof ["n";"x"]
1717 `constant (nseq n x)`
1718 [
1719    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN case) [ALL_TAC; (move ["n"])]) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("constant", [constant]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1720    (((((use_arg_then2 ("ncons", [ncons]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nseq", [nseq]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("all_pred1_nseq", [all_pred1_nseq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1721 ];;
1722
1723 (* Lemma constantP *)
1724 let constantP = Sections.section_proof ["s"]
1725 `(?x. s = nseq (sizel s) x) <=> (constant s)`
1726 [
1727    ((THENL_FIRST) ((THENL) (split_tac) [(case THEN ((move ["x"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))); ALL_TAC]) ((((use_arg_then2 ("constant_nseq", [constant_nseq]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
1728    ((THENL_FIRST) (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["x"]) THEN (move ["s"]))]) THEN ((((use_arg_then2 ("constant", [constant]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac))) ((EXISTS_TAC `x0:A`) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)));
1729    (((((use_arg_then2 ("all_pred1P", [all_pred1P]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (move ["def_s"])) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)));
1730    ((((use_arg_then2 ("def_s", []))(thm_tac (new_rewrite [1] [])))) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1731 ];;
1732 let uniq = define `uniq [] = T /\ (uniq (x :: s') <=> ~(MEM x s') /\ uniq s')`;;
1733
1734 (* Lemma nil_uniq *)
1735 let nil_uniq = Sections.section_proof []
1736 `uniq ([]:(A)list)`
1737 [
1738    ((((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1739 ];;
1740
1741 (* Lemma cons_uniq *)
1742 let cons_uniq = Sections.section_proof ["x";"s"]
1743 `uniq (x :: s) <=> ~(x <- s) /\ uniq s`
1744 [
1745    ((((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1746 ];;
1747
1748 (* Lemma cat_uniq *)
1749 let cat_uniq = Sections.section_proof ["s1";"s2"]
1750 `uniq (s1 ++ s2) <=> uniq s1 /\ ~ has (\x. x <- s1) s2 /\ uniq s2`
1751 [
1752    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) (((((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred0", [pred0]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_pred0", [has_pred0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nil_uniq", [nil_uniq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
1753    ((((use_arg_then2 ("has_sym", [has_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat_cons", [cat_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_cons", [has_cons]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("negb_or", [negb_or]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_sym", [has_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("andbA", [andbA]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac));
1754    ((((use_arg_then2 ("andbAC", [andbAC]))(thm_tac (new_rewrite [] [(`_ /\ uniq s1`)])))) THEN (done_tac));
1755 ];;
1756
1757 (* Lemma uniq_catC *)
1758 let uniq_catC = Sections.section_proof ["s1";"s2"]
1759 `uniq (s1 ++ s2) = uniq (s2 ++ s1)`
1760 [
1761    (((repeat_tactic 1 9 (((use_arg_then2 ("cat_uniq", [cat_uniq]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_sym", [has_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbCA", [andbCA]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbA", [andbA]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1762 ];;
1763
1764 (* Lemma uniq_catCA *)
1765 let uniq_catCA = Sections.section_proof ["s1";"s2";"s3"]
1766 `uniq (s1 ++ s2 ++ s3) = uniq (s2 ++ s1 ++ s3)`
1767 [
1768    (repeat_tactic 1 9 (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] [])))));
1769    (((repeat_tactic 1 9 (((use_arg_then2 ("uniq_catC", [uniq_catC]))(gsym_then (thm_tac (new_rewrite [] [(`uniq (cat _ s3)`)])))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat_uniq", [cat_uniq]))(thm_tac (new_rewrite [] [(`uniq (cat s3 _)`)]))))) THEN (((use_arg_then2 ("uniq_catC", [uniq_catC]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("has_cat", [has_cat]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("orbC", [orbC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1770 ];;
1771
1772 (* Lemma rcons_uniq *)
1773 let rcons_uniq = Sections.section_proof ["s";"x"]
1774 `uniq (rcons s x) <=> (~(x <- s) /\ uniq s)`
1775 [
1776    (((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("uniq_catC", [uniq_catC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat_cons", [cat_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1777 ];;
1778
1779 (* Lemma filter_uniq *)
1780 let filter_uniq = Sections.section_proof ["s";"a"]
1781 `uniq s ==> uniq (filter a s)`
1782 [
1783    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1784    ((THENL_ROT (-1)) (((THENL) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`a x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (move ["nax"])]) THEN (BETA_TAC THEN (case THEN ((move ["Hx"]) THEN (move ["Hs"]))))));
1785    (((((use_arg_then2 ("nax", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (((use_arg_then2 ("IHs", [])) (disch_tac [])) THEN (clear_assumption "IHs") THEN (exact_tac)) THEN (done_tac));
1786    ((((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((((use_arg_then2 ("mem_filter", [mem_filter]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("negbTE", [negbTE])) (fun fst_arg -> (use_arg_then2 ("Hx", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbF", [andbF]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1787 ];;
1788
1789 (* Lemma rot_uniq *)
1790 let rot_uniq = Sections.section_proof ["s"]
1791 `uniq (rot n0 s) = uniq s`
1792 [
1793    (((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("uniq_catC", [uniq_catC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1794 ];;
1795
1796 (* Lemma rev_uniq *)
1797 let rev_uniq = Sections.section_proof ["s"]
1798 `uniq (rev s) = uniq s`
1799 [
1800    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) (((((use_arg_then2 ("rev", [rev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (done_tac)));
1801    (((((use_arg_then2 ("rev_cons", [rev_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("cat_uniq", [cat_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_cons", [has_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nil_uniq", [nil_uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_nil", [has_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negb_or", [negb_or]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_rev", [mem_rev]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1802 ];;
1803
1804 (* Lemma count_uniq_mem *)
1805 let count_uniq_mem = Sections.section_proof ["s";"x"]
1806 `uniq s ==> count (pred1 x) s = if (x <- s) then 1 else 0`
1807 [
1808    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
1809    ((((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (move ["Hy"]))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))));
1810    ((((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`y = x`)])))));
1811    (((THENL) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); ALL_TAC]) THEN ((((use_arg_then2 ("Hy", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("addn0", [addn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1812    ((((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1813 ];;
1814 let undup = define `undup [] = [] /\ 
1815         undup (x :: s') = if x <- s' then undup s' else x :: undup s'`;;
1816
1817 (* Lemma size_undup *)
1818 let size_undup = Sections.section_proof ["s"]
1819 `sizel (undup s) <= sizel s`
1820 [
1821    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("undup", [undup]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("leqnn", [leqnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1822    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x <- s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltnW", [ltnW]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1823 ];;
1824
1825 (* Lemma mem_undup *)
1826 let mem_undup = Sections.section_proof ["s"]
1827 `!x. x <- undup s <=> x <- s`
1828 [
1829    ((BETA_TAC THEN (move ["x"])) THEN ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("undup", [undup]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1830    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`y <- s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["Hy"])) THEN ((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1831    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) THEN (done_tac));
1832 ];;
1833
1834 (* Lemma undup_uniq *)
1835 let undup_uniq = Sections.section_proof ["s"]
1836 `uniq (undup s)`
1837 [
1838    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("undup", [undup]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1839    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x <- s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) THEN (((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_undup", [mem_undup]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
1840 ];;
1841
1842 (* Lemma undup_id *)
1843 let undup_id = Sections.section_proof ["s"]
1844 `uniq s ==> undup s = s`
1845 [
1846    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (((((use_arg_then2 ("undup", [undup]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((simp_tac THEN TRY done_tac))) THEN ALL_TAC THEN (case THEN ((move ["Hx"]) THEN (move ["Hs"])))));
1847    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
1848 ];;
1849
1850 (* Lemma ltn_size_undup *)
1851 let ltn_size_undup = Sections.section_proof ["s"]
1852 `(sizel (undup s) < sizel s) <=> ~ uniq s`
1853 [
1854    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("undup", [undup]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
1855    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x <- s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) THEN (((simp_tac THEN TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltnS", [ltnS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_undup", [size_undup]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1856 ];;
1857 let index = new_definition `indexl x = find (pred1 x)`;;
1858
1859 (* Lemma index_size *)
1860 let index_size = Sections.section_proof ["x";"s"]
1861 `indexl x s <= sizel s`
1862 [
1863    (((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("find_size", [find_size]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1864 ];;
1865
1866 (* Lemma index_mem *)
1867 let index_mem = Sections.section_proof ["x";"s"]
1868 `(indexl x s < sizel s) <=> (x <- s)`
1869 [
1870    (((((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_find", [has_find]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1871 ];;
1872
1873 (* Lemma nth_index *)
1874 let nth_index = Sections.section_proof ["x";"s"]
1875 `x <- s ==> nth x0 s (indexl x s) = x`
1876 [
1877    ((((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((DISCH_THEN (fun snd_th -> (fun arg_tac -> (use_arg_then2 ("nth_find", [nth_find])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN ((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
1878 ];;
1879
1880 (* Lemma index_cat *)
1881 let index_cat = Sections.section_proof ["x";"s1";"s2"]
1882 `indexl x (s1 ++ s2) = if x <- s1 then indexl x s1 else sizel s1 + indexl x s2`
1883 [
1884    (((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("find_cat", [find_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_pred1", [has_pred1]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1885 ];;
1886
1887 (* Lemma index_uniq *)
1888 let index_uniq = Sections.section_proof ["i";"s"]
1889 `i < sizel s ==> uniq s ==> indexl (nth x0 s i) s = i`
1890 [
1891    (((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN ((THENL) elim [ALL_TAC; ((move ["i"]) THEN (move ["_"]))]));
1892    (((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("index", [index]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1893    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnS", [ltnS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] []))))) THEN (move ["lt_i_s"]) THEN (case THEN (move ["not_s_x"])));
1894    (((DISCH_THEN (fun snd_th -> (fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("IHs", [])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("lt_i_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("index", [index]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac)));
1895    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = nth x0 s i`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["x_eq"]));
1896    (((fun arg_tac -> (use_arg_then2 ("mem_nth", [mem_nth])) (fun fst_arg -> (use_arg_then2 ("lt_i_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun arg -> thm_tac MP_TAC arg THEN ALL_TAC)) THEN ((((use_arg_then2 ("x_eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("negbTE", [negbTE])) (fun fst_arg -> (use_arg_then2 ("not_s_x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1897 ];;
1898
1899 (* Lemma index_head *)
1900 let index_head = Sections.section_proof ["x";"s"]
1901 `indexl x (x :: s) = 0`
1902 [
1903    (((((use_arg_then2 ("index", [index]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
1904 ];;
1905
1906 (* Lemma index_last *)
1907 let index_last = Sections.section_proof ["x";"s"]
1908 `uniq (x :: s) ==> indexl (last x s) (x :: s) = sizel s`
1909 [
1910    ((((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rcons_uniq", [rcons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_cat", [index_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_belast", [size_belast]))(thm_tac (new_rewrite [] [])))));
1911    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`last x s <- belast x s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac));
1912    (((((use_arg_then2 ("index", [index]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("addn0", [addn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1913 ];;
1914
1915 (* Lemma nth_uniq *)
1916 let nth_uniq = Sections.section_proof ["s";"i";"j"]
1917 `i < sizel s ==> j < sizel s ==> uniq s ==> (nth x0 s i = nth x0 s j) = (i = j)`
1918 [
1919    ((BETA_TAC THEN (move ["lt_i_s"]) THEN (move ["lt_j_s"]) THEN (move ["Us"])) THEN ((THENL) (split_tac) [(move ["eq_sij"]); ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))]));
1920    (((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("index_uniq", [index_uniq])) (fun fst_arg -> (use_arg_then2 ("lt_i_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("Us", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("eq_sij", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_uniq", [index_uniq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1921 ];;
1922
1923 (* Lemma mem_rot *)
1924 let mem_rot = Sections.section_proof ["s"]
1925 `!x. x <- rot n0 s <=> x <- s`
1926 [
1927    ((BETA_TAC THEN (move ["x"])) THEN ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [2] [(`s`)]))))) THEN (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("orbC", [orbC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1928 ];;
1929
1930 (* Lemma eqseq_rot *)
1931 let eqseq_rot = Sections.section_proof ["s1";"s2"]
1932 `(rot n0 s1 = rot n0 s2) <=> (s1 = s2)`
1933 [
1934    (((THENL) (split_tac) [ALL_TAC; ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))]) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("rot_inj", [rot_inj])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac));
1935 ];;
1936
1937 (* Lemma rot_to *)
1938 let rot_to = Sections.section_proof ["s";"x"]
1939 `x <- s ==> ?i s'. rot i s = x :: s'`
1940 [
1941    ((BETA_TAC THEN (move ["s_x"])) THEN ((fun arg_tac -> arg_tac (Arg_term (`indexl (x:A) s`))) (term_tac (set_tac "i"))));
1942    (((use_arg_then2 ("i", [])) (term_tac exists_tac)) THEN ((fun arg_tac -> arg_tac (Arg_term (`dropl (SUC i) s ++ take i s`))) (term_tac exists_tac)));
1943    (((((use_arg_then2 ("cat_cons", [cat_cons]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("i_def", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((fun arg_tac -> arg_tac (Arg_term (`take _1 _2`))) (term_tac (set_tac "r"))));
1944    (((use_arg_then2 ("r_def", [])) (disch_tac [])) THEN (clear_assumption "r_def") THEN ((use_arg_then2 ("i_def", [])) (disch_tac [])) THEN (clear_assumption "i_def") THEN BETA_TAC THEN (move ["_"]) THEN (move ["_"]));
1945    (((THENL) (((use_arg_then2 ("s_x", [])) (disch_tac [])) THEN (clear_assumption "s_x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("in_nil", [in_nil]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))));
1946    ((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)));
1947    ((((use_arg_then2 ("index_head", [index_head]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop0", [drop0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop_cons", [drop_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop0", [drop0]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)));
1948    ((((((use_arg_then2 ("index", [index]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("pred1", [pred1]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("index", [index]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("drop_cons", [drop_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (move ["_"])) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1949 ];;
1950
1951 (* Finalization of the section EqSeq *)
1952 let eqseq_cons = Sections.finalize_theorem eqseq_cons;;
1953 let eqseq_cat = Sections.finalize_theorem eqseq_cat;;
1954 let eqseq_rcons = Sections.finalize_theorem eqseq_rcons;;
1955 let has_filter = Sections.finalize_theorem has_filter;;
1956 let size_eq0 = Sections.finalize_theorem size_eq0;;
1957 let in_cons = Sections.finalize_theorem in_cons;;
1958 let in_nil = Sections.finalize_theorem in_nil;;
1959 let mem_seq1 = Sections.finalize_theorem mem_seq1;;
1960 let mem_seq2 = Sections.finalize_theorem mem_seq2;;
1961 let mem_seq3 = Sections.finalize_theorem mem_seq3;;
1962 let mem_seq4 = Sections.finalize_theorem mem_seq4;;
1963 let mem_cat = Sections.finalize_theorem mem_cat;;
1964 let mem_rcons = Sections.finalize_theorem mem_rcons;;
1965 let mem_head = Sections.finalize_theorem mem_head;;
1966 let mem_last = Sections.finalize_theorem mem_last;;
1967 let mem_behead = Sections.finalize_theorem mem_behead;;
1968 let mem_belast = Sections.finalize_theorem mem_belast;;
1969 let mem_nth = Sections.finalize_theorem mem_nth;;
1970 let mem_take = Sections.finalize_theorem mem_take;;
1971 let mem_drop = Sections.finalize_theorem mem_drop;;
1972 let mem_rev = Sections.finalize_theorem mem_rev;;
1973 let hasP = Sections.finalize_theorem hasP;;
1974 let hasPn = Sections.finalize_theorem hasPn;;
1975 let allP = Sections.finalize_theorem allP;;
1976 let allPn = Sections.finalize_theorem allPn;;
1977 let mem_filter = Sections.finalize_theorem mem_filter;;
1978 let eq_in_filter = Sections.finalize_theorem eq_in_filter;;
1979 let eq_has_r = Sections.finalize_theorem eq_has_r;;
1980 let eq_all_r = Sections.finalize_theorem eq_all_r;;
1981 let has_sym = Sections.finalize_theorem has_sym;;
1982 let has_pred1 = Sections.finalize_theorem has_pred1;;
1983 let all_pred1P = Sections.finalize_theorem all_pred1P;;
1984 let all_pred1_constant = Sections.finalize_theorem all_pred1_constant;;
1985 let all_pred1_nseq = Sections.finalize_theorem all_pred1_nseq;;
1986 let constant_nseq = Sections.finalize_theorem constant_nseq;;
1987 let constantP = Sections.finalize_theorem constantP;;
1988 let nil_uniq = Sections.finalize_theorem nil_uniq;;
1989 let cons_uniq = Sections.finalize_theorem cons_uniq;;
1990 let cat_uniq = Sections.finalize_theorem cat_uniq;;
1991 let uniq_catC = Sections.finalize_theorem uniq_catC;;
1992 let uniq_catCA = Sections.finalize_theorem uniq_catCA;;
1993 let rcons_uniq = Sections.finalize_theorem rcons_uniq;;
1994 let filter_uniq = Sections.finalize_theorem filter_uniq;;
1995 let rot_uniq = Sections.finalize_theorem rot_uniq;;
1996 let rev_uniq = Sections.finalize_theorem rev_uniq;;
1997 let count_uniq_mem = Sections.finalize_theorem count_uniq_mem;;
1998 let size_undup = Sections.finalize_theorem size_undup;;
1999 let mem_undup = Sections.finalize_theorem mem_undup;;
2000 let undup_uniq = Sections.finalize_theorem undup_uniq;;
2001 let undup_id = Sections.finalize_theorem undup_id;;
2002 let ltn_size_undup = Sections.finalize_theorem ltn_size_undup;;
2003 let index_size = Sections.finalize_theorem index_size;;
2004 let index_mem = Sections.finalize_theorem index_mem;;
2005 let nth_index = Sections.finalize_theorem nth_index;;
2006 let index_cat = Sections.finalize_theorem index_cat;;
2007 let index_uniq = Sections.finalize_theorem index_uniq;;
2008 let index_head = Sections.finalize_theorem index_head;;
2009 let index_last = Sections.finalize_theorem index_last;;
2010 let nth_uniq = Sections.finalize_theorem nth_uniq;;
2011 let mem_rot = Sections.finalize_theorem mem_rot;;
2012 let eqseq_rot = Sections.finalize_theorem eqseq_rot;;
2013 let rot_to = Sections.finalize_theorem rot_to;;
2014 Sections.end_section "EqSeq";;
2015
2016 (* Section NseqthTheory *)
2017 Sections.begin_section "NseqthTheory";;
2018 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
2019
2020 (* Lemma nthP *)
2021 let nthP = Sections.section_proof ["s";"x";"x0"]
2022 `(?i. i < sizel s /\ nth x0 s i = x) <=> (x <- s)`
2023 [
2024    ((THENL_FIRST) ((THENL) (split_tac) [(case THEN ((move ["n"]) THEN (case THEN ((move ["Hn"]) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] []))))))))); (move ["Hx"])]) ((((use_arg_then2 ("mem_nth", [mem_nth])) (disch_tac [])) THEN (clear_assumption "mem_nth") THEN (DISCH_THEN apply_tac)) THEN (done_tac)));
2025    (((fun arg_tac -> arg_tac (Arg_term (`indexl x s`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hx", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index])) (disch_tac [])) THEN (clear_assumption "nth_index") THEN (DISCH_THEN apply_tac)) THEN (done_tac));
2026 ];;
2027
2028 (* Lemma has_nthP *)
2029 let has_nthP = Sections.section_proof ["a";"s";"x0"]
2030 `(?i. i < sizel s /\ a (nth x0 s i)) <=> (has a s)`
2031 [
2032    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("andFb", [andFb]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2033    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`a x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["ax"]));
2034    (((fun arg_tac -> arg_tac (Arg_term (`0`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0Sn", [ltn0Sn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2035    ((THENL_ROT (-1)) ((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((THENL) (split_tac) [(case THEN ALL_TAC); (case THEN (move ["i"]))])));
2036    ((BETA_TAC THEN (case THEN ((move ["i_s"]) THEN (move ["anth"])))) THEN ((fun arg_tac -> arg_tac (Arg_term (`SUC i`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2037    ((THENL_FIRST) (((THENL) elim [ALL_TAC; ((move ["i"]) THEN (move ["_"]))]) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) ((((use_arg_then2 ("ax", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)));
2038    ((((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN ((move ["i_s"]) THEN (move ["anth"])))) THEN ((use_arg_then2 ("i", [])) (term_tac exists_tac)) THEN (done_tac));
2039 ];;
2040
2041 (* Lemma all_nthP *)
2042 let all_nthP = Sections.section_proof ["a";"s";"x0"]
2043 `(!i. i < sizel s ==> a (nth x0 s i)) <=> (all a s)`
2044 [
2045    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((TRY done_tac))));
2046    ((THENL_ROT (-1)) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`a x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["ax"])));
2047    ((((use_arg_then2 ("NOT_FORALL_THM", [NOT_FORALL_THM]))(thm_tac (new_rewrite [] [])))) THEN ((fun arg_tac -> arg_tac (Arg_term (`0`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0Sn", [ltn0Sn]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2048    ((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((split_tac) THEN (move ["IH"]) THEN (move ["i"]) THEN (move ["i_s"])));
2049    ((((fun arg_tac -> (use_arg_then2 ("IH", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`SUC i`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (exact_tac) THEN (done_tac));
2050    (((THENL) (((use_arg_then2 ("i_s", [])) (disch_tac [])) THEN (clear_assumption "i_s") THEN ((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN elim) [ALL_TAC; ((move ["i"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2051    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IH", [])) (disch_tac [])) THEN (clear_assumption "IH") THEN (DISCH_THEN apply_tac)) THEN (done_tac));
2052 ];;
2053
2054 (* Finalization of the section NseqthTheory *)
2055 let nthP = Sections.finalize_theorem nthP;;
2056 let has_nthP = Sections.finalize_theorem has_nthP;;
2057 let all_nthP = Sections.finalize_theorem all_nthP;;
2058 Sections.end_section "NseqthTheory";;
2059
2060 (* Lemma set_nth_default *)
2061 let set_nth_default = Sections.section_proof ["s";"y0";"x0";"n"]
2062 `n < sizel s ==> nth (x0:A) s n = nth y0 s n`
2063 [
2064    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s'"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2065    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac));
2066 ];;
2067
2068 (* Lemma headI *)
2069 let headI = Sections.section_proof ["s";"x"]
2070 `rcons s x = headl x s :: behead (rcons s (x:A))`
2071 [
2072    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["s"]) THEN (move ["x"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("head", [head]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2073 ];;
2074 let incr_nth = define `incr_nth (n :: v') (SUC i) = n :: incr_nth v' i /\
2075         incr_nth (n :: v') 0 = SUC n :: v' /\
2076         incr_nth [] i = ncons i 0 [1]`;;
2077
2078 (* Lemma nth_incr_nth *)
2079 let nth_incr_nth = Sections.section_proof ["v";"i";"j"]
2080 `nth 0 (incr_nth v i) j = (if (i = j) then 1 else 0) + nth 0 v j`
2081 [
2082    (((THENL) (((use_arg_then2 ("j", [])) (disch_tac [])) THEN (clear_assumption "j") THEN ((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN ((use_arg_then2 ("v", [])) (disch_tac [])) THEN (clear_assumption "v") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["v"]) THEN (move ["IHv"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["i"]) THEN (move ["_"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["j"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("incr_nth", [incr_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("addn0", [addn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("eqS0", [eqS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("add1n", [add1n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2083    (arith_tac);
2084    (((THENL) (((use_arg_then2 ("j", [])) (disch_tac [])) THEN (clear_assumption "j") THEN ((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN elim) [ALL_TAC; ((move ["i"]) THEN (move ["IHv"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["j"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((TRY done_tac))));
2085    (arith_tac);
2086    (arith_tac);
2087    (((((use_arg_then2 ("IHv", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2088    (((((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`0 = SUC j`)])))) THEN (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2089    (((((use_arg_then2 ("IHv", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2090 ];;
2091
2092 (* Lemma size_incr_nth *)
2093 let size_incr_nth = Sections.section_proof ["v";"i"]
2094 `sizel (incr_nth v i) = if i < sizel v then sizel v else SUC i`
2095 [
2096    (((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN ((use_arg_then2 ("v", [])) (disch_tac [])) THEN (clear_assumption "v") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["v"]) THEN (move ["IHv"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["i"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("incr_nth", [incr_nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_ncons", [size_ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltS0", [ltS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
2097    (((((use_arg_then2 ("ONE", [ONE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("addn1", [addn1]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2098    ((((use_arg_then2 ("ltn0Sn", [ltn0Sn]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2099    ((((use_arg_then2 ("IHv", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))));
2100    (((use_arg_then2 ("fun_if", [fun_if])) (thm_tac apply_tac)) THEN (done_tac));
2101 ];;
2102
2103 (* Section PermSeq *)
2104 Sections.begin_section "PermSeq";;
2105 (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));;
2106 let same_count1 = new_definition `same_count1 s1 s2 x <=> (count (pred1 x) s1 = count (pred1 x) s2)`;;
2107 let perm_eq = new_definition `perm_eq s1 s2 = all (same_count1 s1 s2) (s1 ++ s2)`;;
2108
2109 (* Lemma perm_eqP *)
2110 let perm_eqP = Sections.section_proof ["s1";"s2"]
2111 `perm_eq s1 s2 <=> (!a. count a s1 = count a s2)`
2112 [
2113    ((THENL_LAST) (((((use_arg_then2 ("perm_eq", [perm_eq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("same_count1", [same_count1]))(thm_tac (new_rewrite [] []))))) THEN ((THENL) (split_tac) [((move ["eq_cnt1"]) THEN (move ["a"])); ((move ["eq_cnt"]) THEN (move ["x"]) THEN (move ["_"]))])) (exact_tac));
2114    ((((fun arg_tac -> (use_arg_then2 ("ltnSn", [ltnSn])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`count a (s1 ++ s2)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN ((use_arg_then2 ("a", [])) (disch_tac [1; 3; 4])) THEN (clear_assumption "a") THEN ((fun arg_tac -> arg_tac (Arg_term (`SUC _`))) (disch_tac [])) THEN elim) THEN (((repeat_tactic 0 10 (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (move ["n"]) THEN (move ["IHn"]) THEN (move ["a"]) THEN (move ["le_an"])));
2115    (((fun arg_tac -> (use_arg_then2 ("posnP", [posnP])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`count a (s1 ++ s2)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case);
2116    ((((((use_arg_then2 ("count_cat", [count_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn_eq0", [addn_eq0]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN ALL_TAC) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2117    ((((((use_arg_then2 ("has_count", [has_count]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ALL_TAC THEN (case THEN (move ["x"])) THEN (case THEN ((move ["s12x"]) THEN (move ["a_x"])))) THEN ((fun arg_tac -> arg_tac (Arg_term (`predD1 a x`))) (term_tac (set_tac "a'"))));
2118    ((fun arg_tac -> arg_tac (Arg_term (`!s. count a s = count (pred1 x) s + count a' s`))) (term_tac (have_gen_tac [](move ["cnt_a'"]))));
2119    (BETA_TAC THEN (move ["s"]));
2120    ((((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("count_predC", [count_predC])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`pred1 x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 2 0 (((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] []))))));
2121    ((repeat_tactic 1 9 (((use_arg_then2 ("filter_predI", [filter_predI]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("count_filter", [count_filter]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))));
2122    ((fun arg_tac -> arg_tac (Arg_term (`predI (\x'. ~pred1 x x') a = predD1 a x`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))));
2123    (((((use_arg_then2 ("predI", [predI]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predD1", [predD1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predD", [predD]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
2124    ((((use_arg_then2 ("a'_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqn_addr", [eqn_addr]))(thm_tac (new_rewrite [] [])))));
2125    ((((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("eq_count", [eq_count])) (disch_tac [])) THEN (clear_assumption "eq_count") THEN (DISCH_THEN apply_tac) THEN (move ["y"])) THEN ((((use_arg_then2 ("predI", [predI]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN ((THENL) (split_tac) [(case THEN ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) THEN (done_tac));
2126    ((repeat_tactic 1 9 (((use_arg_then2 ("cnt_a'", []))(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("eq_cnt1", [])) (fun fst_arg -> (use_arg_then2 ("s12x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("IHn", [])) (fun fst_arg -> (use_arg_then2 ("a'", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnS", [ltnS]))(gsym_then (thm_tac (new_rewrite [] []))))));
2127    ((((use_arg_then2 ("le_an", [])) (disch_tac [])) THEN (clear_assumption "le_an") THEN BETA_TAC) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leq_trans", [leq_trans])) (disch_tac [])) THEN (clear_assumption "leq_trans") THEN (DISCH_THEN apply_tac)));
2128    (((((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltnS", [ltnS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cnt_a'", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("add1n", [add1n]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leq_add2r", [leq_add2r]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ONE", [ONE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_count", [has_count]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_pred1", [has_pred1]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2129 ];;
2130
2131 (* Lemma perm_eq_refl *)
2132 let perm_eq_refl = Sections.section_proof ["s"]
2133 `perm_eq s s`
2134 [
2135    ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2136 ];;
2137
2138 (* Lemma perm_eq_sym *)
2139 let perm_eq_sym = Sections.section_proof []
2140 `!s1 s2. perm_eq s1 s2 = perm_eq s2 s1`
2141 [
2142    ((BETA_TAC THEN (move ["s1"]) THEN (move ["s2"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`!a. _ a`)]))))) THEN (done_tac));
2143 ];;
2144
2145 (* Lemma perm_eq_trans *)
2146 let perm_eq_trans = Sections.section_proof []
2147 `!s2 s1 s3. perm_eq s1 s2 ==> perm_eq s2 s3 ==> perm_eq s1 s3`
2148 [
2149    ((BETA_TAC THEN (move ["s2"]) THEN (move ["s1"]) THEN (move ["s3"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN (move ["eq12"]) THEN (move ["eq23"]) THEN (move ["a"])));
2150    (((((use_arg_then2 ("eq12", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq23", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2151 ];;
2152
2153 (* Lemma perm_eqlP *)
2154 let perm_eqlP = Sections.section_proof ["s1";"s2"]
2155 `perm_eq s1 s2 <=> (!s. perm_eq s1 s = perm_eq s2 s)`
2156 [
2157    ((THENL_LAST) ((THENL) (split_tac) [((move ["eq12"]) THEN (move ["s3"])); (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) ((((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
2158    ((THENL_LAST) (split_tac) (((use_arg_then2 ("perm_eq_trans", [perm_eq_trans])) (disch_tac [])) THEN (clear_assumption "perm_eq_trans") THEN (exact_tac)));
2159    ((repeat_tactic 1 9 (((fun arg_tac -> (use_arg_then2 ("perm_eq_sym", [perm_eq_sym])) (fun fst_arg -> (use_arg_then2 ("s3", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [(`perm_eq _ s3`)])))))) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("perm_eq_trans", [perm_eq_trans])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (DISCH_THEN apply_tac) THEN (done_tac));
2160 ];;
2161
2162 (* Lemma perm_eqrP *)
2163 let perm_eqrP = Sections.section_proof ["s1";"s2"]
2164 `perm_eq s1 s2 <=> (!s. perm_eq s s1 = perm_eq s s2)`
2165 [
2166    ((THENL_LAST) ((THENL) (split_tac) [ALL_TAC; (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))]) ((((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
2167    ((((use_arg_then2 ("perm_eqlP", [perm_eqlP]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq12"]) THEN (move ["s3"]));
2168    (((repeat_tactic 1 9 (((fun arg_tac -> (use_arg_then2 ("perm_eq_sym", [perm_eq_sym])) (fun fst_arg -> (use_arg_then2 ("s3", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [(`perm_eq s3 _`)]))))) THEN (((use_arg_then2 ("eq12", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2169 ];;
2170
2171 (* Lemma perm_catC *)
2172 let perm_catC = Sections.section_proof ["s1";"s2"]
2173 `!s. perm_eq (s1 ++ s2) s = perm_eq (s2 ++ s1) s`
2174 [
2175    ((((((use_arg_then2 ("perm_eqlP", [perm_eqlP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN (move ["a"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("count_cat", [count_cat]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("addnC", [addnC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2176 ];;
2177
2178 (* Lemma perm_cat2l *)
2179 let perm_cat2l = Sections.section_proof ["s1";"s2";"s3"]
2180 `perm_eq (s1 ++ s2) (s1 ++ s3) = perm_eq s2 s3`
2181 [
2182    ((repeat_tactic 1 9 (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN ((split_tac) THEN (move ["eq23"]) THEN (move ["a"])));
2183    ((((fun arg_tac -> (use_arg_then2 ("eq23", [])) (fun fst_arg -> (use_arg_then2 ("a", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("count_cat", [count_cat]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("eqn_addl", [eqn_addl]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2184    ((((fun arg_tac -> (use_arg_then2 ("eq23", [])) (fun fst_arg -> (use_arg_then2 ("a", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("count_cat", [count_cat]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("eqn_addl", [eqn_addl]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2185 ];;
2186
2187 (* Lemma perm_cons *)
2188 let perm_cons = Sections.section_proof ["x";"s1";"s2"]
2189 `perm_eq (x :: s1) (x :: s2) = perm_eq s1 s2`
2190 [
2191    ((((fun arg_tac -> (use_arg_then2 ("perm_cat2l", [perm_cat2l])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`[x]`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (((repeat_tactic 1 9 (((use_arg_then2 ("cat_cons", [cat_cons]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] [])))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2192 ];;
2193
2194 (* Lemma perm_cat2r *)
2195 let perm_cat2r = Sections.section_proof ["s1";"s2";"s3"]
2196 `perm_eq (s2 ++ s1) (s3 ++ s1) = perm_eq s2 s3`
2197 [
2198    ((repeat_tactic 2 0 (((((use_arg_then2 ("perm_eq_sym", [perm_eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_catC", [perm_catC]))(thm_tac (new_rewrite [] []))))))) THEN (((use_arg_then2 ("perm_cat2l", [perm_cat2l]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2199 ];;
2200
2201 (* Lemma perm_catAC *)
2202 let perm_catAC = Sections.section_proof ["s1";"s2";"s3"]
2203 `!s. perm_eq ((s1 ++ s2) ++ s3) s = perm_eq ((s1 ++ s3) ++ s2) s`
2204 [
2205    (((((use_arg_then2 ("perm_eqlP", [perm_eqlP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("catA", [catA]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("perm_cat2l", [perm_cat2l]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_catC", [perm_catC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2206 ];;
2207
2208 (* Lemma perm_catCA *)
2209 let perm_catCA = Sections.section_proof ["s1";"s2";"s3"]
2210 `!s. perm_eq (s1 ++ s2 ++ s3) s = perm_eq (s2 ++ s1 ++ s3) s`
2211 [
2212    (((((use_arg_then2 ("perm_eqlP", [perm_eqlP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("perm_cat2r", [perm_cat2r]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_catC", [perm_catC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2213 ];;
2214
2215 (* Lemma perm_rcons *)
2216 let perm_rcons = Sections.section_proof ["x";"s"]
2217 `!s2. perm_eq (rcons s x) s2 = perm_eq (x :: s) s2`
2218 [
2219    ((BETA_TAC THEN (move ["s2"])) THEN ((((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("perm_catC", [perm_catC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat1s", [cat1s]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2220 ];;
2221
2222 (* Lemma perm_rot *)
2223 let perm_rot = Sections.section_proof ["n";"s"]
2224 `!s2. perm_eq (rot n s) s2 = perm_eq s s2`
2225 [
2226    ((BETA_TAC THEN (move ["s2"])) THEN ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_catC", [perm_catC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2227 ];;
2228
2229 (* Lemma perm_rotr *)
2230 let perm_rotr = Sections.section_proof ["n";"s"]
2231 `!s2. perm_eq (rotr n s) s2 = perm_eq s s2`
2232 [
2233    (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_rot", [perm_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2234 ];;
2235
2236 (* Lemma perm_filterC *)
2237 let perm_filterC = Sections.section_proof ["a";"s"]
2238 `!s2. perm_eq (filter a s ++ filter (predC a) s) s2 = perm_eq s s2`
2239 [
2240    ((((use_arg_then2 ("perm_eqlP", [perm_eqlP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2241    ((((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("predC", [predC]))(gsym_then (thm_tac (new_rewrite [] []))))));
2242    (((THENL_LAST) (((fun arg_tac -> arg_tac (Arg_term (`a x`))) (disch_tac [])) THEN case THEN (simp_tac)) ((((use_arg_then2 ("cat1s", [cat1s]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("perm_catCA", [perm_catCA]))(thm_tac (new_rewrite [] [])))))) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("perm_cons", [perm_cons]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2243 ];;
2244
2245 (* Lemma perm_eq_mem *)
2246 let perm_eq_mem = Sections.section_proof ["s1";"s2"]
2247 `perm_eq s1 s2 ==> (!x. x <- s1 <=> x <- s2)`
2248 [
2249    (((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq12"]) THEN (move ["x"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] [])))))));
2250    ((((use_arg_then2 ("eq12", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2251 ];;
2252
2253 (* Lemma perm_eq_size *)
2254 let perm_eq_size = Sections.section_proof ["s1";"s2"]
2255 `perm_eq s1 s2 ==> sizel s1 = sizel s2`
2256 [
2257    ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq12"]));
2258    (((repeat_tactic 1 9 (((use_arg_then2 ("count_predT", [count_predT]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("eq12", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2259 ];;
2260
2261 (* Lemma uniq_leq_size *)
2262 let uniq_leq_size = Sections.section_proof ["s1";"s2"]
2263 `uniq s1 ==> (!x. x <- s1 ==> x <- s2) ==> sizel s1 <= sizel s2`
2264 [
2265    ((THENL) ((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) [(((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq0n", [leq0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (move ["_"]) THEN (case THEN ((move ["Hx"]) THEN (move ["Hs1"]) THEN (move ["Hs12"]))))]);
2266    ((((fun arg_tac -> (use_arg_then2 ("Hs12", [])) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (((((use_arg_then2 ("mem_head", [mem_head]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["Hxs2"])));
2267    (((fun arg_tac -> (use_arg_then2 ("rot_to", [rot_to])) (fun fst_arg -> (use_arg_then2 ("Hxs2", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC THEN (case THEN (move ["i"])) THEN (case THEN ((move ["s2'"]) THEN (move ["Ds2'"]))));
2268    (((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("size_rot", [size_rot])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s2", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [(`sizel s2`)]))))) THEN (((use_arg_then2 ("Ds2'", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hs1", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] []))))) THEN (move ["y"]) THEN (move ["Hy"]));
2269    ((((fun arg_tac -> (use_arg_then2 ("Hs12", [])) (fun fst_arg -> (use_arg_then2 ("y", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hy", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((fun arg_tac -> (use_arg_then2 ("mem_rot", [mem_rot])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("Ds2'", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))));
2270    ((case THEN ((TRY done_tac)) THEN (move ["yx"])) THEN (((use_arg_then2 ("Hy", [])) (disch_tac [])) THEN (clear_assumption "Hy") THEN ((use_arg_then2 ("Hx", [])) (disch_tac [])) THEN (clear_assumption "Hx") THEN BETA_TAC));
2271    (((((use_arg_then2 ("yx", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
2272 ];;
2273
2274 (* Lemma leq_size_uniq *)
2275 let leq_size_uniq = Sections.section_proof ["s1";"s2"]
2276 `uniq s1 ==> (!x. x <- s1 ==> x <- s2) ==> sizel s2 <= sizel s1 ==> uniq s2`
2277 [
2278    ((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [((move ["s2"]) THEN (move ["Hs1"]) THEN (move ["Hs12"])); ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]) THEN (move ["s2"]) THEN (move ["Hs1"]) THEN (move ["Hs12"]))]);
2279    (((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("nil_uniq", [nil_uniq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2280    ((((fun arg_tac -> (use_arg_then2 ("Hs12", [])) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (((((use_arg_then2 ("mem_head", [mem_head]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["Hxs2"])));
2281    (((fun arg_tac -> (use_arg_then2 ("rot_to", [rot_to])) (fun fst_arg -> (use_arg_then2 ("Hxs2", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC THEN (case THEN (move ["i"])) THEN (case THEN ((move ["s2'"]) THEN (move ["Ds2'"]))));
2282    (((((fun arg_tac -> (use_arg_then2 ("size_rot", [size_rot])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("rot_uniq", [rot_uniq])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("Ds2'", []))(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x <- s2'`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (move ["Hs2'"])));
2283    ((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hs2'", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((fun arg_tac -> (use_arg_then2 ("size_cons", [size_cons])) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))));
2284    (((fun arg_tac -> (use_arg_then2 ("uniq_leq_size", [uniq_leq_size])) (fun fst_arg -> (use_arg_then2 ("Hs1", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (DISCH_THEN apply_tac) THEN ((move ["y"]) THEN (move ["Hy"])));
2285    ((((fun arg_tac -> (use_arg_then2 ("Hs12", [])) (fun fst_arg -> (use_arg_then2 ("Hy", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((fun arg_tac -> (use_arg_then2 ("mem_rot", [mem_rot])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("Ds2'", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (case THEN ((TRY done_tac)) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2286    ((((use_arg_then2 ("Hs1", [])) (disch_tac [])) THEN (clear_assumption "Hs1") THEN BETA_TAC) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN ((move ["Hx"]) THEN (move ["Hs1"])))) THEN ((((use_arg_then2 ("Hs2'", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
2287    (((fun arg_tac -> (use_arg_then2 ("IHs", [])) (fun fst_arg -> (use_arg_then2 ("Hs1", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (DISCH_THEN apply_tac) THEN ((move ["y"]) THEN (move ["Hy"])));
2288    (((fun arg_tac -> (use_arg_then2 ("Hs12", [])) (fun fst_arg -> (use_arg_then2 ("y", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun arg -> thm_tac MP_TAC arg THEN ALL_TAC)) THEN ((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hy", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((fun arg_tac -> (use_arg_then2 ("mem_rot", [mem_rot])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("Ds2'", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (case THEN ((TRY done_tac)) THEN (move ["yx"])));
2289    ((((use_arg_then2 ("Hx", [])) (disch_tac [])) THEN (clear_assumption "Hx") THEN ((use_arg_then2 ("Hy", [])) (disch_tac [])) THEN (clear_assumption "Hy") THEN BETA_TAC) THEN ((((use_arg_then2 ("yx", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
2290 ];;
2291
2292 (* Lemma uniq_size_uniq *)
2293 let uniq_size_uniq = Sections.section_proof ["s1";"s2"]
2294 `uniq s1 ==> (!x. x <- s1 <=> x <- s2) ==> (uniq s2 = (sizel s2 = sizel s1))`
2295 [
2296    (BETA_TAC THEN (move ["Us1"]) THEN (move ["Es12"]));
2297    ((((use_arg_then2 ("eqn_leq", [eqn_leq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("uniq_leq_size", [uniq_leq_size]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("Us1", []))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("Es12", []))(thm_tac (new_rewrite [] []))))) THEN ((simp_tac THEN TRY done_tac)));
2298    ((THENL_FIRST) ((THENL) (split_tac) [(move ["Hs2"]); ALL_TAC]) (((((use_arg_then2 ("uniq_leq_size", [uniq_leq_size]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Es12", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac)));
2299    ((((use_arg_then2 ("leq_size_uniq", [leq_size_uniq])) (disch_tac [])) THEN (clear_assumption "leq_size_uniq") THEN (DISCH_THEN apply_tac)) THEN ((((use_arg_then2 ("Us1", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Es12", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2300 ];;
2301
2302 (* Lemma leq_size_perm *)
2303 let leq_size_perm = Sections.section_proof ["s1";"s2"]
2304 `uniq s1 ==> (!x. x <- s1 ==> x <- s2) ==> sizel s2 <= sizel s1 ==>
2305   (!x. x <- s1 <=> x <- s2) /\ sizel s1 = sizel s2`
2306 [
2307    ((BETA_TAC THEN (move ["Us1"]) THEN (move ["Hs1"]) THEN (move ["Hs12"])) THEN ((fun arg_tac -> arg_tac (Arg_term (`uniq s2`))) (term_tac (have_gen_tac [](move ["Us2"])))));
2308    ((((fun arg_tac -> (use_arg_then2 ("leq_size_uniq", [leq_size_uniq])) (fun fst_arg -> (use_arg_then2 ("Us1", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2309    (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`!x. x <- s1 <=> x <- s2`))) (term_tac (have_gen_tac []ALL_TAC))));
2310    ((BETA_TAC THEN (move ["h"])) THEN ((split_tac) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("uniq_size_uniq", [uniq_size_uniq]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac));
2311    (BETA_TAC THEN (move ["x"]));
2312    ((THENL) ((THENL) (split_tac) [ALL_TAC; (move ["Hxs2"])]) [((((use_arg_then2 ("Hs1", [])) (disch_tac [])) THEN (clear_assumption "Hs1") THEN (DISCH_THEN apply_tac)) THEN (done_tac)); (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x <- s1`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN ((TRY done_tac)) THEN (move ["Hxs1"]))]);
2313    (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`sizel (x :: s1) <= sizel s2`))) (term_tac (have_gen_tac []ALL_TAC))));
2314    (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hs12", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2315    ((THENL_FIRST) ((((use_arg_then2 ("uniq_leq_size", [uniq_leq_size])) (disch_tac [])) THEN (clear_assumption "uniq_leq_size") THEN (DISCH_THEN apply_tac)) THEN ((THENL) (split_tac) [ALL_TAC; (move ["y"])])) ((((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
2316    ((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN ((THENL) case [((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); (move ["Hy"])]) THEN (((use_arg_then2 ("Hs1", [])) (disch_tac [])) THEN (clear_assumption "Hs1") THEN (exact_tac)));
2317 ];;
2318
2319 (* Lemma perm_uniq *)
2320 let perm_uniq = Sections.section_proof ["s1";"s2"]
2321 `(!x. x <- s1 <=> x <- s2) ==> 
2322         sizel s1 = sizel s2 ==> uniq s1 = uniq s2`
2323 [
2324    ((BETA_TAC THEN (move ["Es12"]) THEN (move ["Hs12"])) THEN ((split_tac) THEN (move ["Us"])));
2325    (((((fun arg_tac -> (use_arg_then2 ("uniq_size_uniq", [uniq_size_uniq])) (fun fst_arg -> (use_arg_then2 ("Us", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("Hs12", []))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2326    (((((fun arg_tac -> (use_arg_then2 ("uniq_size_uniq", [uniq_size_uniq])) (fun fst_arg -> (use_arg_then2 ("Us", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("Hs12", []))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2327 ];;
2328
2329 (* Lemma perm_eq_uniq *)
2330 let perm_eq_uniq = Sections.section_proof ["s1";"s2"]
2331 `perm_eq s1 s2 ==> uniq s1 = uniq s2`
2332 [
2333    (((THENL) ((BETA_TAC THEN (move ["eq_s12"])) THEN (((use_arg_then2 ("perm_uniq", [perm_uniq])) (disch_tac [])) THEN (clear_assumption "perm_uniq") THEN (DISCH_THEN apply_tac)) THEN (split_tac)) [(((use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (disch_tac [])) THEN (clear_assumption "perm_eq_mem") THEN (exact_tac)); (((use_arg_then2 ("perm_eq_size", [perm_eq_size])) (disch_tac [])) THEN (clear_assumption "perm_eq_size") THEN (exact_tac))]) THEN (done_tac));
2334 ];;
2335
2336 (* Lemma uniq_perm_eq *)
2337 let uniq_perm_eq = Sections.section_proof ["s1";"s2"]
2338 `uniq s1 ==> uniq s2 ==> 
2339         (!x. x <- s1 <=> x <- s2) ==> perm_eq s1 s2`
2340 [
2341    ((BETA_TAC THEN (move ["Us1"]) THEN (move ["Us2"]) THEN (move ["eq12"])) THEN (((((use_arg_then2 ("perm_eq", [perm_eq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("same_count1", [same_count1]))(thm_tac (new_rewrite [] []))))) THEN (move ["x"]) THEN (move ["_"])));
2342    (((repeat_tactic 1 9 (((use_arg_then2 ("count_uniq_mem", [count_uniq_mem]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("eq12", []))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2343 ];;
2344
2345 (* Lemma count_mem_uniq *)
2346 let count_mem_uniq = Sections.section_proof ["s"]
2347 `(!x. count (pred1 x) s = if (x <- s) then 1 else 0) ==> uniq s`
2348 [
2349    ((BETA_TAC THEN (move ["count1_s"])) THEN ((fun arg_tac -> (use_arg_then2 ("undup_uniq", [undup_uniq])) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun arg -> thm_tac MP_TAC arg THEN (move ["Uus"]))));
2350    ((THENL_FIRST) (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`perm_eq s (undup s)`))) (term_tac (have_gen_tac []ALL_TAC)))) (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("perm_eq_uniq", [perm_eq_uniq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
2351    (((((use_arg_then2 ("perm_eq", [perm_eq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("same_count1", [same_count1]))(thm_tac (new_rewrite [] []))))) THEN (move ["x"]) THEN (move ["_"]));
2352    (((((fun arg_tac -> (fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("count_uniq_mem", [count_uniq_mem])) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("Uus", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_undup", [mem_undup]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2353 ];;
2354
2355 (* Finalization of the section PermSeq *)
2356 let perm_eqP = Sections.finalize_theorem perm_eqP;;
2357 let perm_eq_refl = Sections.finalize_theorem perm_eq_refl;;
2358 let perm_eq_sym = Sections.finalize_theorem perm_eq_sym;;
2359 let perm_eq_trans = Sections.finalize_theorem perm_eq_trans;;
2360 let perm_eqlP = Sections.finalize_theorem perm_eqlP;;
2361 let perm_eqrP = Sections.finalize_theorem perm_eqrP;;
2362 let perm_catC = Sections.finalize_theorem perm_catC;;
2363 let perm_cat2l = Sections.finalize_theorem perm_cat2l;;
2364 let perm_cons = Sections.finalize_theorem perm_cons;;
2365 let perm_cat2r = Sections.finalize_theorem perm_cat2r;;
2366 let perm_catAC = Sections.finalize_theorem perm_catAC;;
2367 let perm_catCA = Sections.finalize_theorem perm_catCA;;
2368 let perm_rcons = Sections.finalize_theorem perm_rcons;;
2369 let perm_rot = Sections.finalize_theorem perm_rot;;
2370 let perm_rotr = Sections.finalize_theorem perm_rotr;;
2371 let perm_filterC = Sections.finalize_theorem perm_filterC;;
2372 let perm_eq_mem = Sections.finalize_theorem perm_eq_mem;;
2373 let perm_eq_size = Sections.finalize_theorem perm_eq_size;;
2374 let uniq_leq_size = Sections.finalize_theorem uniq_leq_size;;
2375 let leq_size_uniq = Sections.finalize_theorem leq_size_uniq;;
2376 let uniq_size_uniq = Sections.finalize_theorem uniq_size_uniq;;
2377 let leq_size_perm = Sections.finalize_theorem leq_size_perm;;
2378 let perm_uniq = Sections.finalize_theorem perm_uniq;;
2379 let perm_eq_uniq = Sections.finalize_theorem perm_eq_uniq;;
2380 let uniq_perm_eq = Sections.finalize_theorem uniq_perm_eq;;
2381 let count_mem_uniq = Sections.finalize_theorem count_mem_uniq;;
2382 Sections.end_section "PermSeq";;
2383
2384 (* Section RotrLemmas *)
2385 Sections.begin_section "RotrLemmas";;
2386 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
2387 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
2388
2389 (* Lemma size_rotr *)
2390 let size_rotr = Sections.section_proof ["s"]
2391 `sizel (rotr n0 s) = sizel s`
2392 [
2393    (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2394 ];;
2395
2396 (* Lemma mem_rotr *)
2397 let mem_rotr = Sections.section_proof ["s"]
2398 `!x. x <- rotr n0 s <=> x <- s`
2399 [
2400    ((BETA_TAC THEN (move ["x"])) THEN ((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_rot", [mem_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2401 ];;
2402
2403 (* Lemma rotr_size_cat *)
2404 let rotr_size_cat = Sections.section_proof ["s1";"s2"]
2405 `rotr (sizel s2) (s1 ++ s2) = s2 ++ s1`
2406 [
2407    (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addnK", [addnK]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2408 ];;
2409
2410 (* Lemma rotr1_rcons *)
2411 let rotr1_rcons = Sections.section_proof ["x";"s"]
2412 `rotr 1 (rcons s x) = x :: s`
2413 [
2414    (((((use_arg_then2 ("rot1_cons", [rot1_cons]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rotK", [rotK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2415 ];;
2416
2417 (* Lemma has_rotr *)
2418 let has_rotr = Sections.section_proof ["a";"s"]
2419 `has a (rotr n0 s) = has a s`
2420 [
2421    (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_rot", [has_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2422 ];;
2423
2424 (* Lemma rotr_uniq *)
2425 let rotr_uniq = Sections.section_proof ["s"]
2426 `uniq (rotr n0 s) = uniq s`
2427 [
2428    (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_uniq", [rot_uniq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2429 ];;
2430
2431 (* Lemma rotrK *)
2432 let rotrK = Sections.section_proof []
2433 `!s. rot n0 (rotr n0 s) = s`
2434 [
2435    (BETA_TAC THEN (move ["s"]));
2436    ((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltnP", [ltnP])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun arg -> thm_tac MP_TAC arg THEN ((THENL) case [(move ["lt_n0s"]); (move ["ge_n0s"])])));
2437    (((((fun arg_tac -> (use_arg_then2 ("subKn", [subKn])) (fun fst_arg -> (fun arg_tac -> (use_arg_then2 ("ltnW", [ltnW])) (fun fst_arg -> (use_arg_then2 ("lt_n0s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN (((use_arg_then2 ("size_rotr", [size_rotr]))(gsym_then (thm_tac (new_rewrite [1] [(`sizel s`)]))))) THEN (((use_arg_then2 ("rotr", [rotr]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [(`rotr n0 _`)])))) THEN (((use_arg_then2 ("rotK", [rotK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2438    ((((fun arg_tac -> (use_arg_then2 ("rot_oversize", [rot_oversize])) (fun fst_arg -> (use_arg_then2 ("ge_n0s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [2] []))))) THEN (((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))));
2439    ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("subn_eq0", [subn_eq0])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("ge_n0s", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("rot0", [rot0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2440 ];;
2441
2442 (* Lemma rotr_inj *)
2443 let rotr_inj = Sections.section_proof ["s1";"s2"]
2444 `rotr n0 (s1:(A)list) = rotr n0 s2 ==> s1 = s2`
2445 [
2446    (BETA_TAC THEN (move ["h"]));
2447    (((((use_arg_then2 ("rotrK", [rotrK]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("h", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rotrK", [rotrK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2448 ];;
2449
2450 (* Lemma rev_rot *)
2451 let rev_rot = Sections.section_proof ["s"]
2452 `rev (rot n0 s) = rotr n0 (rev s)`
2453 [
2454    ((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rev", [size_rev]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [3] [(`s`)]))))) THEN (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("rev_cat", [rev_cat]))(thm_tac (new_rewrite [] []))))));
2455    (((((use_arg_then2 ("size_drop", [size_drop]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_rev", [size_rev]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2456 ];;
2457
2458 (* Lemma rev_rotr *)
2459 let rev_rotr = Sections.section_proof ["s"]
2460 `rev (rotr n0 s) = rot n0 (rev s)`
2461 [
2462    (((((use_arg_then2 ("rotrK", [rotrK]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rotrK", [rotrK]))(gsym_then (thm_tac (new_rewrite [] [(`rot n0 (rev s)`)])))))) THEN (AP_TERM_TAC) THEN (((use_arg_then2 ("rotK", [rotK]))(thm_tac (new_rewrite [] [])))));
2463    ((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rev", [size_rev]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rotr", [size_rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))));
2464    ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [(`rot _ s`)])))) THEN (((use_arg_then2 ("rev_cat", [rev_cat]))(thm_tac (new_rewrite [] [])))));
2465    ((fun arg_tac -> arg_tac (Arg_term (`sizel s - n0`))) (term_tac (set_tac "m")));
2466    ((THENL_ROT (-1)) (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("size_takel", [size_takel])) (fun fst_arg -> (use_arg_then2 ("m", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))));
2467    (((((use_arg_then2 ("size_rev", [size_rev]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rev_cat", [rev_cat]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2468    (((((use_arg_then2 ("m_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leq_subr", [leq_subr]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2469 ];;
2470
2471 (* Finalization of the section RotrLemmas *)
2472 let size_rotr = Sections.finalize_theorem size_rotr;;
2473 let mem_rotr = Sections.finalize_theorem mem_rotr;;
2474 let rotr_size_cat = Sections.finalize_theorem rotr_size_cat;;
2475 let rotr1_rcons = Sections.finalize_theorem rotr1_rcons;;
2476 let has_rotr = Sections.finalize_theorem has_rotr;;
2477 let rotr_uniq = Sections.finalize_theorem rotr_uniq;;
2478 let rotrK = Sections.finalize_theorem rotrK;;
2479 let rotr_inj = Sections.finalize_theorem rotr_inj;;
2480 let rev_rot = Sections.finalize_theorem rev_rot;;
2481 let rev_rotr = Sections.finalize_theorem rev_rotr;;
2482 Sections.end_section "RotrLemmas";;
2483
2484 (* Section RotCompLemmas *)
2485 Sections.begin_section "RotCompLemmas";;
2486 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
2487
2488 (* Lemma rot_addn *)
2489 let rot_addn = Sections.section_proof ["m";"n";"s"]
2490 `m + n <= sizel s ==> rot (m + n) s = rot m (rot n s)`
2491 [
2492    ((BETA_TAC THEN (move ["sz_s"])) THEN ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [(`take _ s`)])))))));
2493    ((((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(thm_tac (new_rewrite [] []))))));
2494    (((((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_takel", [size_takel]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("leq_addl", [leq_addl]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("addnK", [addnK]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2495 ];;
2496
2497 (* Lemma rotS *)
2498 let rotS = Sections.section_proof ["n";"s"]
2499 `n < sizel s ==> rot (SUC n) s = rot 1 (rot n s)`
2500 [
2501    ((((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("add1n", [add1n]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("rot_addn", [rot_addn])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN (done_tac));
2502 ];;
2503
2504 (* Lemma rot_add_mod *)
2505 let rot_add_mod = Sections.section_proof ["m";"n";"s"]
2506 `n <= sizel s ==> m <= sizel s ==>
2507   rot m (rot n s) = rot (if m + n <= sizel s then m + n else (m + n) - sizel s) s`
2508 [
2509    ((THENL) ((BETA_TAC THEN (move ["Hn"]) THEN (move ["Hm"])) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`m + n <= sizel s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac))) [((DISCH_THEN (fun snd_th -> (use_arg_then2 ("rot_addn", [rot_addn])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); BETA_TAC]);
2510    (((((use_arg_then2 ("ltnNge", [ltnNge]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("ltnW", [ltnW])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (move ["Hmn"])) THEN (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [])))));
2511    (((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("rotK", [rotK])) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [2] [(`s`)]))))) THEN (((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_addn", [rot_addn]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn_subA", [addn_subA]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("subnK", [subnK]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("addnK", [addnK]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2512 ];;
2513
2514 (* Lemma rot_rot *)
2515 let rot_rot = Sections.section_proof ["m";"n";"s"]
2516 `rot m (rot n s) = rot n (rot m s)`
2517 [
2518    (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltnP", [ltnP])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("m", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (move ["Hm"]));
2519    (((repeat_tactic 1 9 (((use_arg_then2 ("rot_oversize", [rot_oversize]))(thm_tac (new_rewrite [] [(`rot m _`)]))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 1 (((use_arg_then2 ("ltnW", [ltnW]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2520    (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltnP", [ltnP])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (move ["Hn"]));
2521    (((repeat_tactic 1 9 (((use_arg_then2 ("rot_oversize", [rot_oversize]))(thm_tac (new_rewrite [] [(`rot n _`)]))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 1 (((use_arg_then2 ("ltnW", [ltnW]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2522    (((repeat_tactic 1 9 (((use_arg_then2 ("rot_add_mod", [rot_add_mod]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 1 (((use_arg_then2 ("addnC", [addnC]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2523 ];;
2524
2525 (* Lemma rot_rotr *)
2526 let rot_rotr = Sections.section_proof ["m";"n";"s"]
2527 `rot m (rotr n s) = rotr n (rot m s)`
2528 [
2529    (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [(`rotr n (rot m s)`)])))) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_rot", [rot_rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rotr", [rotr]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2530 ];;
2531
2532 (* Lemma rotr_rotr *)
2533 let rotr_rotr = Sections.section_proof ["m";"n";"s"]
2534 `rotr m (rotr n s) = rotr n (rotr m s)`
2535 [
2536    (((repeat_tactic 1 9 (((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rot_rot", [rot_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2537 ];;
2538
2539 (* Finalization of the section RotCompLemmas *)
2540 let rot_addn = Sections.finalize_theorem rot_addn;;
2541 let rotS = Sections.finalize_theorem rotS;;
2542 let rot_add_mod = Sections.finalize_theorem rot_add_mod;;
2543 let rot_rot = Sections.finalize_theorem rot_rot;;
2544 let rot_rotr = Sections.finalize_theorem rot_rotr;;
2545 let rotr_rotr = Sections.finalize_theorem rotr_rotr;;
2546 Sections.end_section "RotCompLemmas";;
2547
2548 (* Section Mask *)
2549 Sections.begin_section "Mask";;
2550 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
2551 (Sections.add_section_type (mk_var ("m", (`:(bool)list`))));;
2552 (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));;
2553 let mask = define `mask [] s' = [] /\ mask m' [] = [] /\
2554         mask (b :: m') (x :: s') = if b then x :: mask m' s' else mask m' s'`;;
2555
2556 (* Lemma mask_false *)
2557 let mask_false = Sections.section_proof ["s";"n"]
2558 `mask (nseq n F) s = []`
2559 [
2560    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("ncons", [ncons]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("nseq", [nseq]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (done_tac));
2561 ];;
2562
2563 (* Lemma mask_true *)
2564 let mask_true = Sections.section_proof ["s";"n"]
2565 `sizel s <= n ==> mask (nseq n T) s = s`
2566 [
2567    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2568    ((((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ncons", [ncons]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nseq", [nseq]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2569 ];;
2570
2571 (* Lemma mask0 *)
2572 let mask0 = Sections.section_proof ["m"]
2573 `mask m [] = []`
2574 [
2575    (((THENL) (((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN elim) [ALL_TAC; ((move ["m"]) THEN (move ["_"]))]) THEN (((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
2576 ];;
2577
2578 (* Lemma mask1 *)
2579 let mask1 = Sections.section_proof ["b";"x"]
2580 `mask [b] [x] = nseq (if b then 1 else 0) x`
2581 [
2582    ((((use_arg_then2 ("b", [])) (disch_tac [])) THEN (clear_assumption "b") THEN case THEN (simp_tac)) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ONE", [ONE]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2583 ];;
2584
2585 (* Lemma mask_cons *)
2586 let mask_cons = Sections.section_proof ["b";"m";"x";"s"]
2587 `mask (b :: m) (x :: s) = nseq (if b then 1 else 0) x ++ mask m s`
2588 [
2589    ((((use_arg_then2 ("b", [])) (disch_tac [])) THEN (clear_assumption "b") THEN case) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ONE", [ONE]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("cat1s", [cat1s]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat0s", [cat0s]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2590 ];;
2591
2592 (* Lemma size_mask *)
2593 let size_mask = Sections.section_proof ["m";"s"]
2594 `sizel m = sizel s ==> sizel (mask m s) = count I m`
2595 [
2596    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN elim) [ALL_TAC; ((move ["b"]) THEN (move ["m"]) THEN (move ["IHm"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("eqS0", [eqS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("eqSS", [eqSS]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
2597    ((((use_arg_then2 ("I_THM", [I_THM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("b", [])) (disch_tac [])) THEN (clear_assumption "b") THEN case THEN (simp_tac) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHm", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("add1n", [add1n]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2598 ];;
2599
2600 (* Lemma mask_cat *)
2601 let mask_cat = Sections.section_proof ["m1";"s1";"m2";"s2"]
2602 `sizel m1 = sizel s1 ==>
2603        mask (m1 ++ m2) (s1 ++ s2) = mask m1 s1 ++ mask m2 s2`
2604 [
2605    (BETA_TAC THEN (move ["Hm1"]));
2606    (((THENL) (((use_arg_then2 ("Hm1", [])) (disch_tac [])) THEN (clear_assumption "Hm1") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN ((use_arg_then2 ("m1", [])) (disch_tac [])) THEN (clear_assumption "m1") THEN elim) [ALL_TAC; ((move ["b1"]) THEN (move ["m1"]) THEN (move ["IHm"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x1"]) THEN (move ["s1"]) THEN (move ["_"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("mask0", [mask0]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`0 = _`)]))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))));
2607    ((((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat_cons", [cat_cons]))(thm_tac (new_rewrite [] [])))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHm", [])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("b1", [])) (disch_tac [])) THEN (clear_assumption "b1") THEN case THEN (simp_tac)) THEN (((use_arg_then2 ("cat_cons", [cat_cons]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2608 ];;
2609
2610 (* Lemma has_mask_cons *)
2611 let has_mask_cons = Sections.section_proof ["a";"b";"m";"x";"s"]
2612 `has a (mask (b :: m) (x :: s)) <=> b /\ a x \/ has a (mask m s)`
2613 [
2614    ((((use_arg_then2 ("b", [])) (disch_tac [])) THEN (clear_assumption "b") THEN case) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2615 ];;
2616
2617 (* Lemma mask_rot *)
2618 let mask_rot = Sections.section_proof ["m";"s"]
2619 `sizel m = sizel s ==>
2620    mask (rot n0 m) (rot n0 s) = rot (count I (take n0 m)) (mask m s)`
2621 [
2622    (BETA_TAC THEN (move ["Hs"]));
2623    ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`sizel (take n0 m) = sizel (take n0 s)`))) (term_tac (have_gen_tac [](move ["Hsn0"])))) (((repeat_tactic 1 9 (((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("Hs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
2624    ((((fun arg_tac -> (use_arg_then2 ("size_mask", [size_mask])) (fun fst_arg -> (use_arg_then2 ("Hsn0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 2 0 (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mask_cat", [mask_cat]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("Hs", []))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)));
2625    ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("m", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [4] [(`m`)]))))) THEN (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [4] [(`s`)]))))) THEN (((use_arg_then2 ("mask_cat", [mask_cat]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)));
2626    ((((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2627 ];;
2628
2629 (* Finalization of the section Mask *)
2630 let mask_false = Sections.finalize_theorem mask_false;;
2631 let mask_true = Sections.finalize_theorem mask_true;;
2632 let mask0 = Sections.finalize_theorem mask0;;
2633 let mask1 = Sections.finalize_theorem mask1;;
2634 let mask_cons = Sections.finalize_theorem mask_cons;;
2635 let size_mask = Sections.finalize_theorem size_mask;;
2636 let mask_cat = Sections.finalize_theorem mask_cat;;
2637 let has_mask_cons = Sections.finalize_theorem has_mask_cons;;
2638 let mask_rot = Sections.finalize_theorem mask_rot;;
2639 Sections.end_section "Mask";;
2640
2641 (* Section EqMask *)
2642 Sections.begin_section "EqMask";;
2643 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
2644 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
2645 (Sections.add_section_type (mk_var ("m", (`:(bool)list`))));;
2646
2647 (* Lemma mem_mask_cons *)
2648 let mem_mask_cons = Sections.section_proof ["x";"b";"m";"y";"s"]
2649 `(x <- mask (b :: m) (y :: s)) <=> b /\ (x = y) \/ (x <- mask m s)`
2650 [
2651    ((((use_arg_then2 ("b", [])) (disch_tac [])) THEN (clear_assumption "b") THEN case) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("in_cons", [in_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2652 ];;
2653
2654 (* Lemma mem_mask *)
2655 let mem_mask = Sections.section_proof ["x";"m";"s"]
2656 `x <- mask m s ==> x <- s`
2657 [
2658    (((THENL) (((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["p"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["m"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))));
2659    ((((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN case THEN (simp_tac)) THEN (repeat_tactic 0 10 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> arg_tac (Arg_term (`x = y`))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"])) THEN (((use_arg_then2 ("IHs", [])) (disch_tac [])) THEN (clear_assumption "IHs") THEN (DISCH_THEN apply_tac)) THEN (done_tac));
2660 ];;
2661
2662 (* Lemma mask_uniq *)
2663 let mask_uniq = Sections.section_proof ["s"]
2664 `uniq s ==> !m. uniq (mask m s)`
2665 [
2666    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (((repeat_tactic 0 10 (((use_arg_then2 ("mask0", [mask0]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nil_uniq", [nil_uniq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("cons_uniq", [cons_uniq]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN ((move ["Hx"]) THEN (move ["Hs"])))) THEN ((THENL) elim [ALL_TAC; ((move ["b"]) THEN (move ["m"]) THEN (move ["_"]))]));
2667    (((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nil_uniq", [nil_uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2668    ((((use_arg_then2 ("b", [])) (disch_tac [])) THEN (clear_assumption "b") THEN case) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("IHs", [])) (fun fst_arg -> (use_arg_then2 ("Hs", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("m", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((simp_tac THEN TRY done_tac))));
2669    ((((use_arg_then2 ("Hx", [])) (disch_tac [])) THEN (clear_assumption "Hx") THEN BETA_TAC) THEN (((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("mem_mask", [mem_mask])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN (done_tac));
2670 ];;
2671
2672 (* Lemma mem_mask_rot *)
2673 let mem_mask_rot = Sections.section_proof ["m";"s"]
2674 `sizel m = sizel s ==>
2675   (!x. x <- mask (rot n0 m) (rot n0 s) <=> x <- mask m s)`
2676 [
2677    ((BETA_TAC THEN (move ["Hm"]) THEN (move ["x"])) THEN ((((use_arg_then2 ("mask_rot", [mask_rot]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("mem_rot", [mem_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2678 ];;
2679
2680 (* Finalization of the section EqMask *)
2681 let mem_mask_cons = Sections.finalize_theorem mem_mask_cons;;
2682 let mem_mask = Sections.finalize_theorem mem_mask;;
2683 let mask_uniq = Sections.finalize_theorem mask_uniq;;
2684 let mem_mask_rot = Sections.finalize_theorem mem_mask_rot;;
2685 Sections.end_section "EqMask";;
2686
2687 (* Section Subseq *)
2688 Sections.begin_section "Subseq";;
2689 (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));;
2690 let subseq = define `subseq (x :: s1) (y :: s2) = subseq (if x = y then s1 else x :: s1) s2 /\
2691         subseq [] s2 = T /\ subseq (x :: s1) [] = F`;;
2692
2693 (* Lemma sub0seq *)
2694 let sub0seq = Sections.section_proof ["s"]
2695 `subseq [] s`
2696 [
2697    ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
2698 ];;
2699
2700 (* Lemma subseq0 *)
2701 let subseq0 = Sections.section_proof ["s"]
2702 `subseq s [] = (s = [])`
2703 [
2704    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (done_tac));
2705 ];;
2706
2707 (* Lemma subseqP *)
2708 let subseqP = Sections.section_proof ["s1";"s2"]
2709 `subseq s1 s2 <=> (?m. sizel m = sizel s2 /\ s1 = mask m s2)`
2710 [
2711    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN ((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s2"]) THEN (move ["IHs2"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
2712    (((fun arg_tac -> arg_tac (Arg_term (`[]:(bool)list`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
2713    (((((use_arg_then2 ("NOT_EXISTS_THM", [NOT_EXISTS_THM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negb_and", [negb_and]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mask0", [mask0]))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
2714    (((fun arg_tac -> arg_tac (Arg_term (`nseq (SUC (sizel s2)) F`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("size_nseq", [size_nseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mask_false", [mask_false]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2715    ((((use_arg_then2 ("IHs2", []))(thm_tac (new_rewrite [] [])))) THEN ((split_tac) THEN ALL_TAC THEN (case THEN (move ["n"])) THEN (case THEN ((move ["sz_m"]) THEN (move ["def_s1"])))) THEN (((use_arg_then2 ("IHs2", [])) (disch_tac [])) THEN (clear_assumption "IHs2") THEN BETA_TAC THEN (move ["_"])));
2716    (((fun arg_tac -> arg_tac (Arg_term (`(x = y) :: n`))) (term_tac exists_tac)) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("sz_m", []))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((((use_arg_then2 ("def_s1", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)));
2717    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) THEN (done_tac));
2718    ((THENL_ROT (-1)) ((THENL) (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) [(BETA_TAC THEN (move ["_"])); (BETA_TAC THEN (move ["ne_xy"]))]));
2719    (((THENL) (((use_arg_then2 ("sz_m", [])) (disch_tac [])) THEN (clear_assumption "sz_m") THEN ((use_arg_then2 ("def_s1", [])) (disch_tac [])) THEN (clear_assumption "def_s1") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN case) [ALL_TAC; ((case THEN ALL_TAC) THEN (move ["m"]))]) THEN (((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (move ["eq"]) THEN (move ["seq"])));
2720    ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN BETA_TAC) THEN ((((use_arg_then2 ("eqseq_cons", [eqseq_cons]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (done_tac));
2721    (((use_arg_then2 ("m", [])) (term_tac exists_tac)) THEN (done_tac));
2722    ((fun arg_tac -> arg_tac (Arg_term (`indexl T n`))) (term_tac (set_tac "i")));
2723    ((fun arg_tac -> arg_tac (Arg_term (`take i n = nseq (sizel (take i n)) F`))) (term_tac (have_gen_tac [](move ["def_m_i"]))));
2724    (((((use_arg_then2 ("all_pred1P", [all_pred1P]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("all_nthP", [all_nthP])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`pred1 F`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`take i n`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`T`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (move ["j"]));
2725    (((((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("minn", [minn]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leq_minl", [leq_minl]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negb_or", [negb_or]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (case THEN (move ["lt_j_i"]) THEN (move ["_"])));
2726    ((((fun arg_tac -> (use_arg_then2 ("nth_take", [nth_take])) (fun fst_arg -> (use_arg_then2 ("lt_j_i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lt_j_i", [])) (disch_tac [])) THEN (clear_assumption "lt_j_i") THEN BETA_TAC) THEN (((((use_arg_then2 ("i_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("before_find", [before_find])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN ((fun arg_tac ->  (conv_thm_tac DISCH_THEN)  (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`T`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac MP_TAC))));
2727    (((repeat_tactic 1 9 (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (done_tac));
2728    ((fun arg_tac -> arg_tac (Arg_term (`i < sizel n`))) (term_tac (have_gen_tac [](move ["lt_i_m"]))));
2729    ((((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN ((((fun arg_tac -> arg_tac (Arg_theorem (TAUT `!P. (P ==> F) <=> ~P`)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (move ["le_m_i"])));
2730    ((((use_arg_then2 ("def_s1", [])) (disch_tac [])) THEN (clear_assumption "def_s1") THEN ((use_arg_then2 ("def_m_i", [])) (disch_tac [])) THEN (clear_assumption "def_m_i") THEN BETA_TAC) THEN (((((use_arg_then2 ("take_oversize", [take_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mask_false", [mask_false]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2731    ((((use_arg_then2 ("def_m_i", [])) (disch_tac [])) THEN (clear_assumption "def_m_i") THEN BETA_TAC) THEN (((((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lt_i_m", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["def_m_i"])));
2732    (((fun arg_tac -> arg_tac (Arg_term (`take i n ++ dropl (SUC i) n`))) (term_tac exists_tac)) THEN (split_tac));
2733    ((((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lt_i_m", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac));
2734    ((((use_arg_then2 ("lt_i_m", [])) (disch_tac [])) THEN (clear_assumption "lt_i_m") THEN BETA_TAC) THEN (((((use_arg_then2 ("sz_m", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("subnKC", [subnKC])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN ((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addSn", [addSn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2735    ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("congr1", [congr1])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`behead`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("def_s1", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))));
2736    ((((fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [(`s2`)]))))) THEN (((fun arg_tac -> (use_arg_then2 ("cat_take_drop", [cat_take_drop])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] [(`n`)]))))) THEN (((use_arg_then2 ("def_m_i", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat_cons", [cat_cons]))(gsym_then (thm_tac (new_rewrite [] []))))));
2737    ((fun arg_tac -> arg_tac (Arg_term (`sizel (take i s2) = i`))) (term_tac (have_gen_tac [](move ["sz_i_s2"]))));
2738    ((((use_arg_then2 ("size_takel", [size_takel])) (disch_tac [])) THEN (clear_assumption "size_takel") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("lt_i_m", [])) (disch_tac [])) THEN (clear_assumption "lt_i_m") THEN BETA_TAC) THEN ((((use_arg_then2 ("sz_m", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2739    ((((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat_rcons", [cat_rcons]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("mask_cat", [mask_cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_nseq", [size_nseq]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_belast", [size_belast]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("mask_false", [mask_false]))(thm_tac (new_rewrite [] []))))) THEN ((simp_tac THEN TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] []))))));
2740    ((((fun arg_tac -> (use_arg_then2 ("drop_nth", [drop_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`T`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("i_def", []))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("i_def", []))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)));
2741    (((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2742 ];;
2743
2744 (* Lemma subseq_trans *)
2745 let subseq_trans = Sections.section_proof ["s1";"s2";"s3"]
2746 `subseq s1 s2 ==> subseq s2 s3 ==> subseq s1 s3`
2747 [
2748    (((((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["m2"])) THEN (case THEN ((move ["_"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) THEN ((((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["m1"])) THEN (case THEN ((move ["_"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))));
2749    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("m1", [])) (disch_tac [])) THEN (clear_assumption "m1") THEN ((use_arg_then2 ("m2", [])) (disch_tac [])) THEN (clear_assumption "m2") THEN ((use_arg_then2 ("s3", [])) (disch_tac [])) THEN (clear_assumption "s3") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) (((repeat_tactic 1 9 (((use_arg_then2 ("mask0", [mask0]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("subseq0", [subseq0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
2750    (BETA_TAC THEN (move ["m2"]) THEN (move ["m1"]));
2751    (((THENL) (((use_arg_then2 ("m1", [])) (disch_tac [])) THEN (clear_assumption "m1") THEN case) [ALL_TAC; ((case THEN ALL_TAC) THEN (move ["m1"]))]) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("mask0", [mask0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2752    (((THENL) (((use_arg_then2 ("m2", [])) (disch_tac [])) THEN (clear_assumption "m2") THEN case) [ALL_TAC; ((case THEN ALL_TAC) THEN (move ["m2"]))]) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("IHs", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2753    ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("IHs", [])) (fun fst_arg -> (use_arg_then2 ("m2", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("m1", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (move ["m"])) THEN (case THEN ((move ["sz_m"]) THEN (move ["def_s"])))));
2754    (((fun arg_tac -> arg_tac (Arg_term (`F :: m`))) (term_tac exists_tac)) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("sz_m", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("def_s", []))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
2755    ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("IHs", [])) (fun fst_arg -> (use_arg_then2 ("m2", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("m1", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (move ["m"])) THEN (case THEN ((move ["sz_m"]) THEN (move ["def_s"])))));
2756    (((fun arg_tac -> arg_tac (Arg_term (`F :: m`))) (term_tac exists_tac)) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("sz_m", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("def_s", []))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
2757 ];;
2758
2759 (* Lemma subseq_refl *)
2760 let subseq_refl = Sections.section_proof ["s"]
2761 `subseq s s`
2762 [
2763    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
2764 ];;
2765
2766 (* Lemma subseq_cat *)
2767 let subseq_cat = Sections.section_proof ["s1";"s2";"s3";"s4"]
2768 `subseq s1 s3 ==> subseq s2 s4 ==> subseq (s1 ++ s2) (s3 ++ s4)`
2769 [
2770    ((repeat_tactic 1 9 (((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (move ["m1"])) THEN (case THEN ((move ["sz_m1"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))) THEN (case THEN (move ["m2"])) THEN (case THEN ((move ["sz_m2"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))));
2771    (((fun arg_tac -> arg_tac (Arg_term (`m1 ++ m2`))) (term_tac exists_tac)) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("mask_cat", [mask_cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("sz_m1", []))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("sz_m2", []))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2772 ];;
2773
2774 (* Lemma mem_subseq *)
2775 let mem_subseq = Sections.section_proof ["s1";"s2"]
2776 `subseq s1 s2 ==> (!x. x <- s1 ==> x <- s2)`
2777 [
2778    (((((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["m"])) THEN (case THEN ((move ["_"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))) THEN (move ["x"])) THEN (((use_arg_then2 ("mem_mask", [mem_mask])) (disch_tac [])) THEN (clear_assumption "mem_mask") THEN (DISCH_THEN apply_tac)) THEN (done_tac));
2779 ];;
2780
2781 (* Lemma subseq_seq1 *)
2782 let subseq_seq1 = Sections.section_proof ["x";"s"]
2783 `subseq [x] s <=> x <- s`
2784 [
2785    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))));
2786    ((((fun arg_tac -> (use_arg_then2 ("orbN", [orbN])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) THEN ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
2787 ];;
2788
2789 (* Lemma size_subseq *)
2790 let size_subseq = Sections.section_proof ["s1";"s2"]
2791 `subseq s1 s2 ==> sizel s1 <= sizel s2`
2792 [
2793    ((((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["m"])) THEN (case THEN ((move ["sz_m"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))));
2794    (((((use_arg_then2 ("size_mask", [size_mask]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("sz_m", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("count_size", [count_size]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2795 ];;
2796
2797 (* Lemma size_subseq_leqif *)
2798 let size_subseq_leqif = Sections.section_proof ["s1";"s2"]
2799 `subseq s1 s2 ==> leqif (sizel s1) (sizel s2) (s1 = s2)`
2800 [
2801    ((THENL_FIRST) ((BETA_TAC THEN (move ["sub12"])) THEN (((use_arg_then2 ("leqif", [leqif]))(thm_tac (new_rewrite [] [])))) THEN (split_tac)) (((use_arg_then2 ("size_subseq", [size_subseq])) (disch_tac [])) THEN (clear_assumption "size_subseq") THEN (exact_tac)));
2802    (((THENL) (split_tac) [ALL_TAC; ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))]) THEN (((use_arg_then2 ("sub12", [])) (disch_tac [])) THEN (clear_assumption "sub12") THEN BETA_TAC) THEN ((((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["m"])) THEN (case THEN ((move ["sz_m"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))));
2803    ((((use_arg_then2 ("size_mask", [size_mask]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("sz_m", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("all_count", [all_count]))(gsym_then (thm_tac (new_rewrite [] []))))));
2804    ((fun arg_tac -> arg_tac (Arg_term (`all I m = all (pred1 T) m`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))));
2805    (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("eq_all", [eq_all])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`I:bool->bool`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`pred1 T`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC);
2806    (((((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("I_THM", [I_THM]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
2807    (((((use_arg_then2 ("all_pred1P", [all_pred1P]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("sz_m", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mask_true", [mask_true]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
2808 ];;
2809
2810 (* Lemma subseq_cons *)
2811 let subseq_cons = Sections.section_proof ["s";"x"]
2812 `subseq s (x :: s)`
2813 [
2814    (((fun arg_tac -> (fun arg_tac -> (fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("subseq_cat", [subseq_cat])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`[]`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`[x]`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC);
2815    (((((use_arg_then2 ("subseq_refl", [subseq_refl]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat0s", [cat0s]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat1s", [cat1s]))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
2816 ];;
2817
2818 (* Lemma subseq_rcons *)
2819 let subseq_rcons = Sections.section_proof ["s";"x"]
2820 `subseq s (rcons s x)`
2821 [
2822    (((((use_arg_then2 ("cats0", [cats0]))(gsym_then (thm_tac (new_rewrite [1] [(`s`)]))))) THEN (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("subseq_cat", [subseq_cat]))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("subseq_refl", [subseq_refl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (done_tac));
2823 ];;
2824
2825 (* Lemma subseq_uniq *)
2826 let subseq_uniq = Sections.section_proof ["s1";"s2"]
2827 `subseq s1 s2 ==> uniq s2 ==> uniq s1`
2828 [
2829    (((((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["m"])) THEN (case THEN ((move ["_"]) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))) THEN (move ["Us2"])) THEN (((use_arg_then2 ("mask_uniq", [mask_uniq]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2830 ];;
2831
2832 (* Finalization of the section Subseq *)
2833 let sub0seq = Sections.finalize_theorem sub0seq;;
2834 let subseq0 = Sections.finalize_theorem subseq0;;
2835 let subseqP = Sections.finalize_theorem subseqP;;
2836 let subseq_trans = Sections.finalize_theorem subseq_trans;;
2837 let subseq_refl = Sections.finalize_theorem subseq_refl;;
2838 let subseq_cat = Sections.finalize_theorem subseq_cat;;
2839 let mem_subseq = Sections.finalize_theorem mem_subseq;;
2840 let subseq_seq1 = Sections.finalize_theorem subseq_seq1;;
2841 let size_subseq = Sections.finalize_theorem size_subseq;;
2842 let size_subseq_leqif = Sections.finalize_theorem size_subseq_leqif;;
2843 let subseq_cons = Sections.finalize_theorem subseq_cons;;
2844 let subseq_rcons = Sections.finalize_theorem subseq_rcons;;
2845 let subseq_uniq = Sections.finalize_theorem subseq_uniq;;
2846 Sections.end_section "Subseq";;
2847
2848 (* Section Map *)
2849 Sections.begin_section "Map";;
2850 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
2851 (Sections.add_section_var (mk_var ("x1", (`:A`))));;
2852 (Sections.add_section_var (mk_var ("x2", (`:B`))));;
2853 (Sections.add_section_var (mk_var ("f", (`:A -> B`))));;
2854 let map = define `map f (x :: s) = f x :: map f s /\ map f [] = []`;;
2855
2856 (* Lemma map_MAP *)
2857 let map_MAP = Sections.section_proof []
2858 `map = MAP`
2859 [
2860    ((((use_arg_then2 ("EQ_EXT", [EQ_EXT])) (thm_tac apply_tac)) THEN (move ["f"])) THEN (((use_arg_then2 ("EQ_EXT", [EQ_EXT])) (thm_tac apply_tac)) THEN (move ["s"])));
2861    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("MAP", [MAP]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2862 ];;
2863
2864 (* Lemma map_cons *)
2865 let map_cons = Sections.section_proof ["x";"s"]
2866 `map f (x :: s) = f x :: map f s`
2867 [
2868    ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
2869 ];;
2870
2871 (* Lemma map_nseq *)
2872 let map_nseq = Sections.section_proof ["x"]
2873 `map f (nseq n0 x) = nseq n0 (f x)`
2874 [
2875    (((THENL) (((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ncons", [ncons]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("nseq", [nseq]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))));
2876    ((((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2877 ];;
2878
2879 (* Lemma map_cat *)
2880 let map_cat = Sections.section_proof ["s1";"s2"]
2881 `map f (s1 ++ s2) = map f s1 ++ map f s2`
2882 [
2883    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (done_tac));
2884 ];;
2885
2886 (* Lemma size_map *)
2887 let size_map = Sections.section_proof ["s"]
2888 `sizel (map f s) = sizel s`
2889 [
2890    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
2891    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2892 ];;
2893
2894 (* Lemma behead_map *)
2895 let behead_map = Sections.section_proof ["s"]
2896 `behead (map f s) = map f (behead s)`
2897 [
2898    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("behead", [behead]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2899 ];;
2900
2901 (* Lemma nth_map *)
2902 let nth_map = Sections.section_proof ["n";"s"]
2903 `n < sizel s ==> nth x2 (map f s) n = f (nth x1 s n)`
2904 [
2905    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltS0", [ltS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2906    ((((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN (done_tac));
2907 ];;
2908
2909 (* Lemma map_rcons *)
2910 let map_rcons = Sections.section_proof ["s";"x"]
2911 `map f (rcons s x) = rcons (map f s) (f x)`
2912 [
2913    (((repeat_tactic 1 9 (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("map_cat", [map_cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2914 ];;
2915
2916 (* Lemma last_map *)
2917 let last_map = Sections.section_proof ["s";"x"]
2918 `last (f x) (map f s) = f (last x s)`
2919 [
2920    (((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2921 ];;
2922
2923 (* Lemma belast_map *)
2924 let belast_map = Sections.section_proof ["s";"x"]
2925 `belast (f x) (map f s) = map f (belast x s)`
2926 [
2927    (((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]) THEN (move ["x"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("belast", [belast]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (done_tac));
2928 ];;
2929 let preim = new_definition `preim (f:A->B) (a:B->bool) = (\x. a (f x))`;;
2930
2931 (* Lemma filter_map *)
2932 let filter_map = Sections.section_proof ["a";"s"]
2933 `filter a (map f s) = map f (filter (preim f a) s)`
2934 [
2935    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2936    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac));
2937    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`a (f x)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["_"])) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
2938 ];;
2939
2940 (* Lemma find_map *)
2941 let find_map = Sections.section_proof ["a";"s"]
2942 `find a (map f s) = find (preim f a) s`
2943 [
2944    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2945    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2946 ];;
2947
2948 (* Lemma has_map *)
2949 let has_map = Sections.section_proof ["a";"s"]
2950 `has a (map f s) = has (preim f a) s`
2951 [
2952    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2953    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2954 ];;
2955
2956 (* Lemma all_map *)
2957 let all_map = Sections.section_proof ["a";"s"]
2958 `all a (map f s) = all (preim f a) s`
2959 [
2960    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2961    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2962 ];;
2963
2964 (* Lemma count_map *)
2965 let count_map = Sections.section_proof ["a";"s"]
2966 `count a (map f s) = count (preim f a) s`
2967 [
2968    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
2969    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2970 ];;
2971
2972 (* Lemma map_take *)
2973 let map_take = Sections.section_proof ["s"]
2974 `map f (take n0 s) = take n0 (map f s)`
2975 [
2976    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2977 ];;
2978
2979 (* Lemma map_drop *)
2980 let map_drop = Sections.section_proof ["s"]
2981 `map f (dropl n0 s) = dropl n0 (map f s)`
2982 [
2983    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("n0", [])) (disch_tac [])) THEN (clear_assumption "n0") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
2984 ];;
2985
2986 (* Lemma map_rot *)
2987 let map_rot = Sections.section_proof ["s"]
2988 `map f (rot n0 s) = rot n0 (map f s)`
2989 [
2990    (((repeat_tactic 1 9 (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("map_cat", [map_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("map_take", [map_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("map_drop", [map_drop]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2991 ];;
2992
2993 (* Lemma map_rotr *)
2994 let map_rotr = Sections.section_proof ["s"]
2995 `map f (rotr n0 s) = rotr n0 (map f s)`
2996 [
2997    (((fun arg_tac -> (use_arg_then2 ("rot_inj", [rot_inj])) (fun fst_arg -> (use_arg_then2 ("n0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac apply_tac)) THEN ((((use_arg_then2 ("rotrK", [rotrK]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("map_rot", [map_rot]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("rotrK", [rotrK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
2998 ];;
2999
3000 (* Lemma map_rev *)
3001 let map_rev = Sections.section_proof ["s"]
3002 `map f (rev s) = rev (map f s)`
3003 [
3004    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("rev_cons", [rev_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map_rcons", [map_rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("rev", [rev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3005 ];;
3006
3007 (* Lemma map_mask *)
3008 let map_mask = Sections.section_proof ["m";"s"]
3009 `map f (mask m s) = mask m (map f s)`
3010 [
3011    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN elim) [ALL_TAC; ((case THEN ALL_TAC) THEN (move ["m"]) THEN (move ["IHm"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["p"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3012    (((((use_arg_then2 ("map_cons", [map_cons]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("IHm", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3013 ];;
3014
3015 (* Lemma inj_map *)
3016 let inj_map = Sections.section_proof []
3017 `(!x y. f x = f y ==> x = y) ==> (!s1 s2. map f s1 = map f s2 ==> s1 = s2)`
3018 [
3019    ((BETA_TAC THEN (move ["injf"])) THEN ((THENL) elim [ALL_TAC; ((move ["y1"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y2"]) THEN (move ["s2"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`[] = CONS _1 _2`)]))))) THEN ((((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3020    (((((use_arg_then2 ("eqseq_cons", [eqseq_cons]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("injf", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) THEN (done_tac));
3021 ];;
3022
3023 (* Finalization of the section Map *)
3024 let map_MAP = Sections.finalize_theorem map_MAP;;
3025 let map_cons = Sections.finalize_theorem map_cons;;
3026 let map_nseq = Sections.finalize_theorem map_nseq;;
3027 let map_cat = Sections.finalize_theorem map_cat;;
3028 let size_map = Sections.finalize_theorem size_map;;
3029 let behead_map = Sections.finalize_theorem behead_map;;
3030 let nth_map = Sections.finalize_theorem nth_map;;
3031 let map_rcons = Sections.finalize_theorem map_rcons;;
3032 let last_map = Sections.finalize_theorem last_map;;
3033 let belast_map = Sections.finalize_theorem belast_map;;
3034 let filter_map = Sections.finalize_theorem filter_map;;
3035 let find_map = Sections.finalize_theorem find_map;;
3036 let has_map = Sections.finalize_theorem has_map;;
3037 let all_map = Sections.finalize_theorem all_map;;
3038 let count_map = Sections.finalize_theorem count_map;;
3039 let map_take = Sections.finalize_theorem map_take;;
3040 let map_drop = Sections.finalize_theorem map_drop;;
3041 let map_rot = Sections.finalize_theorem map_rot;;
3042 let map_rotr = Sections.finalize_theorem map_rotr;;
3043 let map_rev = Sections.finalize_theorem map_rev;;
3044 let map_mask = Sections.finalize_theorem map_mask;;
3045 let inj_map = Sections.finalize_theorem inj_map;;
3046 Sections.end_section "Map";;
3047
3048 (* Lemma filter_mask *)
3049 let filter_mask = Sections.section_proof ["a";"s"]
3050 `filter (a:A->bool) s = mask (map a s) s`
3051 [
3052    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3053    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`a x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac)) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN ((((use_arg_then2 ("mask", [mask]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)) THEN (done_tac));
3054 ];;
3055
3056 (* Section FilterSubseq *)
3057 Sections.begin_section "FilterSubseq";;
3058 (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));;
3059 (Sections.add_section_type (mk_var ("a", (`:A -> bool`))));;
3060
3061 (* Lemma filter_subseq *)
3062 let filter_subseq = Sections.section_proof ["a";"s"]
3063 `subseq (filter a s) s`
3064 [
3065    ((((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] [])))) THEN ((fun arg_tac -> arg_tac (Arg_term (`map a s`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("size_map", [size_map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("filter_mask", [filter_mask]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3066 ];;
3067
3068 (* Lemma subseq_filter *)
3069 let subseq_filter = Sections.section_proof ["s1";"s2";"a"]
3070 `subseq s1 (filter a s2) <=> all a s1 /\ subseq s1 s2`
3071 [
3072    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN ((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s2"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y"]) THEN (move ["s1"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((TRY done_tac))));
3073    ((((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`a x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["ax"])) THEN (((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`y = x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["yx"])) THEN ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("all_cons", [all_cons]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3074 ];;
3075
3076 (* Lemma subseq_uniqP *)
3077 let subseq_uniqP = Sections.section_proof ["s1";"s2"]
3078 `uniq s2 ==> (subseq s1 s2 <=> s1 = filter (\x. x <- s1) s2)`
3079 [
3080    ((THENL_LAST) ((BETA_TAC THEN (move ["uniq_s2"])) THEN ((THENL) (split_tac) [(move ["ss12"]); (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))])) ((((use_arg_then2 ("filter_subseq", [filter_subseq]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
3081    ((fun arg_tac -> arg_tac (Arg_term (`subseq s1 (filter (\x. x <- s1) s2)`))) (term_tac (have_gen_tac []ALL_TAC)));
3082    (((((use_arg_then2 ("subseq_filter", [subseq_filter]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3083    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("size_subseq_leqif", [size_subseq_leqif])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("leqif_imp_eq", [leqif_imp_eq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))));
3084    ((((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_eq_size", [perm_eq_size])) (disch_tac [])) THEN (clear_assumption "perm_eq_size") THEN (DISCH_THEN apply_tac)));
3085    ((((use_arg_then2 ("uniq_perm_eq", [uniq_perm_eq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("filter_uniq", [filter_uniq]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("subseq_uniq", [subseq_uniq])) (fun fst_arg -> (use_arg_then2 ("ss12", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)));
3086    ((((((use_arg_then2 ("mem_filter", [mem_filter]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["x"])) THEN ((((use_arg_then2 ("andb_idr", [andb_idr]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((fun arg_tac -> (use_arg_then2 ("mem_subseq", [mem_subseq])) (fun fst_arg -> (use_arg_then2 ("ss12", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (DISCH_THEN apply_tac)) THEN (done_tac));
3087 ];;
3088
3089 (* Finalization of the section FilterSubseq *)
3090 let filter_subseq = Sections.finalize_theorem filter_subseq;;
3091 let subseq_filter = Sections.finalize_theorem subseq_filter;;
3092 let subseq_uniqP = Sections.finalize_theorem subseq_uniqP;;
3093 Sections.end_section "FilterSubseq";;
3094
3095 (* Section EqMap *)
3096 Sections.begin_section "EqMap";;
3097 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
3098 (Sections.add_section_var (mk_var ("x1", (`:A`))));;
3099 (Sections.add_section_var (mk_var ("x2", (`:B`))));;
3100 (Sections.add_section_var (mk_var ("f", (`:A -> B`))));;
3101 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
3102
3103 (* Lemma map_f *)
3104 let map_f = Sections.section_proof ["s";"x"]
3105 `x <- s ==> f x <- map f s`
3106 [
3107    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_cons", [in_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3108    (((THENL) case [((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); (move ["Hx"])]) THEN (DISJ2_TAC) THEN (((use_arg_then2 ("IHs", [])) (disch_tac [])) THEN (clear_assumption "IHs") THEN (DISCH_THEN apply_tac)) THEN (done_tac));
3109 ];;
3110
3111 (* Lemma mapP *)
3112 let mapP = Sections.section_proof ["s";"y"]
3113 `(y <- map f s) <=> (?x. x <- s /\ y = f x)`
3114 [
3115    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("andFb", [andFb]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3116    (((((use_arg_then2 ("NOT_EXISTS_THM", [NOT_EXISTS_THM]))(thm_tac (new_rewrite [] [])))) THEN (move ["x"])) THEN (done_tac));
3117    ((repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`y = f x`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["Hxy"])));
3118    (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac));
3119    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN ((THENL) (split_tac) [(case THEN ((move ["x'"]) THEN (case THEN ((move ["Hx'"]) THEN (move ["eq"]))))); (case THEN ((move ["x'"]) THEN (case THEN ((move ["Hx'"]) THEN (move ["Dy"])))))]));
3120    (((use_arg_then2 ("x'", [])) (term_tac exists_tac)) THEN (done_tac));
3121    ((THENL) (((use_arg_then2 ("Hx'", [])) (disch_tac [])) THEN (clear_assumption "Hx'") THEN case THEN (move ["Hx'"])) [BETA_TAC; (((use_arg_then2 ("x'", [])) (term_tac exists_tac)) THEN ((TRY done_tac)))]);
3122    (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("Hxy", [])) (disch_tac [])) THEN (clear_assumption "Hxy") THEN BETA_TAC) THEN ((((use_arg_then2 ("Dy", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hx'", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3123 ];;
3124
3125 (* Lemma map_uniq *)
3126 let map_uniq = Sections.section_proof ["s"]
3127 `uniq (map f s) ==> uniq s`
3128 [
3129    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN ALL_TAC THEN (case THEN (move ["not_sfx"]))));
3130    (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("andbT", [andbT]))(thm_tac (new_rewrite [] [])))));
3131    ((((use_arg_then2 ("not_sfx", [])) (disch_tac [])) THEN (clear_assumption "not_sfx") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (move ["sx"])) THEN (((use_arg_then2 ("mapP", [mapP]))(thm_tac (new_rewrite [] [])))) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac));
3132 ];;
3133
3134 (* Lemma map_inj_in_uniq *)
3135 let map_inj_in_uniq = Sections.section_proof ["s"]
3136 `(!x y. x <- s ==> y <- s ==> (f x = f y ==> x = y)) ==>
3137         uniq (map f s) = uniq s`
3138 [
3139    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (((((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN (move ["injf"])));
3140    (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))));
3141    (BETA_TAC THEN (move ["a"]) THEN (move ["b"]) THEN (case THEN ((case THEN ((move ["Ha"]) THEN (move ["Hb"]))) THEN (move ["fab"]))));
3142    ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("injf", [])) (fun fst_arg -> (use_arg_then2 ("a", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("b", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("Ha", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hb", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("fab", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3143    ((congr_tac (`_ /\ _`)) THEN ((TRY done_tac)));
3144    (((((use_arg_then2 ("mapP", [mapP]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("NOT_EXISTS_THM", [NOT_EXISTS_THM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negb_and", [negb_and]))(thm_tac (new_rewrite [] []))))) THEN (split_tac));
3145    ((((fun arg_tac ->  (conv_thm_tac DISCH_THEN)  (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac MP_TAC)) THEN BETA_TAC THEN (simp_tac)) THEN (done_tac));
3146    (BETA_TAC THEN (move ["Hx"]) THEN (move ["y"]));
3147    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`y <- s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac) THEN (move ["Hy"]));
3148    ((((fun arg_tac -> arg_tac (Arg_theorem (TAUT `~A <=> (A ==> F)`)))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (move ["fxy"]));
3149    ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("injf", [])) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("y", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("Hy", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("fxy", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)));
3150    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x = y`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN ((TRY done_tac)) THEN (move ["xy"]));
3151    ((((use_arg_then2 ("Hx", [])) (disch_tac [])) THEN (clear_assumption "Hx") THEN ((use_arg_then2 ("Hy", [])) (disch_tac [])) THEN (clear_assumption "Hy") THEN BETA_TAC) THEN (((use_arg_then2 ("xy", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
3152 ];;
3153
3154 (* Lemma map_subseq *)
3155 let map_subseq = Sections.section_proof ["s1";"s2"]
3156 `subseq s1 s2 ==> subseq (map f s1) (map f s2)`
3157 [
3158    ((repeat_tactic 1 9 (((use_arg_then2 ("subseqP", [subseqP]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (move ["m"])) THEN (case THEN ((move ["sz_m"]) THEN (move ["eq"]))));
3159    (((use_arg_then2 ("m", [])) (term_tac exists_tac)) THEN ((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_map", [size_map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("map_mask", [map_mask]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3160 ];;
3161
3162 (* Finalization of the section EqMap *)
3163 let map_f = Sections.finalize_theorem map_f;;
3164 let mapP = Sections.finalize_theorem mapP;;
3165 let map_uniq = Sections.finalize_theorem map_uniq;;
3166 let map_inj_in_uniq = Sections.finalize_theorem map_inj_in_uniq;;
3167 let map_subseq = Sections.finalize_theorem map_subseq;;
3168 Sections.end_section "EqMap";;
3169
3170 (* Section EqMap2 *)
3171 Sections.begin_section "EqMap2";;
3172 (Sections.add_section_var (mk_var ("n0", (`:num`))));;
3173 (Sections.add_section_var (mk_var ("x1", (`:A`))));;
3174 (Sections.add_section_var (mk_var ("x2", (`:B`))));;
3175 (Sections.add_section_var (mk_var ("f", (`:A -> B`))));;
3176 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
3177 (Sections.add_section_hyp "Hf" (`!x y. f x = f y ==> x = y`));;
3178
3179 (* Lemma inj_eq *)
3180 let inj_eq = Sections.section_proof ["x";"y"]
3181 `(f x = f y <=> x = y)`
3182 [
3183    (((THENL) (split_tac) [(DISCH_THEN (fun snd_th -> (use_arg_then2 ("Hf", [])) (thm_tac (match_mp_then snd_th MP_TAC)))); (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) THEN (done_tac));
3184 ];;
3185
3186 (* Lemma mem_map *)
3187 let mem_map = Sections.section_proof ["s";"x"]
3188 `(f x <- map f s) = (x <- s)`
3189 [
3190    ((((use_arg_then2 ("mapP", [mapP]))(thm_tac (new_rewrite [] [])))) THEN ((THENL) (split_tac) [((case THEN ((move ["y"]) THEN (case THEN ((move ["Hy"]) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("Hf", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))))) THEN ((TRY done_tac))); (move ["Hx"])]) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac));
3191 ];;
3192
3193 (* Lemma index_map *)
3194 let index_map = Sections.section_proof ["s";"x"]
3195 `indexl (f x) (map f s) = indexl x s`
3196 [
3197    ((repeat_tactic 1 9 (((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] []))))) THEN ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("pred1", [pred1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac)));
3198    (((((use_arg_then2 ("inj_eq", [inj_eq]))(gsym_then (thm_tac (new_rewrite [] [(`y = x`)]))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("pred1", [pred1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3199 ];;
3200
3201 (* Lemma map_inj_uniq *)
3202 let map_inj_uniq = Sections.section_proof ["s"]
3203 `uniq (map f s) = uniq s`
3204 [
3205    ((((use_arg_then2 ("map_inj_in_uniq", [map_inj_in_uniq])) (disch_tac [])) THEN (clear_assumption "map_inj_in_uniq") THEN (DISCH_THEN apply_tac) THEN (move ["x"]) THEN (move ["y"]) THEN (move ["_"]) THEN (move ["_"]) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("Hf", [])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN (done_tac));
3206 ];;
3207
3208 (* Finalization of the section EqMap2 *)
3209 let inj_eq = Sections.finalize_theorem inj_eq;;
3210 let mem_map = Sections.finalize_theorem mem_map;;
3211 let index_map = Sections.finalize_theorem index_map;;
3212 let map_inj_uniq = Sections.finalize_theorem map_inj_uniq;;
3213 Sections.end_section "EqMap2";;
3214
3215 (* Section MapComp *)
3216 Sections.begin_section "MapComp";;
3217
3218 (* Lemma map_id *)
3219 let map_id = Sections.section_proof ["s"]
3220 `map I (s:(A)list) = s`
3221 [
3222    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("I_THM", [I_THM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3223 ];;
3224
3225 (* Lemma eq_map *)
3226 let eq_map = Sections.section_proof ["f1";"f2"]
3227 `(!x. (f1:A->B) x = f2 x) ==> map f1 = map f2`
3228 [
3229    (((((use_arg_then2 ("eq_ext", [eq_ext]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3230 ];;
3231
3232 (* Lemma map_comp *)
3233 let map_comp = Sections.section_proof ["f1";"f2";"s"]
3234 `map (f1 o f2) s = map (f1:B->C) (map (f2:A->B) s)`
3235 [
3236    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (repeat_tactic 1 9 (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3237    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("o_THM", [o_THM]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3238 ];;
3239
3240 (* Lemma mapK *)
3241 let mapK = Sections.section_proof ["f1";"f2"]
3242 `(!x. (f2:B->A) ((f1:A->B) x) = x) ==> (!s. map f2 (map f1 s) = s)`
3243 [
3244    ((BETA_TAC THEN (move ["eq_f12"])) THEN ((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (repeat_tactic 1 9 (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3245 ];;
3246
3247 (* Finalization of the section MapComp *)
3248 let map_id = Sections.finalize_theorem map_id;;
3249 let eq_map = Sections.finalize_theorem eq_map;;
3250 let map_comp = Sections.finalize_theorem map_comp;;
3251 let mapK = Sections.finalize_theorem mapK;;
3252 Sections.end_section "MapComp";;
3253
3254 (* Lemma eq_in_map *)
3255 let eq_in_map = Sections.section_proof ["f1";"f2";"s"]
3256 `(!x. x <- s ==> (f1:A->B) x = f2 x) ==> map f1 s = map f2 s`
3257 [
3258    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]) THEN (move ["eqf12"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3259    (((((use_arg_then2 ("eqf12", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (move ["y"]) THEN (move ["sy"]));
3260    (((((use_arg_then2 ("eqf12", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3261 ];;
3262
3263 (* Lemma map_id_in *)
3264 let map_id_in = Sections.section_proof ["f";"s"]
3265 `(!x. x <- s ==> f x = (x:A)) ==> map f s = s`
3266 [
3267    ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("eq_in_map", [eq_in_map])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))));
3268    (((use_arg_then2 ("map_id", [map_id]))(gsym_then (thm_tac (new_rewrite [2] [(`s`)])))));
3269    (((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("eq_map", [eq_map])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(\x. x)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`I`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("I_THM", [I_THM]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3270 ];;
3271 let iota = define `iota m (SUC n) = m :: iota (SUC m) n /\ iota m 0 = []`;;
3272
3273 (* Lemma size_iota *)
3274 let size_iota = Sections.section_proof ["m";"n"]
3275 `sizel (iota m n) = n`
3276 [
3277    (((THENL) (((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]) THEN (move ["m"]))]) THEN ((((use_arg_then2 ("iota", [iota]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3278    ((((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
3279 ];;
3280
3281 (* Lemma iota_add *)
3282 let iota_add = Sections.section_proof ["m";"n1";"n2"]
3283 `iota m (n1 + n2) = iota m n1 ++ iota (m + n1) n2`
3284 [
3285    (((THENL) (((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN ((use_arg_then2 ("n1", [])) (disch_tac [])) THEN (clear_assumption "n1") THEN elim) [ALL_TAC; ((move ["n1"]) THEN (move ["IHn1"]))]) THEN ((((use_arg_then2 ("addn0", [addn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iota", [iota]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat0s", [cat0s]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3286    (((((use_arg_then2 ("addSnnS", [addSnnS]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("addSn", [addSn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iota", [iota]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("IHn1", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("addSn", [addSn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat_cons", [cat_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3287 ];;
3288
3289 (* Lemma iota_addl *)
3290 let iota_addl = Sections.section_proof ["m1";"m2";"n"]
3291 `iota (m1 + m2) n = map ((+) m1) (iota m2 n)`
3292 [
3293    (((THENL) (((use_arg_then2 ("m2", [])) (disch_tac [])) THEN (clear_assumption "m2") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]) THEN (move ["m2"]))]) THEN ((((use_arg_then2 ("iota", [iota]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((TRY done_tac))));
3294    (((((use_arg_then2 ("addnS", [addnS]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3295 ];;
3296
3297 (* Lemma nth_iota *)
3298 let nth_iota = Sections.section_proof ["m";"n";"i"]
3299 `i < n ==> nth 0 (iota m n) i = m + i`
3300 [
3301    (((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("subnKC", [subnKC])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((((use_arg_then2 ("addSnnS", [addSnnS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("iota_add", [iota_add]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_iota", [size_iota]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("subnn", [subnn]))(thm_tac (new_rewrite [] []))))));
3302    (((((use_arg_then2 ("iota", [iota]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3303 ];;
3304
3305 (* Lemma mem_iota *)
3306 let mem_iota = Sections.section_proof ["m";"n";"i"]
3307 `(i <- iota m n) <=> (m <= i) /\ (i < m + n)`
3308 [
3309    ((((THENL) (((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN (move ["m"])) THEN ((((use_arg_then2 ("iota", [iota]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3310    (((((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbN", [andbN]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3311    ((((use_arg_then2 ("addSnnS", [addSnnS]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("leq_eqVlt", [leq_eqVlt]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`i = m`)])))));
3312    (((fun arg_tac -> (use_arg_then2 ("EXCLUDED_MIDDLE", [EXCLUDED_MIDDLE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`m = i`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN (simp_tac));
3313    (((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addSn", [addSn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_addr", [leq_addr]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3314    (((((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3315 ];;
3316
3317 (* Lemma iota_uniq *)
3318 let iota_uniq = Sections.section_proof ["m";"n"]
3319 `uniq (iota m n)`
3320 [
3321    (((THENL) (((use_arg_then2 ("m", [])) (disch_tac [])) THEN (clear_assumption "m") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]) THEN (move ["m"]))]) THEN ((((use_arg_then2 ("iota", [iota]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((TRY done_tac))));
3322    (((((use_arg_then2 ("mem_iota", [mem_iota]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andFb", [andFb]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3323 ];;
3324
3325 (* Section MakeSeq *)
3326 Sections.begin_section "MakeSeq";;
3327 (Sections.add_section_var (mk_var ("x0", (`:A`))));;
3328 let mkseq = new_definition `mkseq f n = map f (iota 0 n)`;;
3329
3330 (* Lemma size_mkseq *)
3331 let size_mkseq = Sections.section_proof ["f";"n"]
3332 `sizel (mkseq f n) = n`
3333 [
3334    (((((use_arg_then2 ("mkseq", [mkseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_map", [size_map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_iota", [size_iota]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3335 ];;
3336
3337 (* Lemma eq_mkseq *)
3338 let eq_mkseq = Sections.section_proof ["f";"g"]
3339 `(!x. f x = g x) ==> mkseq f = mkseq g`
3340 [
3341    ((((((use_arg_then2 ("eq_ext", [eq_ext]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("mkseq", [mkseq]))(thm_tac (new_rewrite [] [])))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("eq_map", [eq_map])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3342 ];;
3343
3344 (* Lemma nth_mkseq *)
3345 let nth_mkseq = Sections.section_proof ["f";"n";"i"]
3346 `i < n ==> nth x0 (mkseq f n) i = f i`
3347 [
3348    ((BETA_TAC THEN (move ["Hi"])) THEN (((use_arg_then2 ("mkseq", [mkseq]))(thm_tac (new_rewrite [] [])))));
3349    ((((use_arg_then2 ("nth_map", [nth_map]))(thm_tac (new_rewrite [] [])))) THEN ((fun arg_tac -> arg_tac (Arg_term (`0`))) (term_tac exists_tac)) THEN (((((use_arg_then2 ("size_iota", [size_iota]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hi", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["_"])));
3350    (((((use_arg_then2 ("nth_iota", [nth_iota]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3351 ];;
3352
3353 (* Lemma mkseq_nth *)
3354 let mkseq_nth = Sections.section_proof ["s"]
3355 `mkseq (nth x0 s) (sizel s) = s`
3356 [
3357    ((((fun arg_tac -> (use_arg_then2 ("eq_from_nth", [eq_from_nth])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (DISCH_THEN apply_tac)) THEN (((((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["i"]) THEN (move ["Hi"])) THEN (((use_arg_then2 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
3358 ];;
3359
3360 (* Finalization of the section MakeSeq *)
3361 let size_mkseq = Sections.finalize_theorem size_mkseq;;
3362 let eq_mkseq = Sections.finalize_theorem eq_mkseq;;
3363 let nth_mkseq = Sections.finalize_theorem nth_mkseq;;
3364 let mkseq_nth = Sections.finalize_theorem mkseq_nth;;
3365 Sections.end_section "MakeSeq";;
3366
3367 (* Lemma mkseq_uniq *)
3368 let mkseq_uniq = Sections.section_proof ["f";"n"]
3369 `(!x y. f x = f y ==> x = y) ==> uniq (mkseq f n)`
3370 [
3371    ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("map_inj_uniq", [map_inj_uniq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (move ["Hs"]));
3372    (((((use_arg_then2 ("mkseq", [mkseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Hs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("iota_uniq", [iota_uniq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3373 ];;
3374
3375 (* Section FoldRight *)
3376 Sections.begin_section "FoldRight";;
3377 (Sections.add_section_var (mk_var ("f", (`:A -> B -> B`))));;
3378 (Sections.add_section_var (mk_var ("z0", (`:B`))));;
3379 let foldr = define `foldr f z0 (x :: s) = f x (foldr f z0 s) /\ foldr f z0 [] = z0`;;
3380
3381 (* Finalization of the section FoldRight *)
3382 Sections.end_section "FoldRight";;
3383
3384 (* Section FoldRightComp *)
3385 Sections.begin_section "FoldRightComp";;
3386 (Sections.add_section_var (mk_var ("h", (`:A->B`))));;
3387 (Sections.add_section_var (mk_var ("f", (`:B->R->R`))));;
3388 (Sections.add_section_var (mk_var ("z0", (`:R`))));;
3389
3390 (* Lemma foldr_cat *)
3391 let foldr_cat = Sections.section_proof ["s1";"s2"]
3392 `foldr f z0 (s1 ++ s2) = foldr f (foldr f z0 s2) s1`
3393 [
3394    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3395 ];;
3396
3397 (* Lemma foldr_map *)
3398 let foldr_map = Sections.section_proof ["s"]
3399 `foldr f z0 (map h s) = foldr (\x z. f (h x) z) z0 s`
3400 [
3401    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3402 ];;
3403
3404 (* Finalization of the section FoldRightComp *)
3405 let foldr_cat = Sections.finalize_theorem foldr_cat;;
3406 let foldr_map = Sections.finalize_theorem foldr_map;;
3407 Sections.end_section "FoldRightComp";;
3408 let sumn = new_definition `sumn = foldr (+) 0`;;
3409
3410 (* Lemma sumn0 *)
3411 let sumn0 = Sections.section_proof []
3412 `sumn [] = 0`
3413 [
3414    (((((use_arg_then2 ("sumn", [sumn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3415 ];;
3416
3417 (* Lemma sumn_nseq *)
3418 let sumn_nseq = Sections.section_proof ["x";"n"]
3419 `sumn (nseq n x) = x * n`
3420 [
3421    ((((use_arg_then2 ("mulnC", [mulnC]))(thm_tac (new_rewrite [] [])))) THEN ((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IHn"]))]) THEN ((((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sumn", [sumn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("mul0n", [mul0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3422    (((((use_arg_then2 ("sumn", [sumn]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ncons", [ncons]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nseq", [nseq]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mulSn", [mulSn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3423 ];;
3424
3425 (* Lemma sumn_cat *)
3426 let sumn_cat = Sections.section_proof ["s1";"s2"]
3427 `sumn (s1 ++ s2) = sumn s1 + sumn s2`
3428 [
3429    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sumn0", [sumn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("add0n", [add0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3430    (((((use_arg_then2 ("sumn", [sumn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sumn", [sumn]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("IHs", []))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("addnA", [addnA]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3431 ];;
3432
3433 (* Lemma natnseq0P *)
3434 let natnseq0P = Sections.section_proof ["s"]
3435 `sumn s = 0 <=> s = nseq (sizel s) 0`
3436 [
3437    ((THENL_LAST) ((THENL) (split_tac) [ALL_TAC; (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) (((((use_arg_then2 ("sumn_nseq", [sumn_nseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mul0n", [mul0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)));
3438    ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)));
3439    ((((((use_arg_then2 ("sumn", [sumn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sumn", [sumn]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("addn_eq0", [addn_eq0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nseq", [nseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("iter", [iter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ncons", [ncons]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("nseq", [nseq]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN ALL_TAC THEN (case THEN ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))))) THEN (done_tac));
3440 ];;
3441
3442 (* Section FoldLeft *)
3443 Sections.begin_section "FoldLeft";;
3444 (Sections.add_section_var (mk_var ("f", (`:R->A->R`))));;
3445 let foldl = define `foldl f z (x :: s) = foldl f (f z x) s /\ foldl f z [] = z`;;
3446
3447 (* Lemma foldl_rev *)
3448 let foldl_rev = Sections.section_proof ["z";"s"]
3449 `foldl f z (rev s) = foldr (\x z0. f z0 x) z s`
3450 [
3451    ((((use_arg_then2 ("z", [])) (disch_tac [])) THEN (clear_assumption "z") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((fun arg_tac -> arg_tac (Arg_theorem (REWRITE_RULE[IMP_IMP] last_ind))) (disch_tac [])) THEN (DISCH_THEN apply_tac)) THEN (((THENL) (split_tac) [ALL_TAC; ((move ["s"]) THEN (move ["x"]) THEN (move ["IHs"]))]) THEN (move ["z"])));
3452    (((((use_arg_then2 ("rev", [rev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldl", [foldl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3453    ((((use_arg_then2 ("rev_rcons", [rev_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("foldr_cat", [foldr_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))));
3454    (((repeat_tactic 1 9 (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("foldl", [foldl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3455 ];;
3456
3457 (* Lemma foldl_cat *)
3458 let foldl_cat = Sections.section_proof ["z";"s1";"s2"]
3459 `foldl f z (s1 ++ s2) = foldl f (foldl f z s1) s2`
3460 [
3461    (((((fun arg_tac -> (use_arg_then2 ("revK", [revK])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`s1 ++ s2`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("foldl_rev", [foldl_rev]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rev_cat", [rev_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("foldr_cat", [foldr_cat]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("foldl_rev", [foldl_rev]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("revK", [revK]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3462 ];;
3463
3464 (* Finalization of the section FoldLeft *)
3465 let foldl_rev = Sections.finalize_theorem foldl_rev;;
3466 let foldl_cat = Sections.finalize_theorem foldl_cat;;
3467 Sections.end_section "FoldLeft";;
3468
3469 (* Section Scan *)
3470 Sections.begin_section "Scan";;
3471 (Sections.add_section_var (mk_var ("x1", (`:A`))));;
3472 (Sections.add_section_var (mk_var ("x2", (`:B`))));;
3473 (Sections.add_section_var (mk_var ("f", (`:A -> A -> B`))));;
3474 (Sections.add_section_var (mk_var ("g", (`:A -> B -> A`))));;
3475 let pairmap = define `pairmap f x (y :: s) = f x y :: pairmap f y s /\ pairmap f x [] = []`;;
3476
3477 (* Lemma size_pairmap *)
3478 let size_pairmap = Sections.section_proof ["x";"s"]
3479 `sizel (pairmap f x s) = sizel s`
3480 [
3481    ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (move ["x"])) THEN ((((use_arg_then2 ("pairmap", [pairmap]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3482    (((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3483 ];;
3484
3485 (* Lemma pairmap_cat *)
3486 let pairmap_cat = Sections.section_proof ["x";"s1";"s2"]
3487 `pairmap f x (s1 ++ s2) = pairmap f x s1 ++ pairmap f (last x s1) s2`
3488 [
3489    ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s1"]) THEN (move ["IHs1"]))]) THEN (move ["x"])) THEN ((((use_arg_then2 ("pairmap", [pairmap]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("pairmap", [pairmap]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3490    ((((use_arg_then2 ("IHs1", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
3491 ];;
3492
3493 (* Lemma nth_pairmap *)
3494 let nth_pairmap = Sections.section_proof ["s";"n"]
3495 `n < sizel s ==>
3496   !x. nth x2 (pairmap f x s) n = f (nth x1 (x :: s) n) (nth x1 s n)`
3497 [
3498    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltS0", [ltS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("pairmap", [pairmap]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3499    ((((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (move ["Hn"]) THEN (move ["x"])) THEN (done_tac));
3500 ];;
3501 let scanl = define `scanl g x (y :: s) = g x y :: scanl g (g x y) s /\ scanl g x [] = []`;;
3502
3503 (* Lemma size_scanl *)
3504 let size_scanl = Sections.section_proof ["x";"s"]
3505 `sizel (scanl g x s) = sizel s`
3506 [
3507    ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (move ["x"])) THEN ((((use_arg_then2 ("scanl", [scanl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3508    ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
3509 ];;
3510
3511 (* Lemma scanl_cat *)
3512 let scanl_cat = Sections.section_proof ["x";"s1";"s2"]
3513 `scanl g x (s1 ++ s2) = scanl g x s1 ++ scanl g (foldl g x s1) s2`
3514 [
3515    ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s1"]) THEN (move ["IHs1"]))]) THEN (move ["x"])) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("scanl", [scanl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldl", [foldl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3516 ];;
3517
3518 (* Lemma nth_scanl *)
3519 let nth_scanl = Sections.section_proof ["s";"n"]
3520 `n < sizel s ==>
3521   !x. nth x1 (scanl g x s) n = foldl g x (take (SUC n) s)`
3522 [
3523    (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["n"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltS0", [ltS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("scanl", [scanl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("foldl", [foldl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((TRY done_tac))));
3524    ((((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (move ["Hn"])) THEN (done_tac));
3525 ];;
3526
3527 (* Lemma scanlK *)
3528 let scanlK = Sections.section_proof []
3529 `(!x y. f x (g x y) = y) ==> (!x s. pairmap f x (scanl g x s) = s)`
3530 [
3531    (BETA_TAC THEN (move ["Hfg"]) THEN (move ["x"]) THEN (move ["s"]));
3532    ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (move ["x"])) THEN ((((use_arg_then2 ("scanl", [scanl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("pairmap", [pairmap]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3533 ];;
3534
3535 (* Lemma pairmapK *)
3536 let pairmapK = Sections.section_proof []
3537 `(!x y. g x (f x y) = y) ==> (!x s. scanl g x (pairmap f x s) = s)`
3538 [
3539    (BETA_TAC THEN (move ["Hgf"]) THEN (move ["x"]) THEN (move ["s"]));
3540    ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["y"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN (move ["x"])) THEN ((((use_arg_then2 ("pairmap", [pairmap]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("scanl", [scanl]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3541 ];;
3542
3543 (* Finalization of the section Scan *)
3544 let size_pairmap = Sections.finalize_theorem size_pairmap;;
3545 let pairmap_cat = Sections.finalize_theorem pairmap_cat;;
3546 let nth_pairmap = Sections.finalize_theorem nth_pairmap;;
3547 let size_scanl = Sections.finalize_theorem size_scanl;;
3548 let scanl_cat = Sections.finalize_theorem scanl_cat;;
3549 let nth_scanl = Sections.finalize_theorem nth_scanl;;
3550 let scanlK = Sections.finalize_theorem scanlK;;
3551 let pairmapK = Sections.finalize_theorem pairmapK;;
3552 Sections.end_section "Scan";;
3553
3554 (* Section Zip *)
3555 Sections.begin_section "Zip";;
3556 let zip = define `zip (x :: s) (y :: t) = (x, y) :: zip s t /\
3557         zip [] t = [] /\ zip s [] = []`;;
3558 let unzip1 = new_definition `unzip1 = map FST`;;
3559 let unzip2 = new_definition `unzip2 = map SND`;;
3560
3561 (* Lemma zip_unzip *)
3562 let zip_unzip = Sections.section_proof ["s"]
3563 `zip (unzip1 s) (unzip2 s) = s`
3564 [
3565    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("unzip1", [unzip1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("unzip2", [unzip2]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("PAIR", [PAIR]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3566    (((((use_arg_then2 ("unzip1", [unzip1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("unzip2", [unzip2]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3567 ];;
3568
3569 (* Lemma unzip1_zip *)
3570 let unzip1_zip = Sections.section_proof ["s";"t"]
3571 `sizel s <= sizel t ==> unzip1 (zip s t) = s`
3572 [
3573    (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("unzip1", [unzip1]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3574    ((((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("unzip1", [unzip1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3575 ];;
3576
3577 (* Lemma unzip2_zip *)
3578 let unzip2_zip = Sections.section_proof ["s";"t"]
3579 `sizel t <= sizel s ==> unzip2 (zip s t) = t`
3580 [
3581    (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("unzip2", [unzip2]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3582    ((((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("unzip2", [unzip2]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3583 ];;
3584
3585 (* Lemma size1_zip *)
3586 let size1_zip = Sections.section_proof ["s";"t"]
3587 `sizel s <= sizel t ==> sizel (zip s t) = sizel s`
3588 [
3589    (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3590    ((((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3591 ];;
3592
3593 (* Lemma size2_zip *)
3594 let size2_zip = Sections.section_proof ["s";"t"]
3595 `sizel t <= sizel s ==> sizel (zip s t) = sizel t`
3596 [
3597    (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3598    ((((((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3599 ];;
3600
3601 (* Lemma size_zip *)
3602 let size_zip = Sections.section_proof ["s";"t"]
3603 `sizel (zip s t) = minn (sizel s) (sizel t)`
3604 [
3605    (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["t2"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("minn", [minn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltnn", [ltnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (simp_tac) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltS0", [ltS0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3606    (((((use_arg_then2 ("minn", [minn]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("add1n", [add1n]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn_minr", [addn_minr]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("add1n", [add1n]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3607 ];;
3608
3609 (* Lemma zip_cat *)
3610 let zip_cat = Sections.section_proof ["s1";"s2";"t1";"t2"]
3611 `sizel s1 = sizel t1 ==> zip (s1 ++ s2) (t1 ++ t2) = zip s1 t1 ++ zip s2 t2`
3612 [
3613    (((THENL) (((use_arg_then2 ("t1", [])) (disch_tac [])) THEN (clear_assumption "t1") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`0 = _`)]))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))));
3614    (((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3615 ];;
3616
3617 (* Lemma nth_zip *)
3618 let nth_zip = Sections.section_proof ["x";"y";"s";"t";"i"]
3619 `sizel s = sizel t ==> nth (x, y) (zip s t) i = (nth x s i, nth y t i)`
3620 [
3621    (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN elim) [ALL_TAC; ((move ["i"]) THEN (move ["IHi"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y1"]) THEN (move ["s1"]) THEN (move ["_"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y2"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [(`0 = _`)]))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))));
3622    (((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHi", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3623 ];;
3624
3625 (* Lemma nth_zip_cond *)
3626 let nth_zip_cond = Sections.section_proof ["p";"s";"t";"i"]
3627 `nth p (zip s t) i
3628      = (if i < sizel (zip s t) then (nth (FST p) s i, nth (SND p) t i) else p)`
3629 [
3630    ((((use_arg_then2 ("size_zip", [size_zip]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_minl", [leq_minl]))(thm_tac (new_rewrite [] [])))));
3631    (((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN ((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["y"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((THENL) elim [ALL_TAC; ((move ["i"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("leqnn", [leqnn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("leq0n", [leq0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3632    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac));
3633 ];;
3634
3635 (* Lemma zip_rcons *)
3636 let zip_rcons = Sections.section_proof ["s1";"s2";"z1";"z2"]
3637 `sizel s1 = sizel s2 ==>
3638   zip (rcons s1 z1) (rcons s2 z2) = rcons (zip s1 s2) (z1, z2)`
3639 [
3640    ((BETA_TAC THEN (move ["eq_sz"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("cats1", [cats1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("zip_cat", [zip_cat]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3641 ];;
3642
3643 (* Lemma rev_zip *)
3644 let rev_zip = Sections.section_proof ["s1";"s2"]
3645 `sizel s1 = sizel s2 ==> rev (zip s1 s2) = zip (rev s1) (rev s2)`
3646 [
3647    ((((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((THENL) case [ALL_TAC; ((move ["y"]) THEN (move ["s2"]))])) THEN (TRY ((((((use_arg_then2 ("rev", [rev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("catrev", [catrev]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)))));
3648    (((repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] []))))) THEN (move ["eq_sz"]));
3649    (((repeat_tactic 1 9 (((use_arg_then2 ("rev_cons", [rev_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("zip_rcons", [zip_rcons]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_rev", [size_rev]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN ((((use_arg_then2 ("zip", [zip]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("rev_cons", [rev_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (done_tac));
3650 ];;
3651
3652 (* Finalization of the section Zip *)
3653 let zip_unzip = Sections.finalize_theorem zip_unzip;;
3654 let unzip1_zip = Sections.finalize_theorem unzip1_zip;;
3655 let unzip2_zip = Sections.finalize_theorem unzip2_zip;;
3656 let size1_zip = Sections.finalize_theorem size1_zip;;
3657 let size2_zip = Sections.finalize_theorem size2_zip;;
3658 let size_zip = Sections.finalize_theorem size_zip;;
3659 let zip_cat = Sections.finalize_theorem zip_cat;;
3660 let nth_zip = Sections.finalize_theorem nth_zip;;
3661 let nth_zip_cond = Sections.finalize_theorem nth_zip_cond;;
3662 let zip_rcons = Sections.finalize_theorem zip_rcons;;
3663 let rev_zip = Sections.finalize_theorem rev_zip;;
3664 Sections.end_section "Zip";;
3665
3666 (* Section Flatten *)
3667 Sections.begin_section "Flatten";;
3668 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
3669 (Sections.add_section_type (mk_var ("ss", (`:((A)list)list`))));;
3670 let flatten = new_definition `flatten = foldr cat []`;;
3671 let shape = new_definition `shape = map sizel`;;
3672 let reshape = define `reshape (n :: sh) s = take n s :: reshape sh (dropl n s) /\
3673         reshape [] s = []`;;
3674
3675 (* Lemma flatten0 *)
3676 let flatten0 = Sections.section_proof []
3677 `flatten [] = []`
3678 [
3679    (((((use_arg_then2 ("flatten", [flatten]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3680 ];;
3681
3682 (* Lemma flatten_cons *)
3683 let flatten_cons = Sections.section_proof ["s";"ss"]
3684 `flatten (s :: ss) = s ++ flatten ss`
3685 [
3686    (((((use_arg_then2 ("flatten", [flatten]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3687 ];;
3688
3689 (* Lemma size_flatten *)
3690 let size_flatten = Sections.section_proof ["ss"]
3691 `sizel (flatten ss) = sumn (shape ss)`
3692 [
3693    (((THENL) (((use_arg_then2 ("ss", [])) (disch_tac [])) THEN (clear_assumption "ss") THEN elim) [ALL_TAC; ((move ["s"]) THEN (move ["ss"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("flatten", [flatten]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("shape", [shape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sumn0", [sumn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3694    (((((use_arg_then2 ("flatten", [flatten]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("shape", [shape]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((((use_arg_then2 ("sumn", [sumn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3695 ];;
3696
3697 (* Lemma flatten_cat *)
3698 let flatten_cat = Sections.section_proof ["ss1";"ss2"]
3699 `flatten (ss1 ++ ss2) = flatten ss1 ++ flatten ss2`
3700 [
3701    (((THENL) (((use_arg_then2 ("ss1", [])) (disch_tac [])) THEN (clear_assumption "ss1") THEN elim) [ALL_TAC; ((move ["s"]) THEN (move ["ss1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("flatten0", [flatten0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("flatten_cons", [flatten_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3702    (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3703 ];;
3704
3705 (* Lemma flattenK *)
3706 let flattenK = Sections.section_proof ["ss"]
3707 `reshape (shape ss) (flatten ss) = ss`
3708 [
3709    (((THENL) (((use_arg_then2 ("ss", [])) (disch_tac [])) THEN (clear_assumption "ss") THEN elim) [ALL_TAC; ((move ["s"]) THEN (move ["ss"]) THEN (move ["IHss"]))]) THEN ((((use_arg_then2 ("flatten", [flatten]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("shape", [shape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("reshape", [reshape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3710    (((((use_arg_then2 ("take_size_cat", [take_size_cat]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("drop_size_cat", [drop_size_cat]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("flatten", [flatten]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("shape", [shape]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHss", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3711 ];;
3712
3713 (* Lemma reshapeKr *)
3714 let reshapeKr = Sections.section_proof ["sh";"s"]
3715 `sizel s <= sumn sh ==> flatten (reshape sh s) = s`
3716 [
3717    ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("sh", [])) (disch_tac [])) THEN (clear_assumption "sh") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["sh"]) THEN (move ["IHsh"]) THEN (move ["s"]) THEN (move ["sz_s"]))]);
3718    (((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("reshape", [reshape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("flatten0", [flatten0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("sumn0", [sumn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3719    ((((use_arg_then2 ("reshape", [reshape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("flatten", [flatten]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("flatten", [flatten]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))));
3720    (((((use_arg_then2 ("IHsh", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("cat_take_drop", [cat_take_drop]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_sub_add", [leq_sub_add]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("sz_s", [])) (disch_tac [])) THEN (clear_assumption "sz_s") THEN BETA_TAC));
3721    (((((use_arg_then2 ("sumn", [sumn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3722 ];;
3723
3724 (* Lemma reshapeKl *)
3725 let reshapeKl = Sections.section_proof ["sh";"s"]
3726 `sumn sh <= sizel s ==> shape (reshape sh s) = sh`
3727 [
3728    ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN ((use_arg_then2 ("sh", [])) (disch_tac [])) THEN (clear_assumption "sh") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["sh"]) THEN (move ["IHsh"]) THEN (move ["s"]) THEN (move ["sz_s"]))]);
3729    (((THENL) elim [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["_"]))]) THEN ((((use_arg_then2 ("reshape", [reshape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("shape", [shape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
3730    ((((use_arg_then2 ("sz_s", [])) (disch_tac [])) THEN (clear_assumption "sz_s") THEN BETA_TAC) THEN (((((use_arg_then2 ("sumn", [sumn]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("sumn", [sumn]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (move ["sz_s"])));
3731    (((((use_arg_then2 ("reshape", [reshape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("shape", [shape]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("shape", [shape]))(gsym_then (fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))))) THEN (((use_arg_then2 ("size_takel", [size_takel]))(thm_tac (new_rewrite [] [])))));
3732    ((((use_arg_then2 ("sz_s", [])) (disch_tac [])) THEN (clear_assumption "sz_s") THEN ((use_arg_then2 ("leq_trans", [leq_trans])) (disch_tac [])) THEN (clear_assumption "leq_trans") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("leq_addr", [leq_addr]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
3733    (((((use_arg_then2 ("IHsh", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("leq_add2l", [leq_add2l])) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("add_sub_maxn", [add_sub_maxn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_maxr", [leq_maxr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("sz_s", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbT", [orbT]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3734 ];;
3735
3736 (* Finalization of the section Flatten *)
3737 let flatten0 = Sections.finalize_theorem flatten0;;
3738 let flatten_cons = Sections.finalize_theorem flatten_cons;;
3739 let size_flatten = Sections.finalize_theorem size_flatten;;
3740 let flatten_cat = Sections.finalize_theorem flatten_cat;;
3741 let flattenK = Sections.finalize_theorem flattenK;;
3742 let reshapeKr = Sections.finalize_theorem reshapeKr;;
3743 let reshapeKl = Sections.finalize_theorem reshapeKl;;
3744 Sections.end_section "Flatten";;
3745
3746 (* Section AllPairs *)
3747 Sections.begin_section "AllPairs";;
3748 (Sections.add_section_var (mk_var ("f", (`:S->T->R`))));;
3749 (Sections.add_section_type (mk_var ("s", (`:(S)list`))));;
3750 (Sections.add_section_type (mk_var ("t", (`:(T)list`))));;
3751 let allpairs = new_definition `allpairs f s t = foldr (\x. cat (map (f x) t)) [] s`;;
3752
3753 (* Lemma size_allpairs *)
3754 let size_allpairs = Sections.section_proof ["s";"t"]
3755 `sizel (allpairs f s t) = sizel s * sizel t`
3756 [
3757    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("allpairs", [allpairs]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("mul0n", [mul0n]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3758    (((((use_arg_then2 ("size_cat", [size_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("allpairs", [allpairs]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_map", [size_map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mulSn", [mulSn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3759 ];;
3760
3761 (* Lemma allpairs_cat *)
3762 let allpairs_cat = Sections.section_proof ["s1";"s2";"t"]
3763 `allpairs f (s1 ++ s2) t = allpairs f s1 t ++ allpairs f s2 t`
3764 [
3765    (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s1"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("allpairs", [allpairs]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3766    (((repeat_tactic 1 9 (((use_arg_then2 ("allpairs", [allpairs]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3767 ];;
3768
3769 (* Finalization of the section AllPairs *)
3770 let size_allpairs = Sections.finalize_theorem size_allpairs;;
3771 let allpairs_cat = Sections.finalize_theorem allpairs_cat;;
3772 Sections.end_section "AllPairs";;
3773
3774 (* Section EqAllPairs *)
3775 Sections.begin_section "EqAllPairs";;
3776 (Sections.add_section_var (mk_var ("f", (`:S->T->R`))));;
3777 (Sections.add_section_type (mk_var ("s", (`:(S)list`))));;
3778 (Sections.add_section_type (mk_var ("t", (`:(T)list`))));;
3779
3780 (* Lemma allpairsP *)
3781 let allpairsP = Sections.section_proof ["s";"t";"z"]
3782 `(z <- allpairs f s t) <=> (?p. FST p <- s /\ SND p <- t /\ z = f (FST p) (SND p))`
3783 [
3784    (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["x"]) THEN (move ["s"]) THEN (move ["IHs"]))]) THEN ((((use_arg_then2 ("allpairs", [allpairs]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("foldr", [foldr]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (((use_arg_then2 ("in_nil", [in_nil]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN ((TRY done_tac))));
3785    (((((use_arg_then2 ("allpairs", [allpairs]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mapP", [mapP]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (split_tac));
3786    ((THENL_FIRST) ((THENL) case [((case THEN (move ["y"])) THEN (case THEN ((move ["Hy"]) THEN (move ["eq"])))); ((case THEN (move ["p"])) THEN (case THEN ((move ["p1"]) THEN (case THEN ((move ["p2"]) THEN (move ["eq"]))))))]) ((((fun arg_tac -> arg_tac (Arg_term (`(x, y)`))) (term_tac exists_tac)) THEN (simp_tac)) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)));
3787    (((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
3788    ((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (BETA_TAC THEN (case THEN (move ["p"])) THEN (case THEN (case THEN (move ["p_s"]))) THEN (case THEN ((move ["p_t"]) THEN (move ["eq"])))));
3789    ((DISJ1_TAC) THEN ((fun arg_tac -> arg_tac (Arg_term (`SND p`))) (term_tac exists_tac)) THEN (done_tac));
3790    ((DISJ2_TAC) THEN ((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (done_tac));
3791 ];;
3792
3793 (* Lemma mem_allpairs *)
3794 let mem_allpairs = Sections.section_proof ["s1";"t1";"s2";"t2"]
3795 `(!x. x <- s1 <=> x <- s2) ==> (!y. y <- t1 <=> y <- t2) 
3796         ==> (!p. p <- allpairs f s1 t1 <=> p <- allpairs f s2 t2)`
3797 [
3798    (BETA_TAC THEN (move ["eq_s"]) THEN (move ["eq_t"]) THEN (move ["z"]));
3799    ((repeat_tactic 1 9 (((use_arg_then2 ("allpairsP", [allpairsP]))(thm_tac (new_rewrite [] []))))) THEN ((split_tac) THEN ALL_TAC THEN (case THEN (move ["p"]))) THEN (((((use_arg_then2 ("eq_s", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq_t", []))(thm_tac (new_rewrite [] []))))) THEN (move ["fpz"])));
3800    (((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (done_tac));
3801    (((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (done_tac));
3802 ];;
3803
3804 (* Lemma allpairs_catr *)
3805 let allpairs_catr = Sections.section_proof ["s";"t1";"t2"]
3806 `!p. p <- allpairs f s (t1 ++ t2) <=> p <- allpairs f s t1 ++ allpairs f s t2`
3807 [
3808    ((BETA_TAC THEN (move ["z"])) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] [])))));
3809    ((((use_arg_then2 ("allpairsP", [allpairsP]))(thm_tac (new_rewrite [] [])))) THEN ((THENL) (split_tac) [(case THEN ((move ["p"]) THEN (case THEN (move ["sP1"])))); ALL_TAC]));
3810    (((THENL) ((((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN ((case THEN (move ["H"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) [(DISJ1_TAC); (DISJ2_TAC)]) THEN (((use_arg_then2 ("allpairsP", [allpairsP]))(thm_tac (new_rewrite [] [])))) THEN ((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (done_tac));
3811    (case THEN ((((use_arg_then2 ("allpairsP", [allpairsP]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["p"])) THEN (case THEN (move ["sp1"])) THEN (case THEN ((move ["sp2"]) THEN (move ["eq"])))) THEN ((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN ((((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("sp2", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac));
3812 ];;
3813
3814 (* Finalization of the section EqAllPairs *)
3815 let allpairsP = Sections.finalize_theorem allpairsP;;
3816 let mem_allpairs = Sections.finalize_theorem mem_allpairs;;
3817 let allpairs_catr = Sections.finalize_theorem allpairs_catr;;
3818 Sections.end_section "EqAllPairs";;
3819
3820 (* Close the module *)
3821 end;;