1 needs "Examples/ssrnat-compiled.hl";;
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`;;
21 let size0nil = Sections.section_proof ["s"]
22 `sizel s = 0 ==> s = []`
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));
26 let nilp = new_definition `!(s:(A)list). nilp s <=> (sizel s = 0)`;;
29 let nilP = Sections.section_proof ["s"]
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));
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`;;
37 (* Lemma size_behead *)
38 let size_behead = Sections.section_proof ["s"]
39 `sizel (behead s) = (sizel s) - 1`
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));
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 []`;;
47 let size_nil = Sections.section_proof []
48 `sizel ([]:(A)list) = 0`
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));
54 let size_cons = Sections.section_proof ["h";"t"]
55 `sizel (CONS (h:A) t) = SUC (sizel t)`
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));
60 (* Lemma size_ncons *)
61 let size_ncons = Sections.section_proof ["n";"x";"s"]
62 `sizel (ncons n x s) = n + sizel s`
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));
69 let size_nseq = Sections.section_proof ["n";"x"]
70 `sizel (nseq n (x:A)) = n`
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));
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`);;
81 let cat0s = Sections.section_proof ["s"]
82 `[] ++ (s:(A)list) = s`
84 ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
88 let cat1s = Sections.section_proof ["x";"s"]
91 ((repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
95 let cat_cons = Sections.section_proof ["x";"s1";"s2"]
96 `(x :: s1) ++ s2 = x :: s1 ++ s2`
98 ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
102 let cat_nseq = Sections.section_proof ["n";"x";"s"]
103 `nseq n (x:A) ++ s = ncons n x s`
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));
109 let cats0 = Sections.section_proof ["s"]
110 `s ++ [] = (s:(A)list)`
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));
116 let catA = Sections.section_proof ["s1";"s2";"s3"]
117 `s1 ++ s2 ++ s3 = (s1 ++ s2) ++ s3:(A)list`
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));
123 let size_cat = Sections.section_proof ["s1";"s2"]
124 `sizel (s1 ++ s2) = sizel s1 + sizel (s2:(A)list)`
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));
128 let rcons = define `!x t (z:A). rcons [] z = [z] /\ rcons (x :: t) z = x :: rcons t z`;;
130 (* Lemma rcons_cons *)
131 let rcons_cons = Sections.section_proof ["x";"s";"z"]
132 `rcons (x :: s) z = x:A :: rcons s z`
134 ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
138 let cats1 = Sections.section_proof ["s";"z"]
139 `s ++ [z:A] = rcons s z`
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));
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)`;;
147 let lastI = Sections.section_proof ["x";"s"]
148 `(x:A :: s) = rcons (belast x s) (last x s)`
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));
153 (* Lemma last_cons *)
154 let last_cons = Sections.section_proof ["x";"y";"s"]
155 `last x (y:A :: s) = last y s`
157 ((((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
160 (* Lemma size_rcons *)
161 let size_rcons = Sections.section_proof ["s";"x"]
162 `sizel (rcons s (x:A)) = SUC (sizel s)`
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));
167 (* Lemma size_belast *)
168 let size_belast = Sections.section_proof ["x";"s"]
169 `sizel (belast (x:A) s) = sizel s`
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));
175 let last_cat = Sections.section_proof ["x";"s1";"s2"]
176 `last (x:A) (s1 ++ s2) = last (last x s1) s2`
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));
181 (* Lemma last_rcons *)
182 let last_rcons = Sections.section_proof ["x";"s";"z"]
183 `last x (rcons s z) = z:A`
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));
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`
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));
195 (* Lemma belast_rcons *)
196 let belast_rcons = Sections.section_proof ["x";"s";"z"]
197 `belast x (rcons s z) = x:A :: s`
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));
202 (* Lemma cat_rcons *)
203 let cat_rcons = Sections.section_proof ["x";"s1";"s2"]
204 `rcons s1 x ++ s2 = s1 ++ (x:A :: s2)`
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));
209 (* Lemma rcons_cat *)
210 let rcons_cat = Sections.section_proof ["x";"s1";"s2"]
211 `rcons (s1 ++ s2) x = s1 ++ rcons s2 (x:A)`
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));
217 let last_ind = Sections.section_proof ["P"]
218 `P [] ==> (!s (x : A). P s ==> P (rcons s x)) ==> (!s. P s)`
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));
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`;;
232 let nth0 = Sections.section_proof ["s"]
233 `nth x0 s 0 = headl x0 s`
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));
238 (* Lemma nth_default *)
239 let nth_default = Sections.section_proof ["s";"n"]
240 `sizel s <= n ==> nth x0 s n = x0`
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));
247 let nth_nil = Sections.section_proof ["n"]
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));
254 let last_nth = Sections.section_proof ["x";"s"]
255 `last x s = nth x0 (x :: s) (sizel s)`
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));
262 let nth_last = Sections.section_proof ["s"]
263 `nth x0 s (sizel s - 1) = last x0 s`
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));
268 (* Lemma nth_behead *)
269 let nth_behead = Sections.section_proof ["s";"n"]
270 `nth x0 (behead s) n = nth x0 s (SUC n)`
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));
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)`
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));
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`
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));
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)`
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));
301 let nth_nseq = Sections.section_proof ["m";"x";"n"]
302 `nth x0 (nseq m x) n = (if n < m then x else x0)`
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));
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) ==>
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));
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)`
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));
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]`
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));
338 let ltS0 = Sections.section_proof ["n"]
341 ((arith_tac) THEN (done_tac));
345 let eqS0 = Sections.section_proof ["n"]
348 ((arith_tac) THEN (done_tac));
352 let eq0S = Sections.section_proof ["n"]
355 ((arith_tac) THEN (done_tac));
359 let gtS0 = Sections.section_proof ["n"]
362 ((arith_tac) THEN (done_tac));
366 let ltSS = Sections.section_proof ["m";"n"]
367 `SUC m < SUC n <=> m < n`
369 ((arith_tac) THEN (done_tac));
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`
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));
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`
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));
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')`;;
415 let find_nil = Sections.section_proof []
418 ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
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)`
425 ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
428 (* Lemma filter_nil *)
429 let filter_nil = Sections.section_proof []
432 ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
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`
439 ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
442 (* Lemma count_nil *)
443 let count_nil = Sections.section_proof []
446 ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
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`
453 ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
457 let has_nil = Sections.section_proof []
460 ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
464 let has_cons = Sections.section_proof ["x";"t"]
465 `has a (x::t) <=> a x \/ has a t`
467 ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
471 let all_nil = Sections.section_proof []
474 ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
478 let all_cons = Sections.section_proof ["x";"t"]
479 `all a (x::t) <=> a x /\ all a t`
481 ((((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
484 (* Lemma count_filter *)
485 let count_filter = Sections.section_proof ["s"]
486 `count a s = sizel (filter a s)`
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));
493 (* Lemma has_count *)
494 let has_count = Sections.section_proof ["s"]
495 `has a s = (0 < count a s)`
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));
500 (* Lemma count_size *)
501 let count_size = Sections.section_proof ["s"]
502 `count a s <= sizel s`
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)));
508 (* Lemma all_count *)
509 let all_count = Sections.section_proof ["s"]
510 `all a s = (count a s = sizel s)`
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));
517 (* Lemma filter_all *)
518 let filter_all = Sections.section_proof ["s"]
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));
525 (* Lemma all_filterP *)
526 let all_filterP = Sections.section_proof ["s"]
527 `(filter a s = s) <=> (all a s)`
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));
534 (* Lemma filter_id *)
535 let filter_id = Sections.section_proof ["s"]
536 `filter a (filter a s) = filter a s`
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));
542 let has_find = Sections.section_proof ["s"]
543 `has a s <=> (find a s < sizel s)`
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));
549 (* Lemma find_size *)
550 let find_size = Sections.section_proof ["s"]
551 `find a s <= sizel s`
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));
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`
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));
567 let has_nil = Sections.section_proof []
570 ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
574 let has_seq1 = Sections.section_proof ["x"]
577 ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
581 let has_seqb = Sections.section_proof ["b";"x"]
582 `has a (nseq (if b then 1 else 0) x) <=> (b /\ a x)`
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));
588 let all_nil = Sections.section_proof []
591 ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
595 let all_seq1 = Sections.section_proof ["x"]
598 ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
602 let nth_find = Sections.section_proof ["s"]
603 `has a s ==> a (nth x0 s (find a s))`
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));
609 (* Lemma before_find *)
610 let before_find = Sections.section_proof ["s";"i"]
611 `i < find a s ==> (a (nth x0 s i) <=> F)`
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));
619 (* Lemma filter_cat *)
620 let filter_cat = Sections.section_proof ["s1";"s2"]
621 `filter a (s1 ++ s2) = filter a s1 ++ filter a s2`
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));
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`
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));
635 (* Lemma count_cat *)
636 let count_cat = Sections.section_proof ["s1";"s2"]
637 `count a (s1 ++ s2) = count a s1 + count a s2`
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));
643 let has_cat = Sections.section_proof ["s1";"s2"]
644 `has a (s1 ++ s2) = (has a s1 \/ has a s2)`
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));
650 (* Lemma has_rcons *)
651 let has_rcons = Sections.section_proof ["s";"x"]
652 `has a (rcons s x) = (a x \/ has a s)`
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));
658 let all_cat = Sections.section_proof ["s1";"s2"]
659 `all a (s1 ++ s2) = (all a s1 /\ all a s2)`
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));
665 (* Lemma all_rcons *)
666 let all_rcons = Sections.section_proof ["s";"x"]
667 `all a (rcons s x) = (a x /\ all a s)`
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));
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)`;;
712 let eq_find = Sections.section_proof ["a1";"a2"]
713 `(!x:A. a1 x = a2 x) ==> (!s. find a1 s = find a2 s)`
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));
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)`
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));
726 let eq_count = Sections.section_proof ["a1";"a2"]
727 `(!x:A. a1 x = a2 x) ==> (!s. count a1 s = count a2 s)`
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));
733 let eq_has = Sections.section_proof ["a1";"a2"]
734 `(!x. a1 x = a2 x) ==> (!s. has a1 s = has a2 s)`
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));
740 let eq_all = Sections.section_proof ["a1";"a2"]
741 `(!x. a1 x = a2 x) ==> (!s. all a1 s = all a2 s)`
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));
746 (* Lemma filter_pred0 *)
747 let filter_pred0 = Sections.section_proof ["s"]
748 `filter pred0 s = []`
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));
754 (* Lemma filter_predT *)
755 let filter_predT = Sections.section_proof ["s"]
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));
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)`
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));
773 (* Lemma count_pred0 *)
774 let count_pred0 = Sections.section_proof ["s"]
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));
780 (* Lemma count_predT *)
781 let count_predT = Sections.section_proof ["s"]
782 `count predT s = sizel s`
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));
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)`
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));
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)`
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));
804 (* Lemma has_pred0 *)
805 let has_pred0 = Sections.section_proof ["s"]
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));
811 (* Lemma has_predT *)
812 let has_predT = Sections.section_proof ["s"]
813 `has predT s = (0 < sizel s)`
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));
818 (* Lemma has_predC *)
819 let has_predC = Sections.section_proof ["a";"s"]
820 `has (predC a) s = ~ all a s`
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));
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)`
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));
835 (* Lemma all_pred0 *)
836 let all_pred0 = Sections.section_proof ["s"]
837 `all pred0 s = (sizel s = 0)`
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));
842 (* Lemma all_predT *)
843 let all_predT = Sections.section_proof ["s"]
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));
849 (* Lemma all_predC *)
850 let all_predC = Sections.section_proof ["a";"s"]
851 `all (predC a) s = ~ has a s`
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));
858 let can_inj = Sections.section_proof ["f";"g"]
859 `(!x. g (f x) = x) ==> (!x y. f x = f y ==> x = y)`
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));
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`
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));
871 let drop = define `!n x s. dropl (SUC n) (x :: s) = dropl n s /\
872 dropl n [] = [] /\ dropl 0 s = s`;;
875 let eq_ext = Sections.section_proof ["f";"g"]
876 `(!x. f x = g x) <=> f = g`
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));
883 let drop_nil = Sections.section_proof ["n"]
886 ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
890 let drop0 = Sections.section_proof []
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));
896 (* Lemma drop_cons *)
897 let drop_cons = Sections.section_proof ["n";"x";"s"]
898 `dropl (SUC n) (x :: s) = dropl n s`
900 ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
903 (* Lemma drop_behead *)
904 let drop_behead = Sections.section_proof []
905 `dropl n0 = iter n0 behead`
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));
912 let drop0 = Sections.section_proof ["s"]
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));
919 let drop1 = Sections.section_proof ["s"]
920 `dropl 1 s = behead s`
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));
925 (* Lemma drop_oversize *)
926 let drop_oversize = Sections.section_proof ["n";"s"]
927 `sizel s <= n ==> dropl n s = []`
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));
933 (* Lemma drop_size *)
934 let drop_size = Sections.section_proof ["s"]
935 `dropl (sizel s) s = []`
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));
940 (* Lemma size_drop *)
941 let size_drop = Sections.section_proof ["s"]
942 `sizel (dropl n0 s) = sizel s - n0`
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));
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`
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));
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`
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));
966 let nconsK = Sections.section_proof ["n";"x";"s"]
967 `dropl n (ncons n x s) = s`
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));
971 let take = define `!x s n. take (SUC n) (x :: s) = x :: take n s /\
972 take 0 s = [] /\ take n [] = []`;;
975 let take0 = Sections.section_proof ["s"]
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));
981 (* Lemma take_oversize *)
982 let take_oversize = Sections.section_proof ["n";"s"]
983 `sizel s <= n ==> take n s = s`
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));
990 (* Lemma take_size *)
991 let take_size = Sections.section_proof ["s"]
992 `take (sizel s) s = s`
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));
997 (* Lemma take_cons *)
998 let take_cons = Sections.section_proof ["x";"s"]
999 `take (SUC n0) (x :: s) = x :: (take n0 s)`
1001 ((((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1004 (* Lemma drop_rcons *)
1005 let drop_rcons = Sections.section_proof ["s"]
1007 !x. dropl n0 (rcons s x) = rcons (dropl n0 s) x`
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));
1014 let congr1 = Sections.section_proof ["f";"x";"y"]
1015 `x = y ==> f x = f y`
1017 ((BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac));
1020 (* Lemma cat_take_drop *)
1021 let cat_take_drop = Sections.section_proof ["s"]
1022 `take n0 s ++ dropl n0 s = s`
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));
1028 (* Lemma size_takel *)
1029 let size_takel = Sections.section_proof ["s"]
1030 `n0 <= sizel s ==> sizel (take n0 s) = n0`
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));
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`
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));
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`
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));
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`
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));
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)`
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));
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)`
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));
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`
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));
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`
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));
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)`
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));
1107 let rot = new_definition `rot n s = dropl n s ++ take n s`;;
1110 let rot0 = Sections.section_proof ["s"]
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));
1116 (* Lemma size_rot *)
1117 let size_rot = Sections.section_proof ["s"]
1118 `sizel (rot n0 s) = sizel s`
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));
1123 (* Lemma rot_oversize *)
1124 let rot_oversize = Sections.section_proof ["n";"s"]
1125 `sizel s <= n ==> rot n s = s`
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));
1130 (* Lemma rot_size *)
1131 let rot_size = Sections.section_proof ["s"]
1132 `rot (sizel s) s = s`
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));
1138 let has_rot = Sections.section_proof ["s";"a"]
1139 `has a (rot n0 s) = has a s`
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));
1144 (* Lemma rot_size_cat *)
1145 let rot_size_cat = Sections.section_proof ["s1";"s2"]
1146 `rot (sizel s1) (s1 ++ s2) = s2 ++ s1`
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));
1150 let rotr = new_definition `rotr n s = rot (sizel s - n) s`;;
1153 let rotK = Sections.section_proof ["s"]
1154 `rotr n0 (rot n0 s) = s`
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));
1161 let rot_inj = Sections.section_proof ["s1";"s2"]
1162 `rot n0 (s1:(A)list) = rot n0 s2 ==> s1 = s2`
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));
1167 (* Lemma rot1_cons *)
1168 let rot1_cons = Sections.section_proof ["x";"s"]
1169 `rot 1 (x :: s) = rcons s x`
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));
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 []`;;
1320 Sections.begin_section "Rev";;
1321 (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("t", (`:(A)list`))));;
1323 (* Lemma catrev_catl *)
1324 let catrev_catl = Sections.section_proof ["s";"t";"u"]
1325 `catrev (s ++ t) u = catrev t (catrev s u)`
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));
1330 (* Lemma catrev_catr *)
1331 let catrev_catr = Sections.section_proof ["s";"t";"u"]
1332 `catrev s (t ++ u) = catrev s t ++ u`
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));
1339 let catrevE = Sections.section_proof ["s";"t"]
1340 `catrev s t = rev s ++ t`
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));
1345 (* Lemma rev_cons *)
1346 let rev_cons = Sections.section_proof ["x";"s"]
1347 `rev (x :: s) = rcons (rev s) x`
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));
1352 (* Lemma size_rev *)
1353 let size_rev = Sections.section_proof ["s"]
1354 `sizel (rev s) = sizel s`
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));
1361 let rev_cat = Sections.section_proof ["s";"t"]
1362 `rev (s ++ t) = rev t ++ rev s`
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));
1367 (* Lemma rev_rcons *)
1368 let rev_rcons = Sections.section_proof ["s";"x"]
1369 `rev (rcons s x) = x :: rev s`
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));
1375 let revK = Sections.section_proof ["s"]
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));
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)`
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));
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";;
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`))));;
1414 (* Lemma eqseq_cons *)
1415 let eqseq_cons = Sections.section_proof ["x1";"x2";"s1";"s2"]
1416 `((x1 :: s1) = x2 :: s2) <=> (x1 = x2 /\ s1 = s2)`
1418 ((((fun arg_tac -> arg_tac (Arg_theorem (injectivity "list")))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
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))`
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));
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)`
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));
1439 (* Lemma has_filter *)
1440 let has_filter = Sections.section_proof ["a";"s"]
1441 `has a s <=> ~(filter a s = [])`
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));
1449 (* Lemma size_eq0 *)
1450 let size_eq0 = Sections.section_proof ["s"]
1451 `(sizel s = 0) <=> (s = [])`
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));
1455 parse_as_infix("<-", (11, "right"));;
1456 override_interface("<-", `MEM`);;
1459 let in_cons = Sections.section_proof ["y";"s";"x"]
1460 `(x <- y :: s) <=> (x = y \/ x <- s)`
1462 ((repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1466 let in_nil = Sections.section_proof ["x"]
1469 ((repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac));
1472 (* Lemma mem_seq1 *)
1473 let mem_seq1 = Sections.section_proof ["x";"y"]
1474 `(x <- [y]) <=> (x = y)`
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));
1479 (* Lemma mem_seq2 *)
1480 let mem_seq2 = Sections.section_proof ["x";"y1";"y2"]
1481 `(x <- [y1; y2]) <=> (x = y1 \/ x = y2)`
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));
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)`
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));
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)`
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));
1501 let mem_cat = Sections.section_proof ["x";"s1";"s2"]
1502 `(x <- s1 ++ s2) <=> (x <- s1 \/ x <- s2)`
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));
1508 (* Lemma mem_rcons *)
1509 let mem_rcons = Sections.section_proof ["s";"y"]
1510 `!x. x <- rcons s y <=> x <- y :: s`
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));
1515 (* Lemma mem_head *)
1516 let mem_head = Sections.section_proof ["x";"s"]
1519 (((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac));
1522 (* Lemma mem_last *)
1523 let mem_last = Sections.section_proof ["x";"s"]
1524 `last x s <- x :: s`
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));
1529 (* Lemma mem_behead *)
1530 let mem_behead = Sections.section_proof ["s"]
1531 `!x. x <- behead s ==> x <- s`
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));
1536 (* Lemma mem_belast *)
1537 let mem_belast = Sections.section_proof ["s";"y"]
1538 `!x. x <- belast y s ==> x <- y :: s`
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));
1544 let mem_nth = Sections.section_proof ["s";"n"]
1545 `n < sizel s ==> nth x0 s n <- s`
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));
1552 (* Lemma mem_take *)
1553 let mem_take = Sections.section_proof ["s";"x"]
1554 `x <- take n0 s ==> x <- s`
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));
1559 (* Lemma mem_drop *)
1560 let mem_drop = Sections.section_proof ["s";"x"]
1561 `x <- dropl n0 s ==> x <- s`
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));
1567 let mem_rev = Sections.section_proof ["s"]
1568 `!x. x <- rev s <=> x <- s`
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));
1574 (* Section Filters *)
1575 Sections.begin_section "Filters";;
1576 (Sections.add_section_var (mk_var ("a", (`:A -> bool`))));;
1579 let hasP = Sections.section_proof ["s"]
1580 `(?x. x <- s /\ a x) <=> has a s`
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));
1592 let hasPn = Sections.section_proof ["s"]
1593 `(!x. x <- s ==> ~(a x)) <=> ~has a s`
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));
1602 let allP = Sections.section_proof ["s"]
1603 `(!x. x <- s ==> a x) <=> (all a s)`
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));
1616 let allPn = Sections.section_proof ["s"]
1617 `(?x. x <- s /\ ~a x) <=> ~all a s`
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));
1628 (* Lemma mem_filter *)
1629 let mem_filter = Sections.section_proof ["x";"s"]
1630 `(x <- filter a s) <=> (a x /\ x <- s)`
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));
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";;
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`
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));
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)`
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));
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)`
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));
1674 let has_sym = Sections.section_proof ["s1";"s2"]
1675 `has (\x. x <- s1) s2 = has (\x. x <- s2) s1`
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));
1680 (* Lemma has_pred1 *)
1681 let has_pred1 = Sections.section_proof ["x";"s"]
1682 `has (pred1 x) s <=> x <- s`
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));
1687 let constant = define `constant [] = T /\ constant (CONS x s') = all (pred1 x) s'`;;
1689 (* Lemma all_pred1P *)
1690 let all_pred1P = Sections.section_proof ["x";"s"]
1691 `(s = nseq (sizel s) x) <=> (all (pred1 x) s)`
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));
1699 (* Lemma all_pred1_constant *)
1700 let all_pred1_constant = Sections.section_proof ["x";"s"]
1701 `all (pred1 x) s ==> constant s`
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));
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)`
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));
1715 (* Lemma constant_nseq *)
1716 let constant_nseq = Sections.section_proof ["n";"x"]
1717 `constant (nseq n x)`
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));
1723 (* Lemma constantP *)
1724 let constantP = Sections.section_proof ["s"]
1725 `(?x. s = nseq (sizel s) x) <=> (constant s)`
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));
1732 let uniq = define `uniq [] = T /\ (uniq (x :: s') <=> ~(MEM x s') /\ uniq s')`;;
1734 (* Lemma nil_uniq *)
1735 let nil_uniq = Sections.section_proof []
1738 ((((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
1741 (* Lemma cons_uniq *)
1742 let cons_uniq = Sections.section_proof ["x";"s"]
1743 `uniq (x :: s) <=> ~(x <- s) /\ uniq s`
1745 ((((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
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`
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));
1757 (* Lemma uniq_catC *)
1758 let uniq_catC = Sections.section_proof ["s1";"s2"]
1759 `uniq (s1 ++ s2) = uniq (s2 ++ s1)`
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));
1764 (* Lemma uniq_catCA *)
1765 let uniq_catCA = Sections.section_proof ["s1";"s2";"s3"]
1766 `uniq (s1 ++ s2 ++ s3) = uniq (s2 ++ s1 ++ s3)`
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));
1772 (* Lemma rcons_uniq *)
1773 let rcons_uniq = Sections.section_proof ["s";"x"]
1774 `uniq (rcons s x) <=> (~(x <- s) /\ uniq s)`
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));
1779 (* Lemma filter_uniq *)
1780 let filter_uniq = Sections.section_proof ["s";"a"]
1781 `uniq s ==> uniq (filter a s)`
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));
1789 (* Lemma rot_uniq *)
1790 let rot_uniq = Sections.section_proof ["s"]
1791 `uniq (rot n0 s) = uniq s`
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));
1796 (* Lemma rev_uniq *)
1797 let rev_uniq = Sections.section_proof ["s"]
1798 `uniq (rev s) = uniq s`
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));
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`
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));
1814 let undup = define `undup [] = [] /\
1815 undup (x :: s') = if x <- s' then undup s' else x :: undup s'`;;
1817 (* Lemma size_undup *)
1818 let size_undup = Sections.section_proof ["s"]
1819 `sizel (undup s) <= sizel s`
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));
1825 (* Lemma mem_undup *)
1826 let mem_undup = Sections.section_proof ["s"]
1827 `!x. x <- undup s <=> x <- s`
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));
1834 (* Lemma undup_uniq *)
1835 let undup_uniq = Sections.section_proof ["s"]
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));
1842 (* Lemma undup_id *)
1843 let undup_id = Sections.section_proof ["s"]
1844 `uniq s ==> undup s = s`
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));
1850 (* Lemma ltn_size_undup *)
1851 let ltn_size_undup = Sections.section_proof ["s"]
1852 `(sizel (undup s) < sizel s) <=> ~ uniq s`
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));
1857 let index = new_definition `indexl x = find (pred1 x)`;;
1859 (* Lemma index_size *)
1860 let index_size = Sections.section_proof ["x";"s"]
1861 `indexl x s <= sizel s`
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));
1866 (* Lemma index_mem *)
1867 let index_mem = Sections.section_proof ["x";"s"]
1868 `(indexl x s < sizel s) <=> (x <- s)`
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));
1873 (* Lemma nth_index *)
1874 let nth_index = Sections.section_proof ["x";"s"]
1875 `x <- s ==> nth x0 s (indexl x s) = x`
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));
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`
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));
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`
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));
1899 (* Lemma index_head *)
1900 let index_head = Sections.section_proof ["x";"s"]
1901 `indexl x (x :: s) = 0`
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));
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`
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));
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)`
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));
1924 let mem_rot = Sections.section_proof ["s"]
1925 `!x. x <- rot n0 s <=> x <- s`
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));
1930 (* Lemma eqseq_rot *)
1931 let eqseq_rot = Sections.section_proof ["s1";"s2"]
1932 `(rot n0 s1 = rot n0 s2) <=> (s1 = s2)`
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));
1938 let rot_to = Sections.section_proof ["s";"x"]
1939 `x <- s ==> ?i s'. rot i s = x :: s'`
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));
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";;
2016 (* Section NseqthTheory *)
2017 Sections.begin_section "NseqthTheory";;
2018 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
2021 let nthP = Sections.section_proof ["s";"x";"x0"]
2022 `(?i. i < sizel s /\ nth x0 s i = x) <=> (x <- s)`
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));
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)`
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));
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)`
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));
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";;
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`
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));
2069 let headI = Sections.section_proof ["s";"x"]
2070 `rcons s x = headl x s :: behead (rcons s (x:A))`
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));
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]`;;
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`
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))));
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))));
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));
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`
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));
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)`;;
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)`
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));
2131 (* Lemma perm_eq_refl *)
2132 let perm_eq_refl = Sections.section_proof ["s"]
2135 ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (done_tac));
2138 (* Lemma perm_eq_sym *)
2139 let perm_eq_sym = Sections.section_proof []
2140 `!s1 s2. perm_eq s1 s2 = perm_eq s2 s1`
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));
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`
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));
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)`
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));
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)`
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));
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`
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));
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`
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));
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`
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));
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`
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));
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`
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));
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`
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));
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`
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));
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`
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));
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`
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));
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`
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));
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)`
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));
2253 (* Lemma perm_eq_size *)
2254 let perm_eq_size = Sections.section_proof ["s1";"s2"]
2255 `perm_eq s1 s2 ==> sizel s1 = sizel s2`
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));
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`
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));
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`
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));
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))`
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));
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`
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)));
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`
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));
2329 (* Lemma perm_eq_uniq *)
2330 let perm_eq_uniq = Sections.section_proof ["s1";"s2"]
2331 `perm_eq s1 s2 ==> uniq s1 = uniq s2`
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));
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`
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));
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`
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));
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";;
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`))));;
2389 (* Lemma size_rotr *)
2390 let size_rotr = Sections.section_proof ["s"]
2391 `sizel (rotr n0 s) = sizel s`
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));
2396 (* Lemma mem_rotr *)
2397 let mem_rotr = Sections.section_proof ["s"]
2398 `!x. x <- rotr n0 s <=> x <- s`
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));
2403 (* Lemma rotr_size_cat *)
2404 let rotr_size_cat = Sections.section_proof ["s1";"s2"]
2405 `rotr (sizel s2) (s1 ++ s2) = s2 ++ s1`
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));
2410 (* Lemma rotr1_rcons *)
2411 let rotr1_rcons = Sections.section_proof ["x";"s"]
2412 `rotr 1 (rcons s x) = x :: s`
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));
2417 (* Lemma has_rotr *)
2418 let has_rotr = Sections.section_proof ["a";"s"]
2419 `has a (rotr n0 s) = has a s`
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));
2424 (* Lemma rotr_uniq *)
2425 let rotr_uniq = Sections.section_proof ["s"]
2426 `uniq (rotr n0 s) = uniq s`
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));
2432 let rotrK = Sections.section_proof []
2433 `!s. rot n0 (rotr n0 s) = s`
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));
2442 (* Lemma rotr_inj *)
2443 let rotr_inj = Sections.section_proof ["s1";"s2"]
2444 `rotr n0 (s1:(A)list) = rotr n0 s2 ==> s1 = s2`
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));
2451 let rev_rot = Sections.section_proof ["s"]
2452 `rev (rot n0 s) = rotr n0 (rev s)`
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));
2458 (* Lemma rev_rotr *)
2459 let rev_rotr = Sections.section_proof ["s"]
2460 `rev (rotr n0 s) = rot n0 (rev s)`
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));
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";;
2484 (* Section RotCompLemmas *)
2485 Sections.begin_section "RotCompLemmas";;
2486 (Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
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)`
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));
2498 let rotS = Sections.section_proof ["n";"s"]
2499 `n < sizel s ==> rot (SUC n) s = rot 1 (rot n s)`
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));
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`
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));
2515 let rot_rot = Sections.section_proof ["m";"n";"s"]
2516 `rot m (rot n s) = rot n (rot m s)`
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));
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)`
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));
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)`
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));
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";;
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'`;;
2556 (* Lemma mask_false *)
2557 let mask_false = Sections.section_proof ["s";"n"]
2558 `mask (nseq n F) s = []`
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));
2563 (* Lemma mask_true *)
2564 let mask_true = Sections.section_proof ["s";"n"]
2565 `sizel s <= n ==> mask (nseq n T) s = s`
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));
2572 let mask0 = Sections.section_proof ["m"]
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));
2579 let mask1 = Sections.section_proof ["b";"x"]
2580 `mask [b] [x] = nseq (if b then 1 else 0) x`
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));
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`
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));
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`
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));
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`
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));
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)`
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));
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)`
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));
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";;
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`))));;
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)`
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));
2654 (* Lemma mem_mask *)
2655 let mem_mask = Sections.section_proof ["x";"m";"s"]
2656 `x <- mask m s ==> x <- s`
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));
2662 (* Lemma mask_uniq *)
2663 let mask_uniq = Sections.section_proof ["s"]
2664 `uniq s ==> !m. uniq (mask m s)`
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));
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)`
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));
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";;
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`;;
2694 let sub0seq = Sections.section_proof ["s"]
2697 ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
2701 let subseq0 = Sections.section_proof ["s"]
2702 `subseq s [] = (s = [])`
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));
2708 let subseqP = Sections.section_proof ["s1";"s2"]
2709 `subseq s1 s2 <=> (?m. sizel m = sizel s2 /\ s1 = mask m s2)`
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));
2744 (* Lemma subseq_trans *)
2745 let subseq_trans = Sections.section_proof ["s1";"s2";"s3"]
2746 `subseq s1 s2 ==> subseq s2 s3 ==> subseq s1 s3`
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));
2759 (* Lemma subseq_refl *)
2760 let subseq_refl = Sections.section_proof ["s"]
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));
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)`
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));
2774 (* Lemma mem_subseq *)
2775 let mem_subseq = Sections.section_proof ["s1";"s2"]
2776 `subseq s1 s2 ==> (!x. x <- s1 ==> x <- s2)`
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));
2781 (* Lemma subseq_seq1 *)
2782 let subseq_seq1 = Sections.section_proof ["x";"s"]
2783 `subseq [x] s <=> x <- s`
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));
2789 (* Lemma size_subseq *)
2790 let size_subseq = Sections.section_proof ["s1";"s2"]
2791 `subseq s1 s2 ==> sizel s1 <= sizel s2`
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));
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)`
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));
2810 (* Lemma subseq_cons *)
2811 let subseq_cons = Sections.section_proof ["s";"x"]
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));
2818 (* Lemma subseq_rcons *)
2819 let subseq_rcons = Sections.section_proof ["s";"x"]
2820 `subseq s (rcons s x)`
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));
2825 (* Lemma subseq_uniq *)
2826 let subseq_uniq = Sections.section_proof ["s1";"s2"]
2827 `subseq s1 s2 ==> uniq s2 ==> uniq s1`
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));
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";;
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 [] = []`;;
2857 let map_MAP = Sections.section_proof []
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));
2864 (* Lemma map_cons *)
2865 let map_cons = Sections.section_proof ["x";"s"]
2866 `map f (x :: s) = f x :: map f s`
2868 ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac));
2871 (* Lemma map_nseq *)
2872 let map_nseq = Sections.section_proof ["x"]
2873 `map f (nseq n0 x) = nseq n0 (f x)`
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));
2880 let map_cat = Sections.section_proof ["s1";"s2"]
2881 `map f (s1 ++ s2) = map f s1 ++ map f s2`
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));
2886 (* Lemma size_map *)
2887 let size_map = Sections.section_proof ["s"]
2888 `sizel (map f s) = sizel s`
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));
2894 (* Lemma behead_map *)
2895 let behead_map = Sections.section_proof ["s"]
2896 `behead (map f s) = map f (behead s)`
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));
2902 let nth_map = Sections.section_proof ["n";"s"]
2903 `n < sizel s ==> nth x2 (map f s) n = f (nth x1 s n)`
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));
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)`
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));
2916 (* Lemma last_map *)
2917 let last_map = Sections.section_proof ["s";"x"]
2918 `last (f x) (map f s) = f (last x s)`
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));
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)`
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));
2929 let preim = new_definition `preim (f:A->B) (a:B->bool) = (\x. a (f x))`;;
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)`
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));
2940 (* Lemma find_map *)
2941 let find_map = Sections.section_proof ["a";"s"]
2942 `find a (map f s) = find (preim f a) s`
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));
2949 let has_map = Sections.section_proof ["a";"s"]
2950 `has a (map f s) = has (preim f a) s`
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));
2957 let all_map = Sections.section_proof ["a";"s"]
2958 `all a (map f s) = all (preim f a) s`
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));
2964 (* Lemma count_map *)
2965 let count_map = Sections.section_proof ["a";"s"]
2966 `count a (map f s) = count (preim f a) s`
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));
2972 (* Lemma map_take *)
2973 let map_take = Sections.section_proof ["s"]
2974 `map f (take n0 s) = take n0 (map f s)`
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));
2979 (* Lemma map_drop *)
2980 let map_drop = Sections.section_proof ["s"]
2981 `map f (dropl n0 s) = dropl n0 (map f s)`
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));
2987 let map_rot = Sections.section_proof ["s"]
2988 `map f (rot n0 s) = rot n0 (map f s)`
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));
2993 (* Lemma map_rotr *)
2994 let map_rotr = Sections.section_proof ["s"]
2995 `map f (rotr n0 s) = rotr n0 (map f s)`
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));
3001 let map_rev = Sections.section_proof ["s"]
3002 `map f (rev s) = rev (map f s)`
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));
3007 (* Lemma map_mask *)
3008 let map_mask = Sections.section_proof ["m";"s"]
3009 `map f (mask m s) = mask m (map f s)`
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));
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)`
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));
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";;
3048 (* Lemma filter_mask *)
3049 let filter_mask = Sections.section_proof ["a";"s"]
3050 `filter (a:A->bool) s = mask (map a s) s`
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));
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`))));;
3061 (* Lemma filter_subseq *)
3062 let filter_subseq = Sections.section_proof ["a";"s"]
3063 `subseq (filter a s) s`
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));
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`
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));
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)`
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));
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";;
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`))));;
3104 let map_f = Sections.section_proof ["s";"x"]
3105 `x <- s ==> f x <- map f s`
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));
3112 let mapP = Sections.section_proof ["s";"y"]
3113 `(y <- map f s) <=> (?x. x <- s /\ y = f x)`
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));
3125 (* Lemma map_uniq *)
3126 let map_uniq = Sections.section_proof ["s"]
3127 `uniq (map f s) ==> uniq s`
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));
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`
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));
3154 (* Lemma map_subseq *)
3155 let map_subseq = Sections.section_proof ["s1";"s2"]
3156 `subseq s1 s2 ==> subseq (map f s1) (map f s2)`
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));
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";;
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`));;
3180 let inj_eq = Sections.section_proof ["x";"y"]
3181 `(f x = f y <=> x = y)`
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));
3187 let mem_map = Sections.section_proof ["s";"x"]
3188 `(f x <- map f s) = (x <- s)`
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));
3193 (* Lemma index_map *)
3194 let index_map = Sections.section_proof ["s";"x"]
3195 `indexl (f x) (map f s) = indexl x s`
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));
3201 (* Lemma map_inj_uniq *)
3202 let map_inj_uniq = Sections.section_proof ["s"]
3203 `uniq (map f s) = uniq s`
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));
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";;
3215 (* Section MapComp *)
3216 Sections.begin_section "MapComp";;
3219 let map_id = Sections.section_proof ["s"]
3220 `map I (s:(A)list) = s`
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));
3226 let eq_map = Sections.section_proof ["f1";"f2"]
3227 `(!x. (f1:A->B) x = f2 x) ==> map f1 = map f2`
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));
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)`
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));
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)`
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));
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";;
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`
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));
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`
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));
3271 let iota = define `iota m (SUC n) = m :: iota (SUC m) n /\ iota m 0 = []`;;
3273 (* Lemma size_iota *)
3274 let size_iota = Sections.section_proof ["m";"n"]
3275 `sizel (iota m n) = n`
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));
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`
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));
3289 (* Lemma iota_addl *)
3290 let iota_addl = Sections.section_proof ["m1";"m2";"n"]
3291 `iota (m1 + m2) n = map ((+) m1) (iota m2 n)`
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));
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`
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));
3305 (* Lemma mem_iota *)
3306 let mem_iota = Sections.section_proof ["m";"n";"i"]
3307 `(i <- iota m n) <=> (m <= i) /\ (i < m + n)`
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));
3317 (* Lemma iota_uniq *)
3318 let iota_uniq = Sections.section_proof ["m";"n"]
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));
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)`;;
3330 (* Lemma size_mkseq *)
3331 let size_mkseq = Sections.section_proof ["f";"n"]
3332 `sizel (mkseq f n) = n`
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));
3337 (* Lemma eq_mkseq *)
3338 let eq_mkseq = Sections.section_proof ["f";"g"]
3339 `(!x. f x = g x) ==> mkseq f = mkseq g`
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));
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`
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));
3353 (* Lemma mkseq_nth *)
3354 let mkseq_nth = Sections.section_proof ["s"]
3355 `mkseq (nth x0 s) (sizel s) = s`
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));
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";;
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)`
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));
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`;;
3381 (* Finalization of the section FoldRight *)
3382 Sections.end_section "FoldRight";;
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`))));;
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`
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));
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`
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));
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`;;
3411 let sumn0 = Sections.section_proof []
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));
3417 (* Lemma sumn_nseq *)
3418 let sumn_nseq = Sections.section_proof ["x";"n"]
3419 `sumn (nseq n x) = x * n`
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));
3425 (* Lemma sumn_cat *)
3426 let sumn_cat = Sections.section_proof ["s1";"s2"]
3427 `sumn (s1 ++ s2) = sumn s1 + sumn s2`
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));
3433 (* Lemma natnseq0P *)
3434 let natnseq0P = Sections.section_proof ["s"]
3435 `sumn s = 0 <=> s = nseq (sizel s) 0`
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));
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`;;
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`
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));
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`
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));
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";;
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 [] = []`;;
3477 (* Lemma size_pairmap *)
3478 let size_pairmap = Sections.section_proof ["x";"s"]
3479 `sizel (pairmap f x s) = sizel s`
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));
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`
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));
3493 (* Lemma nth_pairmap *)
3494 let nth_pairmap = Sections.section_proof ["s";"n"]
3496 !x. nth x2 (pairmap f x s) n = f (nth x1 (x :: s) n) (nth x1 s n)`
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));
3501 let scanl = define `scanl g x (y :: s) = g x y :: scanl g (g x y) s /\ scanl g x [] = []`;;
3503 (* Lemma size_scanl *)
3504 let size_scanl = Sections.section_proof ["x";"s"]
3505 `sizel (scanl g x s) = sizel s`
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));
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`
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));
3518 (* Lemma nth_scanl *)
3519 let nth_scanl = Sections.section_proof ["s";"n"]
3521 !x. nth x1 (scanl g x s) n = foldl g x (take (SUC n) s)`
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));
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)`
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));
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)`
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));
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";;
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`;;
3561 (* Lemma zip_unzip *)
3562 let zip_unzip = Sections.section_proof ["s"]
3563 `zip (unzip1 s) (unzip2 s) = s`
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));
3569 (* Lemma unzip1_zip *)
3570 let unzip1_zip = Sections.section_proof ["s";"t"]
3571 `sizel s <= sizel t ==> unzip1 (zip s t) = s`
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));
3577 (* Lemma unzip2_zip *)
3578 let unzip2_zip = Sections.section_proof ["s";"t"]
3579 `sizel t <= sizel s ==> unzip2 (zip s t) = t`
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));
3585 (* Lemma size1_zip *)
3586 let size1_zip = Sections.section_proof ["s";"t"]
3587 `sizel s <= sizel t ==> sizel (zip s t) = sizel s`
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));
3593 (* Lemma size2_zip *)
3594 let size2_zip = Sections.section_proof ["s";"t"]
3595 `sizel t <= sizel s ==> sizel (zip s t) = sizel t`
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));
3601 (* Lemma size_zip *)
3602 let size_zip = Sections.section_proof ["s";"t"]
3603 `sizel (zip s t) = minn (sizel s) (sizel t)`
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));
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`
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));
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)`
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));
3625 (* Lemma nth_zip_cond *)
3626 let nth_zip_cond = Sections.section_proof ["p";"s";"t";"i"]
3628 = (if i < sizel (zip s t) then (nth (FST p) s i, nth (SND p) t i) else p)`
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));
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)`
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));
3644 let rev_zip = Sections.section_proof ["s1";"s2"]
3645 `sizel s1 = sizel s2 ==> rev (zip s1 s2) = zip (rev s1) (rev s2)`
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));
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";;
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 = []`;;
3675 (* Lemma flatten0 *)
3676 let flatten0 = Sections.section_proof []
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));
3682 (* Lemma flatten_cons *)
3683 let flatten_cons = Sections.section_proof ["s";"ss"]
3684 `flatten (s :: ss) = s ++ flatten ss`
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));
3689 (* Lemma size_flatten *)
3690 let size_flatten = Sections.section_proof ["ss"]
3691 `sizel (flatten ss) = sumn (shape ss)`
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));
3697 (* Lemma flatten_cat *)
3698 let flatten_cat = Sections.section_proof ["ss1";"ss2"]
3699 `flatten (ss1 ++ ss2) = flatten ss1 ++ flatten ss2`
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));
3705 (* Lemma flattenK *)
3706 let flattenK = Sections.section_proof ["ss"]
3707 `reshape (shape ss) (flatten ss) = ss`
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));
3713 (* Lemma reshapeKr *)
3714 let reshapeKr = Sections.section_proof ["sh";"s"]
3715 `sizel s <= sumn sh ==> flatten (reshape sh s) = s`
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));
3724 (* Lemma reshapeKl *)
3725 let reshapeKl = Sections.section_proof ["sh";"s"]
3726 `sumn sh <= sizel s ==> shape (reshape sh s) = sh`
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));
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";;
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`;;
3753 (* Lemma size_allpairs *)
3754 let size_allpairs = Sections.section_proof ["s";"t"]
3755 `sizel (allpairs f s t) = sizel s * sizel t`
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));
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`
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));
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";;
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`))));;
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))`
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));
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)`
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));
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`
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));
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";;
3820 (* Close the module *)