needs "Examples/ssrnat-compiled.hl";;

(* Module Seq*)
module Seq = struct

open Ssrfun;;
open Ssrbool;;
open Ssrnat;;
prioritize_num();;

(* Section Sequences *)
Sections.begin_section "Sequences";;
(Sections.add_section_var (mk_var ("n0", (`:num`))));;
(Sections.add_section_var (mk_var ("x0", (`:A`))));;
(Sections.add_section_type (mk_var ("x", (`:A`))); Sections.add_section_type (mk_var ("y", (`:A`))); Sections.add_section_type (mk_var ("z", (`:A`))));;
(Sections.add_section_type (mk_var ("m", (`:num`))); Sections.add_section_type (mk_var ("n", (`:num`))));;
(Sections.add_section_type (mk_var ("s", (`:(A)list`))));;
let size = new_definition `sizel = LENGTH`;;
(* Lemma size0nil *) let size0nil = Sections.section_proof ["s"] `sizel s = 0 ==> s = []` [ (((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)); ];;
let nilp = new_definition `!(s:(A)list). nilp s <=> (sizel s = 0)`;;
(* Lemma nilP *) let nilP = Sections.section_proof ["s"] `s = [] <=> nilp s` [ (((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)); ];;
let head = define `!(x0:A) h t. headl x0 [] = x0 /\ headl x0 (CONS h t) = h`;;
let behead = define `!(h:A) t. behead [] = [] /\ behead (CONS h t) = t`;;
(* Lemma size_behead *) let size_behead = Sections.section_proof ["s"] `sizel (behead s) = (sizel s) - 1` [ (((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)); ];;
let ncons = new_definition `!n (x:A). ncons n x = iter n (CONS x)`;;
let nseq = new_definition `!n (x:A). nseq n x = ncons n x []`;;
(* Lemma size_nil *) let size_nil = Sections.section_proof [] `sizel ([]:(A)list) = 0` [ (((((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)); ];; (* Lemma size_cons *) let size_cons = Sections.section_proof ["h";"t"] `sizel (CONS (h:A) t) = SUC (sizel t)` [ (((((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)); ];; (* Lemma size_ncons *) let size_ncons = Sections.section_proof ["n";"x";"s"] `sizel (ncons n x s) = n + sizel s` [ ((((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"]))); (((((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)); ];; (* Lemma size_nseq *) let size_nseq = Sections.section_proof ["n";"x"] `sizel (nseq n (x:A)) = n` [ (((((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)); ];; parse_as_infix ("::", (12, "right"));; override_interface ("::", `CONS`);; make_overloadable "++" `:A -> A -> A`;;
let cat = define `!(x:A) t s2. cat [] s2 = s2 /\ cat (CONS x t) s2 = x :: cat t s2`;;
overload_interface ("++", `cat`);; (* Lemma cat0s *) let cat0s = Sections.section_proof ["s"] `[] ++ (s:(A)list) = s` [ ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma cat1s *) let cat1s = Sections.section_proof ["x";"s"] `[x:A] ++ s = x :: s` [ ((repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma cat_cons *) let cat_cons = Sections.section_proof ["x";"s1";"s2"] `(x :: s1) ++ s2 = x :: s1 ++ s2` [ ((((use_arg_then2 ("cat", [cat]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma cat_nseq *) let cat_nseq = Sections.section_proof ["n";"x";"s"] `nseq n (x:A) ++ s = ncons n x s` [ ((((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)); ];; (* Lemma cats0 *) let cats0 = Sections.section_proof ["s"] `s ++ [] = (s:(A)list)` [ (((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)); ];; (* Lemma catA *) let catA = Sections.section_proof ["s1";"s2";"s3"] `s1 ++ s2 ++ s3 = (s1 ++ s2) ++ s3:(A)list` [ (((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)); ];; (* Lemma size_cat *) let size_cat = Sections.section_proof ["s1";"s2"] `sizel (s1 ++ s2) = sizel s1 + sizel (s2:(A)list)` [ (((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)); ];;
let rcons = define `!x t (z:A). rcons [] z = [z] /\ rcons (x :: t) z = x :: rcons t z`;;
(* Lemma rcons_cons *) let rcons_cons = Sections.section_proof ["x";"s";"z"] `rcons (x :: s) z = x:A :: rcons s z` [ ((((use_arg_then2 ("rcons", [rcons]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma cats1 *) let cats1 = Sections.section_proof ["s";"z"] `s ++ [z:A] = rcons s z` [ (((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)); ];;
let last = define `!(x:A) h t. last x [] = x /\ last x (h :: t) = last h t`;;
let belast = define `!(x:A) h t. belast x [] = [] /\ belast x (h :: t) = x :: (belast h t)`;;
(* Lemma lastI *) let lastI = Sections.section_proof ["x";"s"] `(x:A :: s) = rcons (belast x s) (last x s)` [ (((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)); ];; (* Lemma last_cons *) let last_cons = Sections.section_proof ["x";"y";"s"] `last x (y:A :: s) = last y s` [ ((((use_arg_then2 ("last", [last]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma size_rcons *) let size_rcons = Sections.section_proof ["s";"x"] `sizel (rcons s (x:A)) = SUC (sizel s)` [ (((((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)); ];; (* Lemma size_belast *) let size_belast = Sections.section_proof ["x";"s"] `sizel (belast (x:A) s) = sizel s` [ (((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)); ];; (* Lemma last_cat *) let last_cat = Sections.section_proof ["x";"s1";"s2"] `last (x:A) (s1 ++ s2) = last (last x s1) s2` [ (((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)); ];; (* Lemma last_rcons *) let last_rcons = Sections.section_proof ["x";"s";"z"] `last x (rcons s z) = z:A` [ (((((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)); ];; (* Lemma belast_cat *) let belast_cat = Sections.section_proof ["x";"s1";"s2"] `belast x (s1 ++ s2) = belast x s1 ++ belast (last (x:A) s1) s2` [ (((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)); ];; (* Lemma belast_rcons *) let belast_rcons = Sections.section_proof ["x";"s";"z"] `belast x (rcons s z) = x:A :: s` [ (((((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)); ];; (* Lemma cat_rcons *) let cat_rcons = Sections.section_proof ["x";"s1";"s2"] `rcons s1 x ++ s2 = s1 ++ (x:A :: s2)` [ (((((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)); ];; (* Lemma rcons_cat *) let rcons_cat = Sections.section_proof ["x";"s1";"s2"] `rcons (s1 ++ s2) x = s1 ++ rcons s2 (x:A)` [ (((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)); ];; (* Lemma last_ind *) let last_ind = Sections.section_proof ["P"] `P [] ==> (!s (x : A). P s ==> P (rcons s x)) ==> (!s. P s)` [ (BETA_TAC THEN (move ["Hnil"]) THEN (move ["Hlast"]) THEN (move ["s"])); (((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 [] []))))); ((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))); (((((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)); ];;
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`;;
let set_nth = define `!(x0:A) h t n y. 
	set_nth x0 [] n y = ncons n x0 [y] /\
	set_nth x0 (h :: t) 0 y = y :: t /\
	set_nth x0 (h :: t) (SUC n) y = h :: set_nth x0 t n y`;;
(* Lemma nth0 *) let nth0 = Sections.section_proof ["s"] `nth x0 s 0 = headl x0 s` [ (((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)); ];; (* Lemma nth_default *) let nth_default = Sections.section_proof ["s";"n"] `sizel s <= n ==> nth x0 s n = x0` [ ((((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)))); (((((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)); ];; (* Lemma nth_nil *) let nth_nil = Sections.section_proof ["n"] `nth x0 [] n = x0` [ (((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)); ];; (* Lemma last_nth *) let last_nth = Sections.section_proof ["x";"s"] `last x s = nth x0 (x :: s) (sizel s)` [ ((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)); (((((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)); ];; (* Lemma nth_last *) let nth_last = Sections.section_proof ["s"] `nth x0 s (sizel s - 1) = last x0 s` [ (((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)); ];; (* Lemma nth_behead *) let nth_behead = Sections.section_proof ["s";"n"] `nth x0 (behead s) n = nth x0 s (SUC n)` [ (((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)); ];; (* Lemma nth_cat *) let nth_cat = Sections.section_proof ["s1";"s2";"n"] `nth x0 (s1 ++ s2) n = if n < sizel s1 then nth x0 s1 n else nth x0 s2 (n - sizel s1)` [ ((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]); (((((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)); ];; (* Lemma nth_rcons *) let nth_rcons = Sections.section_proof ["s";"x";"n"] `nth x0 (rcons s x) n = if n < sizel s then nth x0 s n else if n = sizel s then x else x0` [ ((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))); (((((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)); ];; (* Lemma nth_ncons *) let nth_ncons = Sections.section_proof ["m";"x";"s";"n"] `nth x0 (ncons m x s) n = if n < m then x else nth x0 s (n - m)` [ ((((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)))); (((((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)); ];; (* Lemma nth_nseq *) let nth_nseq = Sections.section_proof ["m";"x";"n"] `nth x0 (nseq m x) n = (if n < m then x else x0)` [ ((((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)))); (((((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)); ];; (* Lemma eq_from_nth *) let eq_from_nth = Sections.section_proof ["s1";"s2"] `sizel s1 = sizel s2 ==> (!i. i < sizel s1 ==> nth x0 s1 i = nth x0 s2 i) ==> s1 = s2` [ ((((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)))); ((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq_sz"]) THEN (move ["eq_s12"])); ((((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"]))); ((((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)); ];; (* Lemma size_set_nth *) let size_set_nth = Sections.section_proof ["s";"n";"y"] `sizel (set_nth x0 s n y) = maxn (SUC n) (sizel s)` [ (((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])))); (((((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)); (((((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)); ((((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)); (((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)); ];; (* Lemma set_nth_nil *) let set_nth_nil = Sections.section_proof ["n";"y"] `set_nth x0 [] n y = ncons n x0 [y]` [ (((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)); ];; (* Lemma ltS0 *) let ltS0 = Sections.section_proof ["n"] `SUC n < 0 <=> F` [ ((arith_tac) THEN (done_tac)); ];; (* Lemma eqS0 *) let eqS0 = Sections.section_proof ["n"] `SUC n = 0 <=> F` [ ((arith_tac) THEN (done_tac)); ];; (* Lemma eq0S *) let eq0S = Sections.section_proof ["n"] `0 = SUC n <=> F` [ ((arith_tac) THEN (done_tac)); ];; (* Lemma gtS0 *) let gtS0 = Sections.section_proof ["n"] `0 < SUC n` [ ((arith_tac) THEN (done_tac)); ];; (* Lemma ltSS *) let ltSS = Sections.section_proof ["m";"n"] `SUC m < SUC n <=> m < n` [ ((arith_tac) THEN (done_tac)); ];; (* Lemma nth_set_nth *) let nth_set_nth = Sections.section_proof ["s";"n";"y";"i"] `nth x0 (set_nth x0 s n y) i = if i = n then y else nth x0 s i` [ ((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]))))))); (((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ((((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 [] []))))); ((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))); (((((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)); ((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))); (((((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)); ];; (* Lemma set_set_nth *) let set_set_nth = Sections.section_proof ["s";"n1";"y1";"n2";"y2"] `set_nth x0 (set_nth x0 s n1 y1) n2 y2 = if n1 = n2 then set_nth x0 s n2 y2 else set_nth x0 (set_nth x0 s n2 y2) n1 y1` [ ((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"])]); ((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))); ((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)); ((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))); ((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))); (((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)); (((((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)); (((((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)); ];; (* Section SeqFind *) Sections.begin_section "SeqFind";; (Sections.add_section_var (mk_var ("a", (`:A -> bool`))));;
let find = define `!a (x:A) s'. find a [] = 0 /\ 
	find a (x :: s') = if a x then 0 else SUC(find a s')`;;
let filter = define `!a (x:A) s'. filter a [] = [] /\
	filter a (x :: s') = if a x then x :: filter a s' else filter a s'`;;
let count = define `!a (x:A) s'. count a [] = 0 /\
	count a (x :: s') = (if a x then 1 else 0) + count a s'`;;
let has = define `!a (x:A) s'. has a [] = F /\
	has a (x :: s') = (a x \/ has a s')`;;
let all = define `!a (x:A) s'. all a [] = T /\
	all a (x :: s') = (a x /\ all a s')`;;
(* Lemma find_nil *) let find_nil = Sections.section_proof [] `find a [] = 0` [ ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma find_cons *) let find_cons = Sections.section_proof ["x";"t"] `find a (x::t) = if a x then 0 else SUC (find a t)` [ ((((use_arg_then2 ("find", [find]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma filter_nil *) let filter_nil = Sections.section_proof [] `filter a [] = []` [ ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma filter_cons *) let filter_cons = Sections.section_proof ["x";"t"] `filter a (x::t) = if a x then x :: filter a t else filter a t` [ ((((use_arg_then2 ("filter", [filter]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma count_nil *) let count_nil = Sections.section_proof [] `count a [] = 0` [ ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma count_cons *) let count_cons = Sections.section_proof ["x";"t"] `count a (x::t) = (if a x then 1 else 0) + count a t` [ ((((use_arg_then2 ("count", [count]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma has_nil *) let has_nil = Sections.section_proof [] `has a [] = F` [ ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma has_cons *) let has_cons = Sections.section_proof ["x";"t"] `has a (x::t) <=> a x \/ has a t` [ ((((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma all_nil *) let all_nil = Sections.section_proof [] `all a [] = T` [ ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma all_cons *) let all_cons = Sections.section_proof ["x";"t"] `all a (x::t) <=> a x /\ all a t` [ ((((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma count_filter *) let count_filter = Sections.section_proof ["s"] `count a s = sizel (filter a s)` [ (((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 [] [])))))); (((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))); (((((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)); ];; (* Lemma has_count *) let has_count = Sections.section_proof ["s"] `has a s = (0 < count a s)` [ (((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)); ];; (* Lemma count_size *) let count_size = Sections.section_proof ["s"] `count a s <= sizel s` [ (((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]))))); ((((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))); ];; (* Lemma all_count *) let all_count = Sections.section_proof ["s"] `all a s = (count a s = sizel s)` [ (((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)))); ((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))); (((((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)); ];; (* Lemma filter_all *) let filter_all = Sections.section_proof ["s"] `all a (filter a s)` [ (((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]))))); ((((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)); ];; (* Lemma all_filterP *) let all_filterP = Sections.section_proof ["s"] `(filter a s = s) <=> (all a s)` [ ((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))); (((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))); ((((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)); ];; (* Lemma filter_id *) let filter_id = Sections.section_proof ["s"] `filter a (filter a s) = filter a s` [ (((((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)); ];; (* Lemma has_find *) let has_find = Sections.section_proof ["s"] `has a s <=> (find a s < sizel s)` [ (((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)))); ((((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)); ];; (* Lemma find_size *) let find_size = Sections.section_proof ["s"] `find a s <= sizel s` [ (((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]))))); ((((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)); ];; (* Lemma find_cat *) let find_cat = Sections.section_proof ["s1";"s2"] `find a (s1 ++ s2) = if has a s1 then find a s1 else sizel s1 + find a s2` [ (((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)))); (((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 ["_"])); (((((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)); ];; (* Lemma has_nil *) let has_nil = Sections.section_proof [] `has a [] = F` [ ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma has_seq1 *) let has_seq1 = Sections.section_proof ["x"] `has a [x] = a x` [ ((repeat_tactic 1 9 (((use_arg_then2 ("has", [has]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma has_seqb *) let has_seqb = Sections.section_proof ["b";"x"] `has a (nseq (if b then 1 else 0) x) <=> (b /\ a x)` [ ((((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)); ];; (* Lemma all_nil *) let all_nil = Sections.section_proof [] `all a [] = T` [ ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma all_seq1 *) let all_seq1 = Sections.section_proof ["x"] `all a [x] = a x` [ ((repeat_tactic 1 9 (((use_arg_then2 ("all", [all]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma nth_find *) let nth_find = Sections.section_proof ["s"] `has a s ==> a (nth x0 s (find a s))` [ (((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]))))); ((((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)); ];; (* Lemma before_find *) let before_find = Sections.section_proof ["s";"i"] `i < find a s ==> (a (nth x0 s i) <=> F)` [ (((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)))); ((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))); (((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]))))); (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("IHs", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac)); ];; (* Lemma filter_cat *) let filter_cat = Sections.section_proof ["s1";"s2"] `filter a (s1 ++ s2) = filter a s1 ++ filter a s2` [ (((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)))); ((((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)); ];; (* Lemma filter_rcons *) let filter_rcons = Sections.section_proof ["s";"x"] `filter a (rcons s x) = if a x then rcons (filter a s) x else filter a s` [ (((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]))))); ((((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)); ];; (* Lemma count_cat *) let count_cat = Sections.section_proof ["s1";"s2"] `count a (s1 ++ s2) = count a s1 + count a s2` [ (((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)); ];; (* Lemma has_cat *) let has_cat = Sections.section_proof ["s1";"s2"] `has a (s1 ++ s2) = (has a s1 \/ has a s2)` [ (((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))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orbA", [orbA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma has_rcons *) let has_rcons = Sections.section_proof ["s";"x"] `has a (rcons s x) = (a x \/ has a s)` [ (((((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)); ];; (* Lemma all_cat *) let all_cat = Sections.section_proof ["s1";"s2"] `all a (s1 ++ s2) = (all a s1 /\ all a s2)` [ (((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))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbA", [andbA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma all_rcons *) let all_rcons = Sections.section_proof ["s";"x"] `all a (rcons s x) = (a x /\ all a s)` [ (((((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)); ];; (* Finalization of the section SeqFind *) let find_nil = Sections.finalize_theorem find_nil;; let find_cons = Sections.finalize_theorem find_cons;; let filter_nil = Sections.finalize_theorem filter_nil;; let filter_cons = Sections.finalize_theorem filter_cons;; let count_nil = Sections.finalize_theorem count_nil;; let count_cons = Sections.finalize_theorem count_cons;; let has_nil = Sections.finalize_theorem has_nil;; let has_cons = Sections.finalize_theorem has_cons;; let all_nil = Sections.finalize_theorem all_nil;; let all_cons = Sections.finalize_theorem all_cons;; let count_filter = Sections.finalize_theorem count_filter;; let has_count = Sections.finalize_theorem has_count;; let count_size = Sections.finalize_theorem count_size;; let all_count = Sections.finalize_theorem all_count;; let filter_all = Sections.finalize_theorem filter_all;; let all_filterP = Sections.finalize_theorem all_filterP;; let filter_id = Sections.finalize_theorem filter_id;; let has_find = Sections.finalize_theorem has_find;; let find_size = Sections.finalize_theorem find_size;; let find_cat = Sections.finalize_theorem find_cat;; let has_nil = Sections.finalize_theorem has_nil;; let has_seq1 = Sections.finalize_theorem has_seq1;; let has_seqb = Sections.finalize_theorem has_seqb;; let all_nil = Sections.finalize_theorem all_nil;; let all_seq1 = Sections.finalize_theorem all_seq1;; let nth_find = Sections.finalize_theorem nth_find;; let before_find = Sections.finalize_theorem before_find;; let filter_cat = Sections.finalize_theorem filter_cat;; let filter_rcons = Sections.finalize_theorem filter_rcons;; let count_cat = Sections.finalize_theorem count_cat;; let has_cat = Sections.finalize_theorem has_cat;; let has_rcons = Sections.finalize_theorem has_rcons;; let all_cat = Sections.finalize_theorem all_cat;; let all_rcons = Sections.finalize_theorem all_rcons;; Sections.end_section "SeqFind";;
let pred1 = new_definition `pred1 (a:A) = (\x. x = a)`;;
let predD1 = new_definition `predD1 a x = predD a (pred1 x)`;;
(* Lemma eq_find *) let eq_find = Sections.section_proof ["a1";"a2"] `(!x:A. a1 x = a2 x) ==> (!s. find a1 s = find a2 s)` [ (((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)); ];; (* Lemma eq_filter *) let eq_filter = Sections.section_proof ["a1";"a2"] `(!x:A. a1 x = a2 x) ==> (!s. filter a1 s = filter a2 s)` [ (((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)); ];; (* Lemma eq_count *) let eq_count = Sections.section_proof ["a1";"a2"] `(!x:A. a1 x = a2 x) ==> (!s. count a1 s = count a2 s)` [ (((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)); ];; (* Lemma eq_has *) let eq_has = Sections.section_proof ["a1";"a2"] `(!x. a1 x = a2 x) ==> (!s. has a1 s = has a2 s)` [ (((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)); ];; (* Lemma eq_all *) let eq_all = Sections.section_proof ["a1";"a2"] `(!x. a1 x = a2 x) ==> (!s. all a1 s = all a2 s)` [ (((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)); ];; (* Lemma filter_pred0 *) let filter_pred0 = Sections.section_proof ["s"] `filter pred0 s = []` [ (((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))); (((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("pred0", [pred0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma filter_predT *) let filter_predT = Sections.section_proof ["s"] `filter predT s = s` [ (((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))); (((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [2] []))))) THEN (((use_arg_then2 ("predT", [predT]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma filter_predI *) let filter_predI = Sections.section_proof ["a1";"a2";"s"] `filter (predI a1 a2) s = filter a1 (filter a2 s)` [ (((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]))))); ((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))); ((((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])))); (((((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)); (((((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)); ];; (* Lemma count_pred0 *) let count_pred0 = Sections.section_proof ["s"] `count pred0 s = 0` [ (((((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)); ];; (* Lemma count_predT *) let count_predT = Sections.section_proof ["s"] `count predT s = sizel s` [ (((((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)); ];; (* Lemma count_predUI *) let count_predUI = Sections.section_proof ["a1";"a2";"s"] `count (predU a1 a2) s + count (predI a1 a2) s = count a1 s + count a2 (s:(A)list)` [ (((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]))))); ((((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)); ];; (* Lemma count_predC *) let count_predC = Sections.section_proof ["a";"s"] `count a s + count (predC a) s = sizel (s:(A)list)` [ (((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))); ((((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 [] []))))); ((((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)); ];; (* Lemma has_pred0 *) let has_pred0 = Sections.section_proof ["s"] `has pred0 s = F` [ (((((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)); ];; (* Lemma has_predT *) let has_predT = Sections.section_proof ["s"] `has predT s = (0 < sizel s)` [ (((((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)); ];; (* Lemma has_predC *) let has_predC = Sections.section_proof ["a";"s"] `has (predC a) s = ~ all a s` [ (((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])))))); (((((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)); ];; (* Lemma has_predU *) let has_predU = Sections.section_proof ["a1";"a2";"s"] `has (predU a1 a2) s <=> (has a1 s \/ has a2 s)` [ (((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))); ((((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 [] []))))))); ((((use_arg_then2 ("orbCA", [orbCA]))(thm_tac (new_rewrite [] [(`has a1 s \/ _ \/ _1`)])))) THEN (done_tac)); ];; (* Lemma all_pred0 *) let all_pred0 = Sections.section_proof ["s"] `all pred0 s = (sizel s = 0)` [ (((((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)); ];; (* Lemma all_predT *) let all_predT = Sections.section_proof ["s"] `all predT s` [ (((((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)); ];; (* Lemma all_predC *) let all_predC = Sections.section_proof ["a";"s"] `all (predC a) s = ~ has a s` [ (((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])))))); (((((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)); ];; (* Lemma can_inj *) let can_inj = Sections.section_proof ["f";"g"] `(!x. g (f x) = x) ==> (!x y. f x = f y ==> x = y)` [ (BETA_TAC THEN (move ["h"]) THEN (move ["x"]) THEN (move ["y"]) THEN (move ["f_eq"])); (((((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)); ];; (* Lemma all_predI *) let all_predI = Sections.section_proof ["a1";"a2";"s"] `all (predI a1 a2) s <=> all a1 s /\ all a2 s` [ ((((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)); ];;
let drop = define `!n x s. dropl (SUC n) (x :: s) = dropl n s /\ 
	dropl n [] = [] /\ dropl 0 s = s`;;
(* Lemma eq_ext *) let eq_ext = Sections.section_proof ["f";"g"] `(!x. f x = g x) <=> f = g` [ ((THENL_FIRST) ((split_tac) THEN (move ["h"])) ((MATCH_MP_TAC EQ_EXT) THEN (done_tac))); ((((use_arg_then2 ("h", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma drop_nil *) let drop_nil = Sections.section_proof ["n"] `dropl n [] = []` [ ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma drop0 *) let drop0 = Sections.section_proof [] `dropl 0 = I` [ (((((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)); ];; (* Lemma drop_cons *) let drop_cons = Sections.section_proof ["n";"x";"s"] `dropl (SUC n) (x :: s) = dropl n s` [ ((((use_arg_then2 ("drop", [drop]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma drop_behead *) let drop_behead = Sections.section_proof [] `dropl n0 = iter n0 behead` [ ((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))); (((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)); ];; (* Lemma drop0 *) let drop0 = Sections.section_proof ["s"] `dropl 0 s = s` [ (((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)); ];; (* Lemma drop1 *) let drop1 = Sections.section_proof ["s"] `dropl 1 s = behead s` [ (((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)); ];; (* Lemma drop_oversize *) let drop_oversize = Sections.section_proof ["n";"s"] `sizel s <= n ==> dropl n s = []` [ (((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)))); (((((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)); ];; (* Lemma drop_size *) let drop_size = Sections.section_proof ["s"] `dropl (sizel s) s = []` [ (((((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)); ];; (* Lemma size_drop *) let size_drop = Sections.section_proof ["s"] `sizel (dropl n0 s) = sizel s - n0` [ (((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)))); (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma drop_cat *) let drop_cat = Sections.section_proof ["s1";"s2"] `dropl n0 (s1 ++ s2) = if n0 < sizel s1 then dropl n0 s1 ++ s2 else dropl (n0 - sizel s1) s2` [ (((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))); (((((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)); ];; (* Lemma drop_size_cat *) let drop_size_cat = Sections.section_proof ["n";"s1";"s2"] `sizel s1 = n ==> dropl n (s1 ++ s2) = s2` [ ((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)))); (((((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)); ];; (* Lemma nconsK *) let nconsK = Sections.section_proof ["n";"x";"s"] `dropl n (ncons n x s) = s` [ (((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)); ];;
let take = define `!x s n. take (SUC n) (x :: s) = x :: take n s /\
	take 0 s = [] /\ take n [] = []`;;
(* Lemma take0 *) let take0 = Sections.section_proof ["s"] `take 0 s = []` [ (((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)); ];; (* Lemma take_oversize *) let take_oversize = Sections.section_proof ["n";"s"] `sizel s <= n ==> take n s = s` [ (((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))); (((((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)); ((((((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)); ];; (* Lemma take_size *) let take_size = Sections.section_proof ["s"] `take (sizel s) s = s` [ (((((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)); ];; (* Lemma take_cons *) let take_cons = Sections.section_proof ["x";"s"] `take (SUC n0) (x :: s) = x :: (take n0 s)` [ ((((use_arg_then2 ("take", [take]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma drop_rcons *) let drop_rcons = Sections.section_proof ["s"] `n0 <= sizel s ==> !x. dropl n0 (rcons s x) = rcons (dropl n0 s) x` [ (((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))); (((((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)); ];; (* Lemma congr1 *) let congr1 = Sections.section_proof ["f";"x";"y"] `x = y ==> f x = f y` [ ((BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma cat_take_drop *) let cat_take_drop = Sections.section_proof ["s"] `take n0 s ++ dropl n0 s = s` [ (((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))); ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma size_takel *) let size_takel = Sections.section_proof ["s"] `n0 <= sizel s ==> sizel (take n0 s) = n0` [ (((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)); ];; (* Lemma size_take *) let size_take = Sections.section_proof ["s"] `sizel (take n0 s) = if n0 < sizel s then n0 else sizel s` [ (((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"])])); (((((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)); (((((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)); ];; (* Lemma take_cat *) let take_cat = Sections.section_proof ["s1";"s2"] `take n0 (s1 ++ s2) = if n0 < sizel s1 then take n0 s1 else s1 ++ take (n0 - sizel s1) s2` [ (((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))); (((((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)); ];; (* Lemma take_size_cat *) let take_size_cat = Sections.section_proof ["n";"s1";"s2"] `sizel s1 = n ==> take n (s1 ++ s2) = s1` [ ((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]))))); ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma takel_cat *) let takel_cat = Sections.section_proof ["s1"] `n0 <= sizel (s1:(A)list) ==> (!s2. take n0 (s1 ++ s2) = take n0 s1)` [ (BETA_TAC THEN (move ["Hn0"]) THEN (move ["s2"])); ((((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 [] []))))); (((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"])); (((((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)); ];; (* Lemma nth_drop *) let nth_drop = Sections.section_proof ["s";"i"] `nth x0 (dropl n0 s) i = nth x0 s (n0 + i)` [ (((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"])])); ((((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 [] []))))); (((((use_arg_then2 ("ltnNge", [ltnNge]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_addr", [leq_addr]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((repeat_tactic 1 9 (((use_arg_then2 ("nth_default", [nth_default]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))); ((((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)); ((((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)); ];; (* Lemma nth_take *) let nth_take = Sections.section_proof ["i"] `i < n0 ==> !s. nth x0 (take n0 s) i = nth x0 s i` [ ((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"]))); (((((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)); (((((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)); ];; (* Lemma drop_nth *) let drop_nth = Sections.section_proof ["n";"s"] `n < sizel s ==> dropl n s = nth x0 s n :: dropl (SUC n) s` [ (((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))); (((((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)); ];; (* Lemma take_nth *) let take_nth = Sections.section_proof ["n";"s"] `n < sizel s ==> take (SUC n) s = rcons (take n s) (nth x0 s n)` [ (((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))); (((((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)); ];;
let rot = new_definition `rot n s = dropl n s ++ take n s`;;
(* Lemma rot0 *) let rot0 = Sections.section_proof ["s"] `rot 0 s = s` [ (((((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)); ];; (* Lemma size_rot *) let size_rot = Sections.section_proof ["s"] `sizel (rot n0 s) = sizel s` [ (((((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)); ];; (* Lemma rot_oversize *) let rot_oversize = Sections.section_proof ["n";"s"] `sizel s <= n ==> rot n s = s` [ ((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)); ];; (* Lemma rot_size *) let rot_size = Sections.section_proof ["s"] `rot (sizel s) s = s` [ ((((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)); ];; (* Lemma has_rot *) let has_rot = Sections.section_proof ["s";"a"] `has a (rot n0 s) = has a s` [ (((((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)); ];; (* Lemma rot_size_cat *) let rot_size_cat = Sections.section_proof ["s1";"s2"] `rot (sizel s1) (s1 ++ s2) = s2 ++ s1` [ (((((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)); ];;
let rotr = new_definition `rotr n s = rot (sizel s - n) s`;;
(* Lemma rotK *) let rotK = Sections.section_proof ["s"] `rotr n0 (rot n0 s) = s` [ ((((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 _`)]))))); (((((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)); ];; (* Lemma rot_inj *) let rot_inj = Sections.section_proof ["s1";"s2"] `rot n0 (s1:(A)list) = rot n0 s2 ==> s1 = s2` [ ((((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)); ];; (* Lemma rot1_cons *) let rot1_cons = Sections.section_proof ["x";"s"] `rot 1 (x :: s) = rcons s x` [ (((((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)); ];; (* Finalization of the section Sequences *) let size0nil = Sections.finalize_theorem size0nil;; let nilP = Sections.finalize_theorem nilP;; let size_behead = Sections.finalize_theorem size_behead;; let size_nil = Sections.finalize_theorem size_nil;; let size_cons = Sections.finalize_theorem size_cons;; let size_ncons = Sections.finalize_theorem size_ncons;; let size_nseq = Sections.finalize_theorem size_nseq;; let cat0s = Sections.finalize_theorem cat0s;; let cat1s = Sections.finalize_theorem cat1s;; let cat_cons = Sections.finalize_theorem cat_cons;; let cat_nseq = Sections.finalize_theorem cat_nseq;; let cats0 = Sections.finalize_theorem cats0;; let catA = Sections.finalize_theorem catA;; let size_cat = Sections.finalize_theorem size_cat;; let rcons_cons = Sections.finalize_theorem rcons_cons;; let cats1 = Sections.finalize_theorem cats1;; let lastI = Sections.finalize_theorem lastI;; let last_cons = Sections.finalize_theorem last_cons;; let size_rcons = Sections.finalize_theorem size_rcons;; let size_belast = Sections.finalize_theorem size_belast;; let last_cat = Sections.finalize_theorem last_cat;; let last_rcons = Sections.finalize_theorem last_rcons;; let belast_cat = Sections.finalize_theorem belast_cat;; let belast_rcons = Sections.finalize_theorem belast_rcons;; let cat_rcons = Sections.finalize_theorem cat_rcons;; let rcons_cat = Sections.finalize_theorem rcons_cat;; let last_ind = Sections.finalize_theorem last_ind;; let nth0 = Sections.finalize_theorem nth0;; let nth_default = Sections.finalize_theorem nth_default;; let nth_nil = Sections.finalize_theorem nth_nil;; let last_nth = Sections.finalize_theorem last_nth;; let nth_last = Sections.finalize_theorem nth_last;; let nth_behead = Sections.finalize_theorem nth_behead;; let nth_cat = Sections.finalize_theorem nth_cat;; let nth_rcons = Sections.finalize_theorem nth_rcons;; let nth_ncons = Sections.finalize_theorem nth_ncons;; let nth_nseq = Sections.finalize_theorem nth_nseq;; let eq_from_nth = Sections.finalize_theorem eq_from_nth;; let size_set_nth = Sections.finalize_theorem size_set_nth;; let set_nth_nil = Sections.finalize_theorem set_nth_nil;; let ltS0 = Sections.finalize_theorem ltS0;; let eqS0 = Sections.finalize_theorem eqS0;; let eq0S = Sections.finalize_theorem eq0S;; let gtS0 = Sections.finalize_theorem gtS0;; let ltSS = Sections.finalize_theorem ltSS;; let nth_set_nth = Sections.finalize_theorem nth_set_nth;; let set_set_nth = Sections.finalize_theorem set_set_nth;; let find_nil = Sections.finalize_theorem find_nil;; let find_cons = Sections.finalize_theorem find_cons;; let filter_nil = Sections.finalize_theorem filter_nil;; let filter_cons = Sections.finalize_theorem filter_cons;; let count_nil = Sections.finalize_theorem count_nil;; let count_cons = Sections.finalize_theorem count_cons;; let has_nil = Sections.finalize_theorem has_nil;; let has_cons = Sections.finalize_theorem has_cons;; let all_nil = Sections.finalize_theorem all_nil;; let all_cons = Sections.finalize_theorem all_cons;; let count_filter = Sections.finalize_theorem count_filter;; let has_count = Sections.finalize_theorem has_count;; let count_size = Sections.finalize_theorem count_size;; let all_count = Sections.finalize_theorem all_count;; let filter_all = Sections.finalize_theorem filter_all;; let all_filterP = Sections.finalize_theorem all_filterP;; let filter_id = Sections.finalize_theorem filter_id;; let has_find = Sections.finalize_theorem has_find;; let find_size = Sections.finalize_theorem find_size;; let find_cat = Sections.finalize_theorem find_cat;; let has_nil = Sections.finalize_theorem has_nil;; let has_seq1 = Sections.finalize_theorem has_seq1;; let has_seqb = Sections.finalize_theorem has_seqb;; let all_nil = Sections.finalize_theorem all_nil;; let all_seq1 = Sections.finalize_theorem all_seq1;; let nth_find = Sections.finalize_theorem nth_find;; let before_find = Sections.finalize_theorem before_find;; let filter_cat = Sections.finalize_theorem filter_cat;; let filter_rcons = Sections.finalize_theorem filter_rcons;; let count_cat = Sections.finalize_theorem count_cat;; let has_cat = Sections.finalize_theorem has_cat;; let has_rcons = Sections.finalize_theorem has_rcons;; let all_cat = Sections.finalize_theorem all_cat;; let all_rcons = Sections.finalize_theorem all_rcons;; let eq_find = Sections.finalize_theorem eq_find;; let eq_filter = Sections.finalize_theorem eq_filter;; let eq_count = Sections.finalize_theorem eq_count;; let eq_has = Sections.finalize_theorem eq_has;; let eq_all = Sections.finalize_theorem eq_all;; let filter_pred0 = Sections.finalize_theorem filter_pred0;; let filter_predT = Sections.finalize_theorem filter_predT;; let filter_predI = Sections.finalize_theorem filter_predI;; let count_pred0 = Sections.finalize_theorem count_pred0;; let count_predT = Sections.finalize_theorem count_predT;; let count_predUI = Sections.finalize_theorem count_predUI;; let count_predC = Sections.finalize_theorem count_predC;; let has_pred0 = Sections.finalize_theorem has_pred0;; let has_predT = Sections.finalize_theorem has_predT;; let has_predC = Sections.finalize_theorem has_predC;; let has_predU = Sections.finalize_theorem has_predU;; let all_pred0 = Sections.finalize_theorem all_pred0;; let all_predT = Sections.finalize_theorem all_predT;; let all_predC = Sections.finalize_theorem all_predC;; let can_inj = Sections.finalize_theorem can_inj;; let all_predI = Sections.finalize_theorem all_predI;; let eq_ext = Sections.finalize_theorem eq_ext;; let drop_nil = Sections.finalize_theorem drop_nil;; let drop0 = Sections.finalize_theorem drop0;; let drop_cons = Sections.finalize_theorem drop_cons;; let drop_behead = Sections.finalize_theorem drop_behead;; let drop0 = Sections.finalize_theorem drop0;; let drop1 = Sections.finalize_theorem drop1;; let drop_oversize = Sections.finalize_theorem drop_oversize;; let drop_size = Sections.finalize_theorem drop_size;; let size_drop = Sections.finalize_theorem size_drop;; let drop_cat = Sections.finalize_theorem drop_cat;; let drop_size_cat = Sections.finalize_theorem drop_size_cat;; let nconsK = Sections.finalize_theorem nconsK;; let take0 = Sections.finalize_theorem take0;; let take_oversize = Sections.finalize_theorem take_oversize;; let take_size = Sections.finalize_theorem take_size;; let take_cons = Sections.finalize_theorem take_cons;; let drop_rcons = Sections.finalize_theorem drop_rcons;; let congr1 = Sections.finalize_theorem congr1;; let cat_take_drop = Sections.finalize_theorem cat_take_drop;; let size_takel = Sections.finalize_theorem size_takel;; let size_take = Sections.finalize_theorem size_take;; let take_cat = Sections.finalize_theorem take_cat;; let take_size_cat = Sections.finalize_theorem take_size_cat;; let takel_cat = Sections.finalize_theorem takel_cat;; let nth_drop = Sections.finalize_theorem nth_drop;; let nth_take = Sections.finalize_theorem nth_take;; let drop_nth = Sections.finalize_theorem drop_nth;; let take_nth = Sections.finalize_theorem take_nth;; let rot0 = Sections.finalize_theorem rot0;; let size_rot = Sections.finalize_theorem size_rot;; let rot_oversize = Sections.finalize_theorem rot_oversize;; let rot_size = Sections.finalize_theorem rot_size;; let has_rot = Sections.finalize_theorem has_rot;; let rot_size_cat = Sections.finalize_theorem rot_size_cat;; let rotK = Sections.finalize_theorem rotK;; let rot_inj = Sections.finalize_theorem rot_inj;; let rot1_cons = Sections.finalize_theorem rot1_cons;; Sections.end_section "Sequences";;
let catrev = define `catrev (x :: s1) s2 = catrev s1 (x :: s2) /\ catrev [] s2 = s2`;;
let rev = new_definition `rev s = catrev s []`;;
(* Section Rev *) Sections.begin_section "Rev";; (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("t", (`:(A)list`))));; (* Lemma catrev_catl *) let catrev_catl = Sections.section_proof ["s";"t";"u"] `catrev (s ++ t) u = catrev t (catrev s u)` [ ((((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)); ];; (* Lemma catrev_catr *) let catrev_catr = Sections.section_proof ["s";"t";"u"] `catrev s (t ++ u) = catrev s t ++ u` [ (((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))); (((((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)); ];; (* Lemma catrevE *) let catrevE = Sections.section_proof ["s";"t"] `catrev s t = rev s ++ t` [ (((((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)); ];; (* Lemma rev_cons *) let rev_cons = Sections.section_proof ["x";"s"] `rev (x :: s) = rcons (rev s) x` [ (((((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)); ];; (* Lemma size_rev *) let size_rev = Sections.section_proof ["s"] `sizel (rev s) = sizel s` [ (((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))); (((((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)); ];; (* Lemma rev_cat *) let rev_cat = Sections.section_proof ["s";"t"] `rev (s ++ t) = rev t ++ rev s` [ (((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)); ];; (* Lemma rev_rcons *) let rev_rcons = Sections.section_proof ["s";"x"] `rev (rcons s x) = x :: rev s` [ (((((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)); ];; (* Lemma revK *) let revK = Sections.section_proof ["s"] `rev (rev s) = s` [ ((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))); (((((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)); ];; (* Lemma nth_rev *) let nth_rev = Sections.section_proof ["x0";"n";"s"] `n < sizel s ==> nth x0 (rev s) n = nth x0 s (sizel s - SUC n)` [ ((((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))); (((((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"])); ((((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 [] []))))); ((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))); (BETA_TAC THEN (move ["lt_n_s"])); ((((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))); ((((use_arg_then2 ("nth", [nth]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Finalization of the section Rev *) let catrev_catl = Sections.finalize_theorem catrev_catl;; let catrev_catr = Sections.finalize_theorem catrev_catr;; let catrevE = Sections.finalize_theorem catrevE;; let rev_cons = Sections.finalize_theorem rev_cons;; let size_rev = Sections.finalize_theorem size_rev;; let rev_cat = Sections.finalize_theorem rev_cat;; let rev_rcons = Sections.finalize_theorem rev_rcons;; let revK = Sections.finalize_theorem revK;; let nth_rev = Sections.finalize_theorem nth_rev;; Sections.end_section "Rev";; (* Section EqSeq *) Sections.begin_section "EqSeq";; (Sections.add_section_var (mk_var ("n0", (`:num`))));; (Sections.add_section_var (mk_var ("x0", (`:A`))));; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (Sections.add_section_type (mk_var ("x", (`:A`))); Sections.add_section_type (mk_var ("y", (`:A`))); Sections.add_section_type (mk_var ("z", (`:A`))));; (* Lemma eqseq_cons *) let eqseq_cons = Sections.section_proof ["x1";"x2";"s1";"s2"] `((x1 :: s1) = x2 :: s2) <=> (x1 = x2 /\ s1 = s2)` [ ((((fun arg_tac -> arg_tac (Arg_theorem (injectivity "list")))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma eqseq_cat *) let eqseq_cat = Sections.section_proof ["s1";"s2";"s3";"s4"] `sizel s1 = sizel s2 ==> (s1 ++ s3 = s2 ++ s4 <=> (s1 = s2 /\ s3 = s4))` [ ((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]); (((((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)); ];; (* Lemma eqseq_rcons *) let eqseq_rcons = Sections.section_proof ["s1";"s2";"x1";"x2"] `(rcons s1 x1 = rcons s2 x2) <=> (s1 = s2 /\ x1 = x2)` [ ((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)))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbA", [andbA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((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)); (((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)); ];; (* Lemma has_filter *) let has_filter = Sections.section_proof ["a";"s"] `has a s <=> ~(filter a s = [])` [ ((((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] []))))); ((fun arg_tac -> arg_tac (Arg_term (`filter a s`))) (term_tac (set_tac "l"))); (((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 [] [])))))); (((((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)); ];; (* Lemma size_eq0 *) let size_eq0 = Sections.section_proof ["s"] `(sizel s = 0) <=> (s = [])` [ (((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)); ];; parse_as_infix("<-", (11, "right"));; override_interface("<-", `MEM`);; (* Lemma in_cons *) let in_cons = Sections.section_proof ["y";"s";"x"] `(x <- y :: s) <=> (x = y \/ x <- s)` [ ((repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma in_nil *) let in_nil = Sections.section_proof ["x"] `(x <- []) = F` [ ((repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg])))) THEN (done_tac)); ];; (* Lemma mem_seq1 *) let mem_seq1 = Sections.section_proof ["x";"y"] `(x <- [y]) <=> (x = y)` [ (((((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)); ];; (* Lemma mem_seq2 *) let mem_seq2 = Sections.section_proof ["x";"y1";"y2"] `(x <- [y1; y2]) <=> (x = y1 \/ x = y2)` [ (((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)); ];; (* Lemma mem_seq3 *) let mem_seq3 = Sections.section_proof ["x";"y1";"y2";"y3"] `(x <- [y1; y2; y3]) <=> (x = y1 \/ x = y2 \/ x = y3)` [ (((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)); ];; (* Lemma mem_seq4 *) let mem_seq4 = Sections.section_proof ["x";"y1";"y2";"y3";"y4"] `(x <- [y1; y2; y3; y4]) <=> (x = y1 \/ x = y2 \/ x = y3 \/ x = y4)` [ (((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)); ];; (* Lemma mem_cat *) let mem_cat = Sections.section_proof ["x";"s1";"s2"] `(x <- s1 ++ s2) <=> (x <- s1 \/ x <- s2)` [ ((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))); (((((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)); ];; (* Lemma mem_rcons *) let mem_rcons = Sections.section_proof ["s";"y"] `!x. x <- rcons s y <=> x <- y :: s` [ ((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)); ];; (* Lemma mem_head *) let mem_head = Sections.section_proof ["x";"s"] `x <- x :: s` [ (((((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac)); ];; (* Lemma mem_last *) let mem_last = Sections.section_proof ["x";"s"] `last x s <- x :: s` [ (((((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)); ];; (* Lemma mem_behead *) let mem_behead = Sections.section_proof ["s"] `!x. x <- behead s ==> x <- s` [ (((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)); ];; (* Lemma mem_belast *) let mem_belast = Sections.section_proof ["s";"y"] `!x. x <- belast y s ==> x <- y :: s` [ ((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)); ];; (* Lemma mem_nth *) let mem_nth = Sections.section_proof ["s";"n"] `n < sizel s ==> nth x0 s n <- s` [ (((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))); (((((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"])); ((((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)); ];; (* Lemma mem_take *) let mem_take = Sections.section_proof ["s";"x"] `x <- take n0 s ==> x <- s` [ ((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)); ];; (* Lemma mem_drop *) let mem_drop = Sections.section_proof ["s";"x"] `x <- dropl n0 s ==> x <- s` [ ((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)); ];; (* Lemma mem_rev *) let mem_rev = Sections.section_proof ["s"] `!x. x <- rev s <=> x <- s` [ ((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))); (((((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)); ];; (* Section Filters *) Sections.begin_section "Filters";; (Sections.add_section_var (mk_var ("a", (`:A -> bool`))));; (* Lemma hasP *) let hasP = Sections.section_proof ["s"] `(?x. x <- s /\ a x) <=> has a s` [ (((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])))))); ((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))); ((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"])))))))); (((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)); (((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 [] []))))); (((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"])); ((((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)); ];; (* Lemma hasPn *) let hasPn = Sections.section_proof ["s"] `(!x. x <- s ==> ~(a x)) <=> ~has a s` [ ((THENL_ROT (1)) ((split_tac) THEN (move ["not_a_s"]))); ((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"]))); ((((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac)); ((((((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)); ];; (* Lemma allP *) let allP = Sections.section_proof ["s"] `(!x. x <- s ==> a x) <=> (all a s)` [ (((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)))); ((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))); (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"])])); (((use_arg_then2 ("h", [])) (disch_tac [])) THEN (clear_assumption "h") THEN (exact_tac)); (BETA_TAC THEN (move ["h"])); ((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"]))); ((((((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)); (((use_arg_then2 ("h", [])) (disch_tac [])) THEN (clear_assumption "h") THEN (exact_tac)); ];; (* Lemma allPn *) let allPn = Sections.section_proof ["s"] `(?x. x <- s /\ ~a x) <=> ~all a s` [ (((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]))))); (((((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)); (BETA_TAC THEN (case THEN ((move ["y"]) THEN (case THEN ((move ["ay"]) THEN ((THENL) case [(move ["eq"]); (move ["mem"])])))))); ((((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)); ((DISJ2_TAC) THEN ((use_arg_then2 ("y", [])) (term_tac exists_tac)) THEN (done_tac)); ((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))); (((use_arg_then2 ("y", [])) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma mem_filter *) let mem_filter = Sections.section_proof ["x";"s"] `(x <- filter a s) <=> (a x /\ x <- s)` [ ((((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)))); ((((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 [] []))))); ((((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)); ];; (* Finalization of the section Filters *) let hasP = Sections.finalize_theorem hasP;; let hasPn = Sections.finalize_theorem hasPn;; let allP = Sections.finalize_theorem allP;; let allPn = Sections.finalize_theorem allPn;; let mem_filter = Sections.finalize_theorem mem_filter;; Sections.end_section "Filters";; (* Lemma eq_in_filter *) let eq_in_filter = Sections.section_proof ["a1";"a2";"s"] `(!x. x <- s ==> a1 x = a2 x) ==> filter a1 s = filter a2 s` [ (((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"]))); (((((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"])); ((((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)); ];; (* Lemma eq_has_r *) let eq_has_r = Sections.section_proof ["s1";"s2"] `(!x. x <- s1 <=> x <- s2) ==> (!a. has a s1 <=> has a s2)` [ (BETA_TAC THEN (move ["Es12"]) THEN (move ["a"])); ((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"]))))))); (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("Es12", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("Es12", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma eq_all_r *) let eq_all_r = Sections.section_proof ["s1";"s2"] `(!x. x <- s1 <=> x <- s2) ==> (!a. all a s1 = all a s2)` [ ((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"]))); ((((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)); ((((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)); ];; (* Lemma has_sym *) let has_sym = Sections.section_proof ["s1";"s2"] `has (\x. x <- s1) s2 = has (\x. x <- s2) s1` [ (((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)); ];; (* Lemma has_pred1 *) let has_pred1 = Sections.section_proof ["x";"s"] `has (pred1 x) s <=> x <- s` [ (((((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"])])); (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac)); ];;
let constant = define `constant [] = T /\ constant (CONS x s') = all (pred1 x) s'`;;
(* Lemma all_pred1P *) let all_pred1P = Sections.section_proof ["x";"s"] `(s = nseq (sizel s) x) <=> (all (pred1 x) s)` [ (((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]))))); ((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"])])); (((((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)); (((((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)); ];; (* Lemma all_pred1_constant *) let all_pred1_constant = Sections.section_proof ["x";"s"] `all (pred1 x) s ==> constant s` [ ((((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)); ];; (* Lemma all_pred1_nseq *) let all_pred1_nseq = Sections.section_proof ["x";"y";"n"] `all (pred1 x) (nseq n y) <=> (n = 0 \/ x = y)` [ (((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)))); (((((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 [] [])))))); (((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)); ];; (* Lemma constant_nseq *) let constant_nseq = Sections.section_proof ["n";"x"] `constant (nseq n x)` [ (((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)))); (((((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)); ];; (* Lemma constantP *) let constantP = Sections.section_proof ["s"] `(?x. s = nseq (sizel s) x) <=> (constant s)` [ ((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))); ((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))); (((((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))); ((((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)); ];;
let uniq = define `uniq [] = T /\ (uniq (x :: s') <=> ~(MEM x s') /\ uniq s')`;;
(* Lemma nil_uniq *) let nil_uniq = Sections.section_proof [] `uniq ([]:(A)list)` [ ((((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma cons_uniq *) let cons_uniq = Sections.section_proof ["x";"s"] `uniq (x :: s) <=> ~(x <- s) /\ uniq s` [ ((((use_arg_then2 ("uniq", [uniq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma cat_uniq *) let cat_uniq = Sections.section_proof ["s1";"s2"] `uniq (s1 ++ s2) <=> uniq s1 /\ ~ has (\x. x <- s1) s2 /\ uniq s2` [ ((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))); ((((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)); ((((use_arg_then2 ("andbAC", [andbAC]))(thm_tac (new_rewrite [] [(`_ /\ uniq s1`)])))) THEN (done_tac)); ];; (* Lemma uniq_catC *) let uniq_catC = Sections.section_proof ["s1";"s2"] `uniq (s1 ++ s2) = uniq (s2 ++ s1)` [ (((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)); ];; (* Lemma uniq_catCA *) let uniq_catCA = Sections.section_proof ["s1";"s2";"s3"] `uniq (s1 ++ s2 ++ s3) = uniq (s2 ++ s1 ++ s3)` [ (repeat_tactic 1 9 (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] []))))); (((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)); ];; (* Lemma rcons_uniq *) let rcons_uniq = Sections.section_proof ["s";"x"] `uniq (rcons s x) <=> (~(x <- s) /\ uniq s)` [ (((((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)); ];; (* Lemma filter_uniq *) let filter_uniq = Sections.section_proof ["s";"a"] `uniq s ==> uniq (filter a s)` [ (((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)))); ((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"])))))); (((((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)); ((((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)); ];; (* Lemma rot_uniq *) let rot_uniq = Sections.section_proof ["s"] `uniq (rot n0 s) = uniq s` [ (((((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)); ];; (* Lemma rev_uniq *) let rev_uniq = Sections.section_proof ["s"] `uniq (rev s) = uniq s` [ ((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))); (((((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)); ];; (* Lemma count_uniq_mem *) let count_uniq_mem = Sections.section_proof ["s";"x"] `uniq s ==> count (pred1 x) s = if (x <- s) then 1 else 0` [ (((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))); ((((((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 [] [])))))); ((((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`)]))))); (((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)))); ((((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];;
let undup = define `undup [] = [] /\ 
	undup (x :: s') = if x <- s' then undup s' else x :: undup s'`;;
(* Lemma size_undup *) let size_undup = Sections.section_proof ["s"] `sizel (undup s) <= sizel s` [ (((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)))); ((((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)); ];; (* Lemma mem_undup *) let mem_undup = Sections.section_proof ["s"] `!x. x <- undup s <=> x <- s` [ ((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)))); ((((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)))); ((((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)); ];; (* Lemma undup_uniq *) let undup_uniq = Sections.section_proof ["s"] `uniq (undup s)` [ (((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)))); ((((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)); ];; (* Lemma undup_id *) let undup_id = Sections.section_proof ["s"] `uniq s ==> undup s = s` [ (((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"]))))); ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma ltn_size_undup *) let ltn_size_undup = Sections.section_proof ["s"] `(sizel (undup s) < sizel s) <=> ~ uniq s` [ (((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)))); ((((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)); ];;
let index = new_definition `indexl x = find (pred1 x)`;;
(* Lemma index_size *) let index_size = Sections.section_proof ["x";"s"] `indexl x s <= sizel s` [ (((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("find_size", [find_size]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma index_mem *) let index_mem = Sections.section_proof ["x";"s"] `(indexl x s < sizel s) <=> (x <- s)` [ (((((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)); ];; (* Lemma nth_index *) let nth_index = Sections.section_proof ["x";"s"] `x <- s ==> nth x0 s (indexl x s) = x` [ ((((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)); ];; (* Lemma index_cat *) let index_cat = Sections.section_proof ["x";"s1";"s2"] `indexl x (s1 ++ s2) = if x <- s1 then indexl x s1 else sizel s1 + indexl x s2` [ (((((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)); ];; (* Lemma index_uniq *) let index_uniq = Sections.section_proof ["i";"s"] `i < sizel s ==> uniq s ==> indexl (nth x0 s i) s = i` [ (((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 ["_"]))])); (((((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)); (((((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"]))); (((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))); (((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"])); (((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)); ];; (* Lemma index_head *) let index_head = Sections.section_proof ["x";"s"] `indexl x (x :: s) = 0` [ (((((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)); ];; (* Lemma index_last *) let index_last = Sections.section_proof ["x";"s"] `uniq (x :: s) ==> indexl (last x s) (x :: s) = sizel s` [ ((((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 [] []))))); (((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)); (((((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)); ];; (* Lemma nth_uniq *) let nth_uniq = Sections.section_proof ["s";"i";"j"] `i < sizel s ==> j < sizel s ==> uniq s ==> (nth x0 s i = nth x0 s j) = (i = j)` [ ((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)))])); (((((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)); ];; (* Lemma mem_rot *) let mem_rot = Sections.section_proof ["s"] `!x. x <- rot n0 s <=> x <- s` [ ((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)); ];; (* Lemma eqseq_rot *) let eqseq_rot = Sections.section_proof ["s1";"s2"] `(rot n0 s1 = rot n0 s2) <=> (s1 = s2)` [ (((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)); ];; (* Lemma rot_to *) let rot_to = Sections.section_proof ["s";"x"] `x <- s ==> ?i s'. rot i s = x :: s'` [ ((BETA_TAC THEN (move ["s_x"])) THEN ((fun arg_tac -> arg_tac (Arg_term (`indexl (x:A) s`))) (term_tac (set_tac "i")))); (((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))); (((((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")))); (((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 ["_"])); (((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)))); ((((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))); ((((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))); ((((((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)); ];; (* Finalization of the section EqSeq *) let eqseq_cons = Sections.finalize_theorem eqseq_cons;; let eqseq_cat = Sections.finalize_theorem eqseq_cat;; let eqseq_rcons = Sections.finalize_theorem eqseq_rcons;; let has_filter = Sections.finalize_theorem has_filter;; let size_eq0 = Sections.finalize_theorem size_eq0;; let in_cons = Sections.finalize_theorem in_cons;; let in_nil = Sections.finalize_theorem in_nil;; let mem_seq1 = Sections.finalize_theorem mem_seq1;; let mem_seq2 = Sections.finalize_theorem mem_seq2;; let mem_seq3 = Sections.finalize_theorem mem_seq3;; let mem_seq4 = Sections.finalize_theorem mem_seq4;; let mem_cat = Sections.finalize_theorem mem_cat;; let mem_rcons = Sections.finalize_theorem mem_rcons;; let mem_head = Sections.finalize_theorem mem_head;; let mem_last = Sections.finalize_theorem mem_last;; let mem_behead = Sections.finalize_theorem mem_behead;; let mem_belast = Sections.finalize_theorem mem_belast;; let mem_nth = Sections.finalize_theorem mem_nth;; let mem_take = Sections.finalize_theorem mem_take;; let mem_drop = Sections.finalize_theorem mem_drop;; let mem_rev = Sections.finalize_theorem mem_rev;; let hasP = Sections.finalize_theorem hasP;; let hasPn = Sections.finalize_theorem hasPn;; let allP = Sections.finalize_theorem allP;; let allPn = Sections.finalize_theorem allPn;; let mem_filter = Sections.finalize_theorem mem_filter;; let eq_in_filter = Sections.finalize_theorem eq_in_filter;; let eq_has_r = Sections.finalize_theorem eq_has_r;; let eq_all_r = Sections.finalize_theorem eq_all_r;; let has_sym = Sections.finalize_theorem has_sym;; let has_pred1 = Sections.finalize_theorem has_pred1;; let all_pred1P = Sections.finalize_theorem all_pred1P;; let all_pred1_constant = Sections.finalize_theorem all_pred1_constant;; let all_pred1_nseq = Sections.finalize_theorem all_pred1_nseq;; let constant_nseq = Sections.finalize_theorem constant_nseq;; let constantP = Sections.finalize_theorem constantP;; let nil_uniq = Sections.finalize_theorem nil_uniq;; let cons_uniq = Sections.finalize_theorem cons_uniq;; let cat_uniq = Sections.finalize_theorem cat_uniq;; let uniq_catC = Sections.finalize_theorem uniq_catC;; let uniq_catCA = Sections.finalize_theorem uniq_catCA;; let rcons_uniq = Sections.finalize_theorem rcons_uniq;; let filter_uniq = Sections.finalize_theorem filter_uniq;; let rot_uniq = Sections.finalize_theorem rot_uniq;; let rev_uniq = Sections.finalize_theorem rev_uniq;; let count_uniq_mem = Sections.finalize_theorem count_uniq_mem;; let size_undup = Sections.finalize_theorem size_undup;; let mem_undup = Sections.finalize_theorem mem_undup;; let undup_uniq = Sections.finalize_theorem undup_uniq;; let undup_id = Sections.finalize_theorem undup_id;; let ltn_size_undup = Sections.finalize_theorem ltn_size_undup;; let index_size = Sections.finalize_theorem index_size;; let index_mem = Sections.finalize_theorem index_mem;; let nth_index = Sections.finalize_theorem nth_index;; let index_cat = Sections.finalize_theorem index_cat;; let index_uniq = Sections.finalize_theorem index_uniq;; let index_head = Sections.finalize_theorem index_head;; let index_last = Sections.finalize_theorem index_last;; let nth_uniq = Sections.finalize_theorem nth_uniq;; let mem_rot = Sections.finalize_theorem mem_rot;; let eqseq_rot = Sections.finalize_theorem eqseq_rot;; let rot_to = Sections.finalize_theorem rot_to;; Sections.end_section "EqSeq";; (* Section NseqthTheory *) Sections.begin_section "NseqthTheory";; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (* Lemma nthP *) let nthP = Sections.section_proof ["s";"x";"x0"] `(?i. i < sizel s /\ nth x0 s i = x) <=> (x <- s)` [ ((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))); (((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)); ];; (* Lemma has_nthP *) let has_nthP = Sections.section_proof ["a";"s";"x0"] `(?i. i < sizel s /\ a (nth x0 s i)) <=> (has a s)` [ (((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)))); (((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"])); (((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)); ((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"]))]))); ((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)); ((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))); ((((((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)); ];; (* Lemma all_nthP *) let all_nthP = Sections.section_proof ["a";"s";"x0"] `(!i. i < sizel s ==> a (nth x0 s i)) <=> (all a s)` [ (((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)))); ((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"]))); ((((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)); ((((use_arg_then2 ("IHs", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((split_tac) THEN (move ["IH"]) THEN (move ["i"]) THEN (move ["i_s"]))); ((((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)); (((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)))); (((((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)); ];; (* Finalization of the section NseqthTheory *) let nthP = Sections.finalize_theorem nthP;; let has_nthP = Sections.finalize_theorem has_nthP;; let all_nthP = Sections.finalize_theorem all_nthP;; Sections.end_section "NseqthTheory";; (* Lemma set_nth_default *) let set_nth_default = Sections.section_proof ["s";"y0";"x0";"n"] `n < sizel s ==> nth (x0:A) s n = nth y0 s n` [ (((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)))); (((((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)); ];; (* Lemma headI *) let headI = Sections.section_proof ["s";"x"] `rcons s x = headl x s :: behead (rcons s (x:A))` [ (((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)); ];;
let incr_nth = define `incr_nth (n :: v') (SUC i) = n :: incr_nth v' i /\
	incr_nth (n :: v') 0 = SUC n :: v' /\
	incr_nth [] i = ncons i 0 [1]`;;
(* Lemma nth_incr_nth *) let nth_incr_nth = Sections.section_proof ["v";"i";"j"] `nth 0 (incr_nth v i) j = (if (i = j) then 1 else 0) + nth 0 v j` [ (((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)))); (arith_tac); (((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)))); (arith_tac); (arith_tac); (((((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)); (((((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)); (((((use_arg_then2 ("IHv", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma size_incr_nth *) let size_incr_nth = Sections.section_proof ["v";"i"] `sizel (incr_nth v i) = if i < sizel v then sizel v else SUC i` [ (((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))); (((((use_arg_then2 ("ONE", [ONE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("addn1", [addn1]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((((use_arg_then2 ("ltn0Sn", [ltn0Sn]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ((((use_arg_then2 ("IHv", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))); (((use_arg_then2 ("fun_if", [fun_if])) (thm_tac apply_tac)) THEN (done_tac)); ];; (* Section PermSeq *) Sections.begin_section "PermSeq";; (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));;
let same_count1 = new_definition `same_count1 s1 s2 x <=> (count (pred1 x) s1 = count (pred1 x) s2)`;;
let perm_eq = new_definition `perm_eq s1 s2 = all (same_count1 s1 s2) (s1 ++ s2)`;;
(* Lemma perm_eqP *) let perm_eqP = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 <=> (!a. count a s1 = count a s2)` [ ((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)); ((((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"]))); (((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); ((((((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)); ((((((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'")))); ((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'"])))); (BETA_TAC THEN (move ["s"])); ((((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 [] [])))))); ((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 [] []))))); ((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 [] []))))))); (((((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)); ((((use_arg_then2 ("a'_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqn_addr", [eqn_addr]))(thm_tac (new_rewrite [] []))))); ((((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)); ((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 [] [])))))); ((((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))); (((((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)); ];; (* Lemma perm_eq_refl *) let perm_eq_refl = Sections.section_proof ["s"] `perm_eq s s` [ ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma perm_eq_sym *) let perm_eq_sym = Sections.section_proof [] `!s1 s2. perm_eq s1 s2 = perm_eq s2 s1` [ ((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)); ];; (* Lemma perm_eq_trans *) let perm_eq_trans = Sections.section_proof [] `!s2 s1 s3. perm_eq s1 s2 ==> perm_eq s2 s3 ==> perm_eq s1 s3` [ ((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"]))); (((((use_arg_then2 ("eq12", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq23", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eqlP *) let perm_eqlP = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 <=> (!s. perm_eq s1 s = perm_eq s2 s)` [ ((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))); ((THENL_LAST) (split_tac) (((use_arg_then2 ("perm_eq_trans", [perm_eq_trans])) (disch_tac [])) THEN (clear_assumption "perm_eq_trans") THEN (exact_tac))); ((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)); ];; (* Lemma perm_eqrP *) let perm_eqrP = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 <=> (!s. perm_eq s s1 = perm_eq s s2)` [ ((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))); ((((use_arg_then2 ("perm_eqlP", [perm_eqlP]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq12"]) THEN (move ["s3"])); (((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)); ];; (* Lemma perm_catC *) let perm_catC = Sections.section_proof ["s1";"s2"] `!s. perm_eq (s1 ++ s2) s = perm_eq (s2 ++ s1) s` [ ((((((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)); ];; (* Lemma perm_cat2l *) let perm_cat2l = Sections.section_proof ["s1";"s2";"s3"] `perm_eq (s1 ++ s2) (s1 ++ s3) = perm_eq s2 s3` [ ((repeat_tactic 1 9 (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN ((split_tac) THEN (move ["eq23"]) THEN (move ["a"]))); ((((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)); ((((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)); ];; (* Lemma perm_cons *) let perm_cons = Sections.section_proof ["x";"s1";"s2"] `perm_eq (x :: s1) (x :: s2) = perm_eq s1 s2` [ ((((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)); ];; (* Lemma perm_cat2r *) let perm_cat2r = Sections.section_proof ["s1";"s2";"s3"] `perm_eq (s2 ++ s1) (s3 ++ s1) = perm_eq s2 s3` [ ((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)); ];; (* Lemma perm_catAC *) let perm_catAC = Sections.section_proof ["s1";"s2";"s3"] `!s. perm_eq ((s1 ++ s2) ++ s3) s = perm_eq ((s1 ++ s3) ++ s2) s` [ (((((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)); ];; (* Lemma perm_catCA *) let perm_catCA = Sections.section_proof ["s1";"s2";"s3"] `!s. perm_eq (s1 ++ s2 ++ s3) s = perm_eq (s2 ++ s1 ++ s3) s` [ (((((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)); ];; (* Lemma perm_rcons *) let perm_rcons = Sections.section_proof ["x";"s"] `!s2. perm_eq (rcons s x) s2 = perm_eq (x :: s) s2` [ ((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)); ];; (* Lemma perm_rot *) let perm_rot = Sections.section_proof ["n";"s"] `!s2. perm_eq (rot n s) s2 = perm_eq s s2` [ ((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)); ];; (* Lemma perm_rotr *) let perm_rotr = Sections.section_proof ["n";"s"] `!s2. perm_eq (rotr n s) s2 = perm_eq s s2` [ (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_rot", [perm_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_filterC *) let perm_filterC = Sections.section_proof ["a";"s"] `!s2. perm_eq (filter a s ++ filter (predC a) s) s2 = perm_eq s s2` [ ((((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)))); ((((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("predC", [predC]))(gsym_then (thm_tac (new_rewrite [] [])))))); (((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)); ];; (* Lemma perm_eq_mem *) let perm_eq_mem = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> (!x. x <- s1 <=> x <- s2)` [ (((((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 [] []))))))); ((((use_arg_then2 ("eq12", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma perm_eq_size *) let perm_eq_size = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> sizel s1 = sizel s2` [ ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq12"])); (((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)); ];; (* Lemma uniq_leq_size *) let uniq_leq_size = Sections.section_proof ["s1";"s2"] `uniq s1 ==> (!x. x <- s1 ==> x <- s2) ==> sizel s1 <= sizel s2` [ ((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"]))))]); ((((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"]))); (((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'"])))); (((((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"])); ((((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 [] [])))))); ((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)); (((((use_arg_then2 ("yx", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac)); ];; (* Lemma leq_size_uniq *) let leq_size_uniq = Sections.section_proof ["s1";"s2"] `uniq s1 ==> (!x. x <- s1 ==> x <- s2) ==> sizel s2 <= sizel s1 ==> uniq s2` [ ((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"]))]); (((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)); ((((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"]))); (((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'"])))); (((((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'"]))); ((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 [] [])))))); (((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"]))); ((((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)); ((((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]))))); (((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"]))); (((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"]))); ((((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)); ];; (* Lemma uniq_size_uniq *) let uniq_size_uniq = Sections.section_proof ["s1";"s2"] `uniq s1 ==> (!x. x <- s1 <=> x <- s2) ==> (uniq s2 = (sizel s2 = sizel s1))` [ (BETA_TAC THEN (move ["Us1"]) THEN (move ["Es12"])); ((((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))); ((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))); ((((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)); ];; (* Lemma leq_size_perm *) let leq_size_perm = Sections.section_proof ["s1";"s2"] `uniq s1 ==> (!x. x <- s1 ==> x <- s2) ==> sizel s2 <= sizel s1 ==> (!x. x <- s1 <=> x <- s2) /\ sizel s1 = sizel s2` [ ((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"]))))); ((((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)); (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`!x. x <- s1 <=> x <- s2`))) (term_tac (have_gen_tac []ALL_TAC)))); ((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)); (BETA_TAC THEN (move ["x"])); ((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"]))]); (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`sizel (x :: s1) <= sizel s2`))) (term_tac (have_gen_tac []ALL_TAC)))); (((((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)); ((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))); ((((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))); ];; (* Lemma perm_uniq *) let perm_uniq = Sections.section_proof ["s1";"s2"] `(!x. x <- s1 <=> x <- s2) ==> sizel s1 = sizel s2 ==> uniq s1 = uniq s2` [ ((BETA_TAC THEN (move ["Es12"]) THEN (move ["Hs12"])) THEN ((split_tac) THEN (move ["Us"]))); (((((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)); (((((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)); ];; (* Lemma perm_eq_uniq *) let perm_eq_uniq = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> uniq s1 = uniq s2` [ (((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)); ];; (* Lemma uniq_perm_eq *) let uniq_perm_eq = Sections.section_proof ["s1";"s2"] `uniq s1 ==> uniq s2 ==> (!x. x <- s1 <=> x <- s2) ==> perm_eq s1 s2` [ ((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 ["_"]))); (((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)); ];; (* Lemma count_mem_uniq *) let count_mem_uniq = Sections.section_proof ["s"] `(!x. count (pred1 x) s = if (x <- s) then 1 else 0) ==> uniq s` [ ((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"])))); ((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))); (((((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 ["_"])); (((((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)); ];; (* Finalization of the section PermSeq *) let perm_eqP = Sections.finalize_theorem perm_eqP;; let perm_eq_refl = Sections.finalize_theorem perm_eq_refl;; let perm_eq_sym = Sections.finalize_theorem perm_eq_sym;; let perm_eq_trans = Sections.finalize_theorem perm_eq_trans;; let perm_eqlP = Sections.finalize_theorem perm_eqlP;; let perm_eqrP = Sections.finalize_theorem perm_eqrP;; let perm_catC = Sections.finalize_theorem perm_catC;; let perm_cat2l = Sections.finalize_theorem perm_cat2l;; let perm_cons = Sections.finalize_theorem perm_cons;; let perm_cat2r = Sections.finalize_theorem perm_cat2r;; let perm_catAC = Sections.finalize_theorem perm_catAC;; let perm_catCA = Sections.finalize_theorem perm_catCA;; let perm_rcons = Sections.finalize_theorem perm_rcons;; let perm_rot = Sections.finalize_theorem perm_rot;; let perm_rotr = Sections.finalize_theorem perm_rotr;; let perm_filterC = Sections.finalize_theorem perm_filterC;; let perm_eq_mem = Sections.finalize_theorem perm_eq_mem;; let perm_eq_size = Sections.finalize_theorem perm_eq_size;; let uniq_leq_size = Sections.finalize_theorem uniq_leq_size;; let leq_size_uniq = Sections.finalize_theorem leq_size_uniq;; let uniq_size_uniq = Sections.finalize_theorem uniq_size_uniq;; let leq_size_perm = Sections.finalize_theorem leq_size_perm;; let perm_uniq = Sections.finalize_theorem perm_uniq;; let perm_eq_uniq = Sections.finalize_theorem perm_eq_uniq;; let uniq_perm_eq = Sections.finalize_theorem uniq_perm_eq;; let count_mem_uniq = Sections.finalize_theorem count_mem_uniq;; Sections.end_section "PermSeq";; (* Section RotrLemmas *) Sections.begin_section "RotrLemmas";; (Sections.add_section_var (mk_var ("n0", (`:num`))));; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (* Lemma size_rotr *) let size_rotr = Sections.section_proof ["s"] `sizel (rotr n0 s) = sizel s` [ (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma mem_rotr *) let mem_rotr = Sections.section_proof ["s"] `!x. x <- rotr n0 s <=> x <- s` [ ((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)); ];; (* Lemma rotr_size_cat *) let rotr_size_cat = Sections.section_proof ["s1";"s2"] `rotr (sizel s2) (s1 ++ s2) = s2 ++ s1` [ (((((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)); ];; (* Lemma rotr1_rcons *) let rotr1_rcons = Sections.section_proof ["x";"s"] `rotr 1 (rcons s x) = x :: s` [ (((((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)); ];; (* Lemma has_rotr *) let has_rotr = Sections.section_proof ["a";"s"] `has a (rotr n0 s) = has a s` [ (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_rot", [has_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma rotr_uniq *) let rotr_uniq = Sections.section_proof ["s"] `uniq (rotr n0 s) = uniq s` [ (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_uniq", [rot_uniq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma rotrK *) let rotrK = Sections.section_proof [] `!s. rot n0 (rotr n0 s) = s` [ (BETA_TAC THEN (move ["s"])); ((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"])]))); (((((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)); ((((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 [] []))))); ((((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)); ];; (* Lemma rotr_inj *) let rotr_inj = Sections.section_proof ["s1";"s2"] `rotr n0 (s1:(A)list) = rotr n0 s2 ==> s1 = s2` [ (BETA_TAC THEN (move ["h"])); (((((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)); ];; (* Lemma rev_rot *) let rev_rot = Sections.section_proof ["s"] `rev (rot n0 s) = rotr n0 (rev s)` [ ((((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 [] [])))))); (((((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)); ];; (* Lemma rev_rotr *) let rev_rotr = Sections.section_proof ["s"] `rev (rotr n0 s) = rot n0 (rev s)` [ (((((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 [] []))))); ((((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 [] []))))); ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [(`rot _ s`)])))) THEN (((use_arg_then2 ("rev_cat", [rev_cat]))(thm_tac (new_rewrite [] []))))); ((fun arg_tac -> arg_tac (Arg_term (`sizel s - n0`))) (term_tac (set_tac "m"))); ((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] [])))))); (((((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)); (((((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)); ];; (* Finalization of the section RotrLemmas *) let size_rotr = Sections.finalize_theorem size_rotr;; let mem_rotr = Sections.finalize_theorem mem_rotr;; let rotr_size_cat = Sections.finalize_theorem rotr_size_cat;; let rotr1_rcons = Sections.finalize_theorem rotr1_rcons;; let has_rotr = Sections.finalize_theorem has_rotr;; let rotr_uniq = Sections.finalize_theorem rotr_uniq;; let rotrK = Sections.finalize_theorem rotrK;; let rotr_inj = Sections.finalize_theorem rotr_inj;; let rev_rot = Sections.finalize_theorem rev_rot;; let rev_rotr = Sections.finalize_theorem rev_rotr;; Sections.end_section "RotrLemmas";; (* Section RotCompLemmas *) Sections.begin_section "RotCompLemmas";; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (* Lemma rot_addn *) let rot_addn = Sections.section_proof ["m";"n";"s"] `m + n <= sizel s ==> rot (m + n) s = rot m (rot n s)` [ ((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`)]))))))); ((((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 [] [])))))); (((((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)); ];; (* Lemma rotS *) let rotS = Sections.section_proof ["n";"s"] `n < sizel s ==> rot (SUC n) s = rot 1 (rot n s)` [ ((((((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)); ];; (* Lemma rot_add_mod *) let rot_add_mod = Sections.section_proof ["m";"n";"s"] `n <= sizel s ==> m <= sizel s ==> rot m (rot n s) = rot (if m + n <= sizel s then m + n else (m + n) - sizel s) s` [ ((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]); (((((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 [] []))))); (((((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)); ];; (* Lemma rot_rot *) let rot_rot = Sections.section_proof ["m";"n";"s"] `rot m (rot n s) = rot n (rot m s)` [ (((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"])); (((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)); (((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"])); (((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)); (((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)); ];; (* Lemma rot_rotr *) let rot_rotr = Sections.section_proof ["m";"n";"s"] `rot m (rotr n s) = rotr n (rot m s)` [ (((((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)); ];; (* Lemma rotr_rotr *) let rotr_rotr = Sections.section_proof ["m";"n";"s"] `rotr m (rotr n s) = rotr n (rotr m s)` [ (((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)); ];; (* Finalization of the section RotCompLemmas *) let rot_addn = Sections.finalize_theorem rot_addn;; let rotS = Sections.finalize_theorem rotS;; let rot_add_mod = Sections.finalize_theorem rot_add_mod;; let rot_rot = Sections.finalize_theorem rot_rot;; let rot_rotr = Sections.finalize_theorem rot_rotr;; let rotr_rotr = Sections.finalize_theorem rotr_rotr;; Sections.end_section "RotCompLemmas";; (* Section Mask *) Sections.begin_section "Mask";; (Sections.add_section_var (mk_var ("n0", (`:num`))));; (Sections.add_section_type (mk_var ("m", (`:(bool)list`))));; (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));;
let mask = define `mask [] s' = [] /\ mask m' [] = [] /\
	mask (b :: m') (x :: s') = if b then x :: mask m' s' else mask m' s'`;;
(* Lemma mask_false *) let mask_false = Sections.section_proof ["s";"n"] `mask (nseq n F) s = []` [ (((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)); ];; (* Lemma mask_true *) let mask_true = Sections.section_proof ["s";"n"] `sizel s <= n ==> mask (nseq n T) s = s` [ (((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)))); ((((((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)); ];; (* Lemma mask0 *) let mask0 = Sections.section_proof ["m"] `mask m [] = []` [ (((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)); ];; (* Lemma mask1 *) let mask1 = Sections.section_proof ["b";"x"] `mask [b] [x] = nseq (if b then 1 else 0) x` [ ((((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)); ];; (* Lemma mask_cons *) let mask_cons = Sections.section_proof ["b";"m";"x";"s"] `mask (b :: m) (x :: s) = nseq (if b then 1 else 0) x ++ mask m s` [ ((((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)); ];; (* Lemma size_mask *) let size_mask = Sections.section_proof ["m";"s"] `sizel m = sizel s ==> sizel (mask m s) = count I m` [ (((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]))))); ((((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)); ];; (* Lemma mask_cat *) let mask_cat = Sections.section_proof ["m1";"s1";"m2";"s2"] `sizel m1 = sizel s1 ==> mask (m1 ++ m2) (s1 ++ s2) = mask m1 s1 ++ mask m2 s2` [ (BETA_TAC THEN (move ["Hm1"])); (((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)))); ((((((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)); ];; (* Lemma has_mask_cons *) let has_mask_cons = Sections.section_proof ["a";"b";"m";"x";"s"] `has a (mask (b :: m) (x :: s)) <=> b /\ a x \/ has a (mask m s)` [ ((((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)); ];; (* Lemma mask_rot *) let mask_rot = Sections.section_proof ["m";"s"] `sizel m = sizel s ==> mask (rot n0 m) (rot n0 s) = rot (count I (take n0 m)) (mask m s)` [ (BETA_TAC THEN (move ["Hs"])); ((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))); ((((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))); ((((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))); ((((use_arg_then2 ("rot_size_cat", [rot_size_cat]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Finalization of the section Mask *) let mask_false = Sections.finalize_theorem mask_false;; let mask_true = Sections.finalize_theorem mask_true;; let mask0 = Sections.finalize_theorem mask0;; let mask1 = Sections.finalize_theorem mask1;; let mask_cons = Sections.finalize_theorem mask_cons;; let size_mask = Sections.finalize_theorem size_mask;; let mask_cat = Sections.finalize_theorem mask_cat;; let has_mask_cons = Sections.finalize_theorem has_mask_cons;; let mask_rot = Sections.finalize_theorem mask_rot;; Sections.end_section "Mask";; (* Section EqMask *) Sections.begin_section "EqMask";; (Sections.add_section_var (mk_var ("n0", (`:num`))));; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (Sections.add_section_type (mk_var ("m", (`:(bool)list`))));; (* Lemma mem_mask_cons *) let mem_mask_cons = Sections.section_proof ["x";"b";"m";"y";"s"] `(x <- mask (b :: m) (y :: s)) <=> b /\ (x = y) \/ (x <- mask m s)` [ ((((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)); ];; (* Lemma mem_mask *) let mem_mask = Sections.section_proof ["x";"m";"s"] `x <- mask m s ==> x <- s` [ (((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])))))); ((((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)); ];; (* Lemma mask_uniq *) let mask_uniq = Sections.section_proof ["s"] `uniq s ==> !m. uniq (mask m s)` [ (((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 ["_"]))])); (((((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)); ((((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)))); ((((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)); ];; (* Lemma mem_mask_rot *) let mem_mask_rot = Sections.section_proof ["m";"s"] `sizel m = sizel s ==> (!x. x <- mask (rot n0 m) (rot n0 s) <=> x <- mask m s)` [ ((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)); ];; (* Finalization of the section EqMask *) let mem_mask_cons = Sections.finalize_theorem mem_mask_cons;; let mem_mask = Sections.finalize_theorem mem_mask;; let mask_uniq = Sections.finalize_theorem mask_uniq;; let mem_mask_rot = Sections.finalize_theorem mem_mask_rot;; Sections.end_section "EqMask";; (* Section Subseq *) Sections.begin_section "Subseq";; (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));;
let subseq = define `subseq (x :: s1) (y :: s2) = subseq (if x = y then s1 else x :: s1) s2 /\
	subseq [] s2 = T /\ subseq (x :: s1) [] = F`;;
(* Lemma sub0seq *) let sub0seq = Sections.section_proof ["s"] `subseq [] s` [ ((((use_arg_then2 ("subseq", [subseq]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma subseq0 *) let subseq0 = Sections.section_proof ["s"] `subseq s [] = (s = [])` [ (((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)); ];; (* Lemma subseqP *) let subseqP = Sections.section_proof ["s1";"s2"] `subseq s1 s2 <=> (?m. sizel m = sizel s2 /\ s1 = mask m s2)` [ (((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))); (((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)); (((((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)); (((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)); ((((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 ["_"]))); (((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))); ((((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)); ((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"]))])); (((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"]))); ((((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)); (((use_arg_then2 ("m", [])) (term_tac exists_tac)) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`indexl T n`))) (term_tac (set_tac "i"))); ((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"])))); (((((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"])); (((((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 ["_"]))); ((((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)))); (((repeat_tactic 1 9 (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`i < sizel n`))) (term_tac (have_gen_tac [](move ["lt_i_m"])))); ((((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"]))); ((((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)); ((((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"]))); (((fun arg_tac -> arg_tac (Arg_term (`take i n ++ dropl (SUC i) n`))) (term_tac exists_tac)) THEN (split_tac)); ((((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)); ((((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)); ((((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 [] [])))))); ((((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 [] [])))))); ((fun arg_tac -> arg_tac (Arg_term (`sizel (take i s2) = i`))) (term_tac (have_gen_tac [](move ["sz_i_s2"])))); ((((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)); ((((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 [] [])))))); ((((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))); (((((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)); ];; (* Lemma subseq_trans *) let subseq_trans = Sections.section_proof ["s1";"s2";"s3"] `subseq s1 s2 ==> subseq s2 s3 ==> subseq s1 s3` [ (((((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 [] [])))))))); ((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))); (BETA_TAC THEN (move ["m2"]) THEN (move ["m1"])); (((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)))); (((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)))); ((((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"]))))); (((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)); ((((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"]))))); (((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)); ];; (* Lemma subseq_refl *) let subseq_refl = Sections.section_proof ["s"] `subseq s s` [ (((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)); ];; (* Lemma subseq_cat *) let subseq_cat = Sections.section_proof ["s1";"s2";"s3";"s4"] `subseq s1 s3 ==> subseq s2 s4 ==> subseq (s1 ++ s2) (s3 ++ s4)` [ ((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 [] []))))))); (((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)); ];; (* Lemma mem_subseq *) let mem_subseq = Sections.section_proof ["s1";"s2"] `subseq s1 s2 ==> (!x. x <- s1 ==> x <- s2)` [ (((((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)); ];; (* Lemma subseq_seq1 *) let subseq_seq1 = Sections.section_proof ["x";"s"] `subseq [x] s <=> x <- s` [ (((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])))))); ((((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)); ];; (* Lemma size_subseq *) let size_subseq = Sections.section_proof ["s1";"s2"] `subseq s1 s2 ==> sizel s1 <= sizel s2` [ ((((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 [] []))))))); (((((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)); ];; (* Lemma size_subseq_leqif *) let size_subseq_leqif = Sections.section_proof ["s1";"s2"] `subseq s1 s2 ==> leqif (sizel s1) (sizel s2) (s1 = s2)` [ ((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))); (((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 [] [])))))))); ((((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 [] [])))))); ((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 [] []))))))); (((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); (((((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)); (((((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)); ];; (* Lemma subseq_cons *) let subseq_cons = Sections.section_proof ["s";"x"] `subseq s (x :: s)` [ (((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); (((((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)); ];; (* Lemma subseq_rcons *) let subseq_rcons = Sections.section_proof ["s";"x"] `subseq s (rcons s x)` [ (((((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)); ];; (* Lemma subseq_uniq *) let subseq_uniq = Sections.section_proof ["s1";"s2"] `subseq s1 s2 ==> uniq s2 ==> uniq s1` [ (((((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)); ];; (* Finalization of the section Subseq *) let sub0seq = Sections.finalize_theorem sub0seq;; let subseq0 = Sections.finalize_theorem subseq0;; let subseqP = Sections.finalize_theorem subseqP;; let subseq_trans = Sections.finalize_theorem subseq_trans;; let subseq_refl = Sections.finalize_theorem subseq_refl;; let subseq_cat = Sections.finalize_theorem subseq_cat;; let mem_subseq = Sections.finalize_theorem mem_subseq;; let subseq_seq1 = Sections.finalize_theorem subseq_seq1;; let size_subseq = Sections.finalize_theorem size_subseq;; let size_subseq_leqif = Sections.finalize_theorem size_subseq_leqif;; let subseq_cons = Sections.finalize_theorem subseq_cons;; let subseq_rcons = Sections.finalize_theorem subseq_rcons;; let subseq_uniq = Sections.finalize_theorem subseq_uniq;; Sections.end_section "Subseq";; (* Section Map *) Sections.begin_section "Map";; (Sections.add_section_var (mk_var ("n0", (`:num`))));; (Sections.add_section_var (mk_var ("x1", (`:A`))));; (Sections.add_section_var (mk_var ("x2", (`:B`))));; (Sections.add_section_var (mk_var ("f", (`:A -> B`))));;
let map = define `map f (x :: s) = f x :: map f s /\ map f [] = []`;;
(* Lemma map_MAP *) let map_MAP = Sections.section_proof [] `map = MAP` [ ((((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"]))); (((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)); ];; (* Lemma map_cons *) let map_cons = Sections.section_proof ["x";"s"] `map f (x :: s) = f x :: map f s` [ ((((use_arg_then2 ("map", [map]))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (done_tac)); ];; (* Lemma map_nseq *) let map_nseq = Sections.section_proof ["x"] `map f (nseq n0 x) = nseq n0 (f x)` [ (((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])))))); ((((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma map_cat *) let map_cat = Sections.section_proof ["s1";"s2"] `map f (s1 ++ s2) = map f s1 ++ map f s2` [ (((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)); ];; (* Lemma size_map *) let size_map = Sections.section_proof ["s"] `sizel (map f s) = sizel s` [ (((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]))))); ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma behead_map *) let behead_map = Sections.section_proof ["s"] `behead (map f s) = map f (behead s)` [ (((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)); ];; (* Lemma nth_map *) let nth_map = Sections.section_proof ["n";"s"] `n < sizel s ==> nth x2 (map f s) n = f (nth x1 s n)` [ (((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)))); ((((((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)); ];; (* Lemma map_rcons *) let map_rcons = Sections.section_proof ["s";"x"] `map f (rcons s x) = rcons (map f s) (f x)` [ (((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)); ];; (* Lemma last_map *) let last_map = Sections.section_proof ["s";"x"] `last (f x) (map f s) = f (last x s)` [ (((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)); ];; (* Lemma belast_map *) let belast_map = Sections.section_proof ["s";"x"] `belast (f x) (map f s) = map f (belast x s)` [ (((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)); ];;
let preim = new_definition `preim (f:A->B) (a:B->bool) = (\x. a (f x))`;;
(* Lemma filter_map *) let filter_map = Sections.section_proof ["a";"s"] `filter a (map f s) = map f (filter (preim f a) s)` [ (((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)))); ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); ((((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)); ];; (* Lemma find_map *) let find_map = Sections.section_proof ["a";"s"] `find a (map f s) = find (preim f a) s` [ (((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)))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma has_map *) let has_map = Sections.section_proof ["a";"s"] `has a (map f s) = has (preim f a) s` [ (((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)))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma all_map *) let all_map = Sections.section_proof ["a";"s"] `all a (map f s) = all (preim f a) s` [ (((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)))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma count_map *) let count_map = Sections.section_proof ["a";"s"] `count a (map f s) = count (preim f a) s` [ (((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)))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("preim", [preim]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma map_take *) let map_take = Sections.section_proof ["s"] `map f (take n0 s) = take n0 (map f s)` [ (((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)); ];; (* Lemma map_drop *) let map_drop = Sections.section_proof ["s"] `map f (dropl n0 s) = dropl n0 (map f s)` [ (((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)); ];; (* Lemma map_rot *) let map_rot = Sections.section_proof ["s"] `map f (rot n0 s) = rot n0 (map f s)` [ (((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)); ];; (* Lemma map_rotr *) let map_rotr = Sections.section_proof ["s"] `map f (rotr n0 s) = rotr n0 (map f s)` [ (((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)); ];; (* Lemma map_rev *) let map_rev = Sections.section_proof ["s"] `map f (rev s) = rev (map f s)` [ (((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)); ];; (* Lemma map_mask *) let map_mask = Sections.section_proof ["m";"s"] `map f (mask m s) = mask m (map f s)` [ (((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)))); (((((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)); ];; (* Lemma inj_map *) let inj_map = Sections.section_proof [] `(!x y. f x = f y ==> x = y) ==> (!s1 s2. map f s1 = map f s2 ==> s1 = s2)` [ ((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)))); (((((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)); ];; (* Finalization of the section Map *) let map_MAP = Sections.finalize_theorem map_MAP;; let map_cons = Sections.finalize_theorem map_cons;; let map_nseq = Sections.finalize_theorem map_nseq;; let map_cat = Sections.finalize_theorem map_cat;; let size_map = Sections.finalize_theorem size_map;; let behead_map = Sections.finalize_theorem behead_map;; let nth_map = Sections.finalize_theorem nth_map;; let map_rcons = Sections.finalize_theorem map_rcons;; let last_map = Sections.finalize_theorem last_map;; let belast_map = Sections.finalize_theorem belast_map;; let filter_map = Sections.finalize_theorem filter_map;; let find_map = Sections.finalize_theorem find_map;; let has_map = Sections.finalize_theorem has_map;; let all_map = Sections.finalize_theorem all_map;; let count_map = Sections.finalize_theorem count_map;; let map_take = Sections.finalize_theorem map_take;; let map_drop = Sections.finalize_theorem map_drop;; let map_rot = Sections.finalize_theorem map_rot;; let map_rotr = Sections.finalize_theorem map_rotr;; let map_rev = Sections.finalize_theorem map_rev;; let map_mask = Sections.finalize_theorem map_mask;; let inj_map = Sections.finalize_theorem inj_map;; Sections.end_section "Map";; (* Lemma filter_mask *) let filter_mask = Sections.section_proof ["a";"s"] `filter (a:A->bool) s = mask (map a s) s` [ (((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]))))); ((((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)); ];; (* Section FilterSubseq *) Sections.begin_section "FilterSubseq";; (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))));; (Sections.add_section_type (mk_var ("a", (`:A -> bool`))));; (* Lemma filter_subseq *) let filter_subseq = Sections.section_proof ["a";"s"] `subseq (filter a s) s` [ ((((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)); ];; (* Lemma subseq_filter *) let subseq_filter = Sections.section_proof ["s1";"s2";"a"] `subseq s1 (filter a s2) <=> all a s1 /\ subseq s1 s2` [ (((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)))); ((((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)); ];; (* Lemma subseq_uniqP *) let subseq_uniqP = Sections.section_proof ["s1";"s2"] `uniq s2 ==> (subseq s1 s2 <=> s1 = filter (\x. x <- s1) s2)` [ ((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))); ((fun arg_tac -> arg_tac (Arg_term (`subseq s1 (filter (\x. x <- s1) s2)`))) (term_tac (have_gen_tac []ALL_TAC))); (((((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)); (((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 [] []))))))); ((((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))); ((((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))); ((((((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)); ];; (* Finalization of the section FilterSubseq *) let filter_subseq = Sections.finalize_theorem filter_subseq;; let subseq_filter = Sections.finalize_theorem subseq_filter;; let subseq_uniqP = Sections.finalize_theorem subseq_uniqP;; Sections.end_section "FilterSubseq";; (* Section EqMap *) Sections.begin_section "EqMap";; (Sections.add_section_var (mk_var ("n0", (`:num`))));; (Sections.add_section_var (mk_var ("x1", (`:A`))));; (Sections.add_section_var (mk_var ("x2", (`:B`))));; (Sections.add_section_var (mk_var ("f", (`:A -> B`))));; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (* Lemma map_f *) let map_f = Sections.section_proof ["s";"x"] `x <- s ==> f x <- map f s` [ (((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)))); (((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)); ];; (* Lemma mapP *) let mapP = Sections.section_proof ["s";"y"] `(y <- map f s) <=> (?x. x <- s /\ y = f x)` [ (((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]))))); (((((use_arg_then2 ("NOT_EXISTS_THM", [NOT_EXISTS_THM]))(thm_tac (new_rewrite [] [])))) THEN (move ["x"])) THEN (done_tac)); ((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"]))); (((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac)); ((((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"])))))])); (((use_arg_then2 ("x'", [])) (term_tac exists_tac)) THEN (done_tac)); ((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)))]); (((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)); ];; (* Lemma map_uniq *) let map_uniq = Sections.section_proof ["s"] `uniq (map f s) ==> uniq s` [ (((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"])))); (((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 [] []))))); ((((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)); ];; (* Lemma map_inj_in_uniq *) let map_inj_in_uniq = Sections.section_proof ["s"] `(!x y. x <- s ==> y <- s ==> (f x = f y ==> x = y)) ==> uniq (map f s) = uniq s` [ (((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"]))); (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))); (BETA_TAC THEN (move ["a"]) THEN (move ["b"]) THEN (case THEN ((case THEN ((move ["Ha"]) THEN (move ["Hb"]))) THEN (move ["fab"])))); ((((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)); ((congr_tac (`_ /\ _`)) THEN ((TRY done_tac))); (((((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)); ((((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)); (BETA_TAC THEN (move ["Hx"]) THEN (move ["y"])); (((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"])); ((((fun arg_tac -> arg_tac (Arg_theorem (TAUT `~A <=> (A ==> F)`)))(fun arg -> ONCE_REWRITE_TAC[get_arg_thm arg]))) THEN (move ["fxy"])); ((((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))); (((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"])); ((((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)); ];; (* Lemma map_subseq *) let map_subseq = Sections.section_proof ["s1";"s2"] `subseq s1 s2 ==> subseq (map f s1) (map f s2)` [ ((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"])))); (((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)); ];; (* Finalization of the section EqMap *) let map_f = Sections.finalize_theorem map_f;; let mapP = Sections.finalize_theorem mapP;; let map_uniq = Sections.finalize_theorem map_uniq;; let map_inj_in_uniq = Sections.finalize_theorem map_inj_in_uniq;; let map_subseq = Sections.finalize_theorem map_subseq;; Sections.end_section "EqMap";; (* Section EqMap2 *) Sections.begin_section "EqMap2";; (Sections.add_section_var (mk_var ("n0", (`:num`))));; (Sections.add_section_var (mk_var ("x1", (`:A`))));; (Sections.add_section_var (mk_var ("x2", (`:B`))));; (Sections.add_section_var (mk_var ("f", (`:A -> B`))));; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (Sections.add_section_hyp "Hf" (`!x y. f x = f y ==> x = y`));; (* Lemma inj_eq *) let inj_eq = Sections.section_proof ["x";"y"] `(f x = f y <=> x = y)` [ (((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)); ];; (* Lemma mem_map *) let mem_map = Sections.section_proof ["s";"x"] `(f x <- map f s) = (x <- s)` [ ((((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)); ];; (* Lemma index_map *) let index_map = Sections.section_proof ["s";"x"] `indexl (f x) (map f s) = indexl x s` [ ((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))); (((((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)); ];; (* Lemma map_inj_uniq *) let map_inj_uniq = Sections.section_proof ["s"] `uniq (map f s) = uniq s` [ ((((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)); ];; (* Finalization of the section EqMap2 *) let inj_eq = Sections.finalize_theorem inj_eq;; let mem_map = Sections.finalize_theorem mem_map;; let index_map = Sections.finalize_theorem index_map;; let map_inj_uniq = Sections.finalize_theorem map_inj_uniq;; Sections.end_section "EqMap2";; (* Section MapComp *) Sections.begin_section "MapComp";; (* Lemma map_id *) let map_id = Sections.section_proof ["s"] `map I (s:(A)list) = s` [ (((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)); ];; (* Lemma eq_map *) let eq_map = Sections.section_proof ["f1";"f2"] `(!x. (f1:A->B) x = f2 x) ==> map f1 = map f2` [ (((((use_arg_then2 ("eq_ext", [eq_ext]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma map_comp *) let map_comp = Sections.section_proof ["f1";"f2";"s"] `map (f1 o f2) s = map (f1:B->C) (map (f2:A->B) s)` [ (((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]))))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("o_THM", [o_THM]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma mapK *) let mapK = Sections.section_proof ["f1";"f2"] `(!x. (f2:B->A) ((f1:A->B) x) = x) ==> (!s. map f2 (map f1 s) = s)` [ ((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)); ];; (* Finalization of the section MapComp *) let map_id = Sections.finalize_theorem map_id;; let eq_map = Sections.finalize_theorem eq_map;; let map_comp = Sections.finalize_theorem map_comp;; let mapK = Sections.finalize_theorem mapK;; Sections.end_section "MapComp";; (* Lemma eq_in_map *) let eq_in_map = Sections.section_proof ["f1";"f2";"s"] `(!x. x <- s ==> (f1:A->B) x = f2 x) ==> map f1 s = map f2 s` [ (((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)))); (((((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"])); (((((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)); ];; (* Lemma map_id_in *) let map_id_in = Sections.section_proof ["f";"s"] `(!x. x <- s ==> f x = (x:A)) ==> map f s = s` [ ((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 [] []))))); (((use_arg_then2 ("map_id", [map_id]))(gsym_then (thm_tac (new_rewrite [2] [(`s`)]))))); (((((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)); ];;
let iota = define `iota m (SUC n) = m :: iota (SUC m) n /\ iota m 0 = []`;;
(* Lemma size_iota *) let size_iota = Sections.section_proof ["m";"n"] `sizel (iota m n) = n` [ (((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]))))); ((((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma iota_add *) let iota_add = Sections.section_proof ["m";"n1";"n2"] `iota m (n1 + n2) = iota m n1 ++ iota (m + n1) n2` [ (((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)))); (((((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)); ];; (* Lemma iota_addl *) let iota_addl = Sections.section_proof ["m1";"m2";"n"] `iota (m1 + m2) n = map ((+) m1) (iota m2 n)` [ (((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)))); (((((use_arg_then2 ("addnS", [addnS]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma nth_iota *) let nth_iota = Sections.section_proof ["m";"n";"i"] `i < n ==> nth 0 (iota m n) i = m + i` [ (((((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 [] [])))))); (((((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)); ];; (* Lemma mem_iota *) let mem_iota = Sections.section_proof ["m";"n";"i"] `(i <- iota m n) <=> (m <= i) /\ (i < m + n)` [ ((((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]))))); (((((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)); ((((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`)]))))); (((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)); (((((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)); (((((use_arg_then2 ("IHn", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma iota_uniq *) let iota_uniq = Sections.section_proof ["m";"n"] `uniq (iota m n)` [ (((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)))); (((((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)); ];; (* Section MakeSeq *) Sections.begin_section "MakeSeq";; (Sections.add_section_var (mk_var ("x0", (`:A`))));;
let mkseq = new_definition `mkseq f n = map f (iota 0 n)`;;
(* Lemma size_mkseq *) let size_mkseq = Sections.section_proof ["f";"n"] `sizel (mkseq f n) = n` [ (((((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)); ];; (* Lemma eq_mkseq *) let eq_mkseq = Sections.section_proof ["f";"g"] `(!x. f x = g x) ==> mkseq f = mkseq g` [ ((((((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)); ];; (* Lemma nth_mkseq *) let nth_mkseq = Sections.section_proof ["f";"n";"i"] `i < n ==> nth x0 (mkseq f n) i = f i` [ ((BETA_TAC THEN (move ["Hi"])) THEN (((use_arg_then2 ("mkseq", [mkseq]))(thm_tac (new_rewrite [] []))))); ((((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 ["_"]))); (((((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)); ];; (* Lemma mkseq_nth *) let mkseq_nth = Sections.section_proof ["s"] `mkseq (nth x0 s) (sizel s) = s` [ ((((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)); ];; (* Finalization of the section MakeSeq *) let size_mkseq = Sections.finalize_theorem size_mkseq;; let eq_mkseq = Sections.finalize_theorem eq_mkseq;; let nth_mkseq = Sections.finalize_theorem nth_mkseq;; let mkseq_nth = Sections.finalize_theorem mkseq_nth;; Sections.end_section "MakeSeq";; (* Lemma mkseq_uniq *) let mkseq_uniq = Sections.section_proof ["f";"n"] `(!x y. f x = f y ==> x = y) ==> uniq (mkseq f n)` [ ((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"])); (((((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)); ];; (* Section FoldRight *) Sections.begin_section "FoldRight";; (Sections.add_section_var (mk_var ("f", (`:A -> B -> B`))));; (Sections.add_section_var (mk_var ("z0", (`:B`))));;
let foldr = define `foldr f z0 (x :: s) = f x (foldr f z0 s) /\ foldr f z0 [] = z0`;;
(* Finalization of the section FoldRight *) Sections.end_section "FoldRight";; (* Section FoldRightComp *) Sections.begin_section "FoldRightComp";; (Sections.add_section_var (mk_var ("h", (`:A->B`))));; (Sections.add_section_var (mk_var ("f", (`:B->R->R`))));; (Sections.add_section_var (mk_var ("z0", (`:R`))));; (* Lemma foldr_cat *) let foldr_cat = Sections.section_proof ["s1";"s2"] `foldr f z0 (s1 ++ s2) = foldr f (foldr f z0 s2) s1` [ (((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)); ];; (* Lemma foldr_map *) let foldr_map = Sections.section_proof ["s"] `foldr f z0 (map h s) = foldr (\x z. f (h x) z) z0 s` [ (((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)); ];; (* Finalization of the section FoldRightComp *) let foldr_cat = Sections.finalize_theorem foldr_cat;; let foldr_map = Sections.finalize_theorem foldr_map;; Sections.end_section "FoldRightComp";;
let sumn = new_definition `sumn = foldr (+) 0`;;
(* Lemma sumn0 *) let sumn0 = Sections.section_proof [] `sumn [] = 0` [ (((((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)); ];; (* Lemma sumn_nseq *) let sumn_nseq = Sections.section_proof ["x";"n"] `sumn (nseq n x) = x * n` [ ((((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)))); (((((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)); ];; (* Lemma sumn_cat *) let sumn_cat = Sections.section_proof ["s1";"s2"] `sumn (s1 ++ s2) = sumn s1 + sumn s2` [ (((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)))); (((((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)); ];; (* Lemma natnseq0P *) let natnseq0P = Sections.section_proof ["s"] `sumn s = 0 <=> s = nseq (sizel s) 0` [ ((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))); ((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))); ((((((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)); ];; (* Section FoldLeft *) Sections.begin_section "FoldLeft";; (Sections.add_section_var (mk_var ("f", (`:R->A->R`))));;
let foldl = define `foldl f z (x :: s) = foldl f (f z x) s /\ foldl f z [] = z`;;
(* Lemma foldl_rev *) let foldl_rev = Sections.section_proof ["z";"s"] `foldl f z (rev s) = foldr (\x z0. f z0 x) z s` [ ((((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"]))); (((((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)); ((((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 [] [])))))); (((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)); ];; (* Lemma foldl_cat *) let foldl_cat = Sections.section_proof ["z";"s1";"s2"] `foldl f z (s1 ++ s2) = foldl f (foldl f z s1) s2` [ (((((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)); ];; (* Finalization of the section FoldLeft *) let foldl_rev = Sections.finalize_theorem foldl_rev;; let foldl_cat = Sections.finalize_theorem foldl_cat;; Sections.end_section "FoldLeft";; (* Section Scan *) Sections.begin_section "Scan";; (Sections.add_section_var (mk_var ("x1", (`:A`))));; (Sections.add_section_var (mk_var ("x2", (`:B`))));; (Sections.add_section_var (mk_var ("f", (`:A -> A -> B`))));; (Sections.add_section_var (mk_var ("g", (`:A -> B -> A`))));;
let pairmap = define `pairmap f x (y :: s) = f x y :: pairmap f y s /\ pairmap f x [] = []`;;
(* Lemma size_pairmap *) let size_pairmap = Sections.section_proof ["x";"s"] `sizel (pairmap f x s) = sizel s` [ ((((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)))); (((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)); ];; (* Lemma pairmap_cat *) let pairmap_cat = Sections.section_proof ["x";"s1";"s2"] `pairmap f x (s1 ++ s2) = pairmap f x s1 ++ pairmap f (last x s1) s2` [ ((((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]))))); ((((use_arg_then2 ("IHs1", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma nth_pairmap *) let nth_pairmap = Sections.section_proof ["s";"n"] `n < sizel s ==> !x. nth x2 (pairmap f x s) n = f (nth x1 (x :: s) n) (nth x1 s n)` [ (((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)))); ((((((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)); ];;
let scanl = define `scanl g x (y :: s) = g x y :: scanl g (g x y) s /\ scanl g x [] = []`;;
(* Lemma size_scanl *) let size_scanl = Sections.section_proof ["x";"s"] `sizel (scanl g x s) = sizel s` [ ((((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]))))); ((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma scanl_cat *) let scanl_cat = Sections.section_proof ["x";"s1";"s2"] `scanl g x (s1 ++ s2) = scanl g x s1 ++ scanl g (foldl g x s1) s2` [ ((((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)); ];; (* Lemma nth_scanl *) let nth_scanl = Sections.section_proof ["s";"n"] `n < sizel s ==> !x. nth x1 (scanl g x s) n = foldl g x (take (SUC n) s)` [ (((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)))); ((((((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)); ];; (* Lemma scanlK *) let scanlK = Sections.section_proof [] `(!x y. f x (g x y) = y) ==> (!x s. pairmap f x (scanl g x s) = s)` [ (BETA_TAC THEN (move ["Hfg"]) THEN (move ["x"]) THEN (move ["s"])); ((((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)); ];; (* Lemma pairmapK *) let pairmapK = Sections.section_proof [] `(!x y. g x (f x y) = y) ==> (!x s. scanl g x (pairmap f x s) = s)` [ (BETA_TAC THEN (move ["Hgf"]) THEN (move ["x"]) THEN (move ["s"])); ((((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)); ];; (* Finalization of the section Scan *) let size_pairmap = Sections.finalize_theorem size_pairmap;; let pairmap_cat = Sections.finalize_theorem pairmap_cat;; let nth_pairmap = Sections.finalize_theorem nth_pairmap;; let size_scanl = Sections.finalize_theorem size_scanl;; let scanl_cat = Sections.finalize_theorem scanl_cat;; let nth_scanl = Sections.finalize_theorem nth_scanl;; let scanlK = Sections.finalize_theorem scanlK;; let pairmapK = Sections.finalize_theorem pairmapK;; Sections.end_section "Scan";; (* Section Zip *) Sections.begin_section "Zip";;
let zip = define `zip (x :: s) (y :: t) = (x, y) :: zip s t /\
	zip [] t = [] /\ zip s [] = []`;;
let unzip1 = new_definition `unzip1 = map FST`;;
let unzip2 = new_definition `unzip2 = map SND`;;
(* Lemma zip_unzip *) let zip_unzip = Sections.section_proof ["s"] `zip (unzip1 s) (unzip2 s) = s` [ (((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]))))); (((((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)); ];; (* Lemma unzip1_zip *) let unzip1_zip = Sections.section_proof ["s";"t"] `sizel s <= sizel t ==> unzip1 (zip s t) = s` [ (((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)))); ((((((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)); ];; (* Lemma unzip2_zip *) let unzip2_zip = Sections.section_proof ["s";"t"] `sizel t <= sizel s ==> unzip2 (zip s t) = t` [ (((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)))); ((((((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)); ];; (* Lemma size1_zip *) let size1_zip = Sections.section_proof ["s";"t"] `sizel s <= sizel t ==> sizel (zip s t) = sizel s` [ (((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)))); ((((((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)); ];; (* Lemma size2_zip *) let size2_zip = Sections.section_proof ["s";"t"] `sizel t <= sizel s ==> sizel (zip s t) = sizel t` [ (((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)))); ((((((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)); ];; (* Lemma size_zip *) let size_zip = Sections.section_proof ["s";"t"] `sizel (zip s t) = minn (sizel s) (sizel t)` [ (((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)))); (((((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)); ];; (* Lemma zip_cat *) let zip_cat = Sections.section_proof ["s1";"s2";"t1";"t2"] `sizel s1 = sizel t1 ==> zip (s1 ++ s2) (t1 ++ t2) = zip s1 t1 ++ zip s2 t2` [ (((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)))); (((((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)); ];; (* Lemma nth_zip *) let nth_zip = Sections.section_proof ["x";"y";"s";"t";"i"] `sizel s = sizel t ==> nth (x, y) (zip s t) i = (nth x s i, nth y t i)` [ (((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)))); (((((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)); ];; (* Lemma nth_zip_cond *) let nth_zip_cond = Sections.section_proof ["p";"s";"t";"i"] `nth p (zip s t) i = (if i < sizel (zip s t) then (nth (FST p) s i, nth (SND p) t i) else p)` [ ((((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 [] []))))); (((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)))); (((((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)); ];; (* Lemma zip_rcons *) let zip_rcons = Sections.section_proof ["s1";"s2";"z1";"z2"] `sizel s1 = sizel s2 ==> zip (rcons s1 z1) (rcons s2 z2) = rcons (zip s1 s2) (z1, z2)` [ ((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)); ];; (* Lemma rev_zip *) let rev_zip = Sections.section_proof ["s1";"s2"] `sizel s1 = sizel s2 ==> rev (zip s1 s2) = zip (rev s1) (rev s2)` [ ((((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))))); (((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"])); (((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)); ];; (* Finalization of the section Zip *) let zip_unzip = Sections.finalize_theorem zip_unzip;; let unzip1_zip = Sections.finalize_theorem unzip1_zip;; let unzip2_zip = Sections.finalize_theorem unzip2_zip;; let size1_zip = Sections.finalize_theorem size1_zip;; let size2_zip = Sections.finalize_theorem size2_zip;; let size_zip = Sections.finalize_theorem size_zip;; let zip_cat = Sections.finalize_theorem zip_cat;; let nth_zip = Sections.finalize_theorem nth_zip;; let nth_zip_cond = Sections.finalize_theorem nth_zip_cond;; let zip_rcons = Sections.finalize_theorem zip_rcons;; let rev_zip = Sections.finalize_theorem rev_zip;; Sections.end_section "Zip";; (* Section Flatten *) Sections.begin_section "Flatten";; (Sections.add_section_type (mk_var ("s", (`:(A)list`))));; (Sections.add_section_type (mk_var ("ss", (`:((A)list)list`))));;
let flatten = new_definition `flatten = foldr cat []`;;
let shape = new_definition `shape = map sizel`;;
let reshape = define `reshape (n :: sh) s = take n s :: reshape sh (dropl n s) /\
	reshape [] s = []`;;
(* Lemma flatten0 *) let flatten0 = Sections.section_proof [] `flatten [] = []` [ (((((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)); ];; (* Lemma flatten_cons *) let flatten_cons = Sections.section_proof ["s";"ss"] `flatten (s :: ss) = s ++ flatten ss` [ (((((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)); ];; (* Lemma size_flatten *) let size_flatten = Sections.section_proof ["ss"] `sizel (flatten ss) = sumn (shape ss)` [ (((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)))); (((((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)); ];; (* Lemma flatten_cat *) let flatten_cat = Sections.section_proof ["ss1";"ss2"] `flatten (ss1 ++ ss2) = flatten ss1 ++ flatten ss2` [ (((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]))))); (((((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("catA", [catA]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma flattenK *) let flattenK = Sections.section_proof ["ss"] `reshape (shape ss) (flatten ss) = ss` [ (((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)))); (((((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)); ];; (* Lemma reshapeKr *) let reshapeKr = Sections.section_proof ["sh";"s"] `sizel s <= sumn sh ==> flatten (reshape sh s) = s` [ ((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"]))]); (((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)); ((((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]))))); (((((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)); (((((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)); ];; (* Lemma reshapeKl *) let reshapeKl = Sections.section_proof ["sh";"s"] `sumn sh <= sizel s ==> shape (reshape sh s) = sh` [ ((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"]))]); (((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)); ((((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"]))); (((((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 [] []))))); ((((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)); (((((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)); ];; (* Finalization of the section Flatten *) let flatten0 = Sections.finalize_theorem flatten0;; let flatten_cons = Sections.finalize_theorem flatten_cons;; let size_flatten = Sections.finalize_theorem size_flatten;; let flatten_cat = Sections.finalize_theorem flatten_cat;; let flattenK = Sections.finalize_theorem flattenK;; let reshapeKr = Sections.finalize_theorem reshapeKr;; let reshapeKl = Sections.finalize_theorem reshapeKl;; Sections.end_section "Flatten";; (* Section AllPairs *) Sections.begin_section "AllPairs";; (Sections.add_section_var (mk_var ("f", (`:S->T->R`))));; (Sections.add_section_type (mk_var ("s", (`:(S)list`))));; (Sections.add_section_type (mk_var ("t", (`:(T)list`))));;
let allpairs = new_definition `allpairs f s t = foldr (\x. cat (map (f x) t)) [] s`;;
(* Lemma size_allpairs *) let size_allpairs = Sections.section_proof ["s";"t"] `sizel (allpairs f s t) = sizel s * sizel t` [ (((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)))); (((((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)); ];; (* Lemma allpairs_cat *) let allpairs_cat = Sections.section_proof ["s1";"s2";"t"] `allpairs f (s1 ++ s2) t = allpairs f s1 t ++ allpairs f s2 t` [ (((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)))); (((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)); ];; (* Finalization of the section AllPairs *) let size_allpairs = Sections.finalize_theorem size_allpairs;; let allpairs_cat = Sections.finalize_theorem allpairs_cat;; Sections.end_section "AllPairs";; (* Section EqAllPairs *) Sections.begin_section "EqAllPairs";; (Sections.add_section_var (mk_var ("f", (`:S->T->R`))));; (Sections.add_section_type (mk_var ("s", (`:(S)list`))));; (Sections.add_section_type (mk_var ("t", (`:(T)list`))));; (* Lemma allpairsP *) let allpairsP = Sections.section_proof ["s";"t";"z"] `(z <- allpairs f s t) <=> (?p. FST p <- s /\ SND p <- t /\ z = f (FST p) (SND p))` [ (((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)))); (((((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)); ((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))); (((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (((use_arg_then2 ("in_cons", [in_cons]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ((((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"]))))); ((DISJ1_TAC) THEN ((fun arg_tac -> arg_tac (Arg_term (`SND p`))) (term_tac exists_tac)) THEN (done_tac)); ((DISJ2_TAC) THEN ((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma mem_allpairs *) let mem_allpairs = Sections.section_proof ["s1";"t1";"s2";"t2"] `(!x. x <- s1 <=> x <- s2) ==> (!y. y <- t1 <=> y <- t2) ==> (!p. p <- allpairs f s1 t1 <=> p <- allpairs f s2 t2)` [ (BETA_TAC THEN (move ["eq_s"]) THEN (move ["eq_t"]) THEN (move ["z"])); ((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"]))); (((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (done_tac)); (((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma allpairs_catr *) let allpairs_catr = Sections.section_proof ["s";"t1";"t2"] `!p. p <- allpairs f s (t1 ++ t2) <=> p <- allpairs f s t1 ++ allpairs f s t2` [ ((BETA_TAC THEN (move ["z"])) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] []))))); ((((use_arg_then2 ("allpairsP", [allpairsP]))(thm_tac (new_rewrite [] [])))) THEN ((THENL) (split_tac) [(case THEN ((move ["p"]) THEN (case THEN (move ["sP1"])))); ALL_TAC])); (((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)); (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)); ];; (* Finalization of the section EqAllPairs *) let allpairsP = Sections.finalize_theorem allpairsP;; let mem_allpairs = Sections.finalize_theorem mem_allpairs;; let allpairs_catr = Sections.finalize_theorem allpairs_catr;; Sections.end_section "EqAllPairs";; (* Close the module *) end;;