needs "Examples/seq-compiled.hl";;
flyspeck_needs "hypermap/hypermap.hl";;

(* Module Seq2*)
module Seq2 = struct

open Ssrbool;;
open Ssrnat;;
open Seq;;
parse_as_infix ("::", (12, "right"));;
override_interface ("::", `CONS`);;
make_overloadable "++" `:A -> A -> A`;;
overload_interface ("++", `cat`);;
parse_as_infix("<-", (11, "right"));;
override_interface("<-", `MEM`);;
let delete_at = (GEN_ALL o define) `delete_at i [] = [] /\ delete_at 0 (h :: t) = t /\ 
	delete_at (SUC i) (h :: t) = h :: delete_at i t`;;
let delete1 = (GEN_ALL o define) 
	`delete1 x [] = [] /\ delete1 x (h :: t) = if x = h then t else h :: delete1 x t`;;
let butlast = (GEN_ALL o define)
  `butlast [] = [] /\ butlast [h] = [] /\ butlast (h :: (h2 :: t)) = h :: butlast (h2 :: t)`;;
let list_sum = new_definition `list_sum s f = foldr (\a b. f a + b) (&0) s`;;
let list_sumn = new_definition `list_sumn s f = foldr (\a b. f a + b) 0 s`;;
let next_el = new_definition `next_el s x = 
  if (indexl x s = sizel s - 1) then (headl x s) else (nth x s (indexl x s + 1))`;;
let prev_el = new_definition `prev_el s x = 
	if ~(MEM x s) then x
		else if (indexl x s = 0) then (last x s) else (nth x s (indexl x s - 1))`;;
let EL = GEN_ALL EL;; let HD = GEN_ALL HD;; let TL = GEN_ALL TL;; let MEM = GEN_ALL MEM;; let ALL = GEN_ALL ALL;; let ALL2 = GEN_ALL ALL2;; let uniq = GEN_ALL uniq;; let foldr = GEN_ALL foldr;; let iter = GEN_ALL iter;; let undup = GEN_ALL undup;; let iota = GEN_ALL iota;; let map = GEN_ALL map;; let zip = GEN_ALL zip;; let take = GEN_ALL Seq.take;; (* Lemma pair_expand *) let pair_expand = Sections.section_proof ["p"] `p = FST p, SND p` [ ((ALL_TAC) THEN (done_tac)); ];; (* Section SeqList *) Sections.begin_section "SeqList";; (* Lemma ALL_all *) let ALL_all = Sections.section_proof [] `ALL = all` [ (((repeat_tactic 1 9 (((use_arg_then2 ("FUN_EQ_THM", [FUN_EQ_THM]))(thm_tac (new_rewrite [] []))))) THEN (move ["P"])) THEN ((THENL) elim [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("ALL", [ALL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("all", [all]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma APPEND_cat *) let APPEND_cat = Sections.section_proof [] `APPEND = cat` [ ((repeat_tactic 1 9 (((use_arg_then2 ("FUN_EQ_THM", [FUN_EQ_THM]))(thm_tac (new_rewrite [] []))))) THEN ((THENL) elim [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("APPEND", [APPEND]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat", [cat]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma head_HD *) let head_HD = Sections.section_proof ["x0";"s"] `0 < sizel s ==> headl x0 s = HD s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((((fun arg_tac ->(use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg1 -> (use_arg_then2 ("head", [head]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac ->(use_arg_then2 ("ltn0", [ltn0]))(fun tmp_arg1 -> (use_arg_then2 ("HD", [HD]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma EL_nth *) let EL_nth = Sections.section_proof ["x0";"s";"i"] `i < sizel s ==> EL i s = nth x0 s i` [ ((((THENL) (((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 ["n"]) THEN (move ["IH"]))]) THEN ((THENL) case [ALL_TAC; ((move ["h"]) THEN (move ["t"]))])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("EL", [EL]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nth", [nth]))(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 (repeat_tactic 0 10 (((use_arg_then2 ("HD", [HD]))(thm_tac (new_rewrite [] [])))))) THEN (TRY ((arith_tac)))); ((((((use_arg_then2 ("TL", [TL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (move ["n_lt"])) THEN (((use_arg_then2 ("IH", [])) (disch_tac [])) THEN (clear_assumption "IH") THEN (DISCH_THEN apply_tac)) THEN (((use_arg_then2 ("size", [size]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma EL_map *) let EL_map = Sections.section_proof ["i";"s";"f"] `i < LENGTH s ==> EL i (map f s) = f (EL i s)` [ ((((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (BETA_TAC THEN (move ["i_lt"])) THEN ((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_map", [size_map]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); ((((fun arg_tac -> (use_arg_then2 ("nth_map", [nth_map])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (term_tac exists_tac)) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); ((((use_arg_then2 ("EL_nth", [EL_nth]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma EL_mkseq *) let EL_mkseq = Sections.section_proof ["i";"f";"n"] `i < n ==> EL i (mkseq f n) = f i` [ ((BETA_TAC THEN (move ["i_lt"])) THEN ((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma all_EL_P *) let all_EL_P = Sections.section_proof ["a";"s"] `(!i. i < sizel s ==> a (EL i s)) <=> all a s` [ ((THENL) (split_tac) [(move ["h"]); ((move ["all_s"]) THEN (move ["i"]) THEN (move ["i_lt"]))]); ((((fun arg_tac -> (use_arg_then2 ("all_nthP", [all_nthP])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (move ["i"]) THEN (move ["i_lt"])); (((((use_arg_then2 ("EL_nth", [EL_nth]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("h", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((in_tac ["all_s"] false (((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((((use_arg_then2 ("all_s", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM_EL", [MEM_EL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma EL_take *) let EL_take = Sections.section_proof ["n";"i";"s"] `i < n /\ i < sizel s ==> EL i (take n s) = EL i s` [ (BETA_TAC THEN (case THEN ((move ["i_lt_n"]) THEN (move ["i_lt"])))); ((THENL_FIRST) ((repeat_tactic 1 9 (((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] [])))))) ((((use_arg_then2 ("i_lt_n", [])) (disch_tac [])) THEN (clear_assumption "i_lt_n") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((((use_arg_then2 ("nth_take", [nth_take]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma EL_index *) let EL_index = Sections.section_proof ["x";"s"] `x <- s ==> EL (indexl x s) s = x` [ ((BETA_TAC THEN (move ["mem_x"])) THEN ((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma ALL2_cat *) let ALL2_cat = Sections.section_proof ["f";"s1";"t1";"s2";"t2"] `sizel s1 = sizel s2 ==> (ALL2 f (s1 ++ t1) (s2 ++ t2) <=> ALL2 f s1 s2 /\ ALL2 f t1 t2)` [ ((((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 ["h1"]) THEN (move ["r1"]) THEN (move ["Ih"]))]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["r2"]))])) THEN ((repeat_tactic 1 9 (((fun arg_tac ->(use_arg_then2 ("size_cons", [size_cons]))(fun tmp_arg1 -> (use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("cat", [cat]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ALL2", [ALL2]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (TRY ((arith_tac)))); (((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("Ih", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("andbA", [andbA]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Finalization of the section SeqList *) let ALL_all = Sections.finalize_theorem ALL_all;; let APPEND_cat = Sections.finalize_theorem APPEND_cat;; let head_HD = Sections.finalize_theorem head_HD;; let EL_nth = Sections.finalize_theorem EL_nth;; let EL_map = Sections.finalize_theorem EL_map;; let EL_mkseq = Sections.finalize_theorem EL_mkseq;; let all_EL_P = Sections.finalize_theorem all_EL_P;; let EL_take = Sections.finalize_theorem EL_take;; let EL_index = Sections.finalize_theorem EL_index;; let ALL2_cat = Sections.finalize_theorem ALL2_cat;; Sections.end_section "SeqList";; (* Section Misc *) Sections.begin_section "Misc";; (* Lemma length_le_1 *) let length_le_1 = Sections.section_proof ["s"] `LENGTH s <= 1 ==> s = [] \/ s = [HD s]` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]))]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("LENGTH", [LENGTH]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("HD", [HD]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma count0 *) let count0 = Sections.section_proof ["P";"s"] `count P s = 0 <=> all (predC P) s` [ (((((use_arg_then2 ("all_predC", [all_predC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma count_filterI *) let count_filterI = Sections.section_proof ["a1";"a2";"s"] `count a1 (filter a2 s) = count (predI a1 a2) s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("predI", [predI]))(thm_tac (new_rewrite [1] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("IH", []))(gsym_then (thm_tac (new_rewrite [] []))))))); ((((fun arg_tac -> arg_tac (Arg_term (`a2 h`))) (disch_tac [])) THEN case THEN (simp_tac)) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma seq_eq_mkseq *) let seq_eq_mkseq = Sections.section_proof ["x0";"s"] `s = mkseq (nth x0 s) (sizel 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))) (thm_tac apply_tac)) THEN (((((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["i"]) THEN (move ["i_lt"])) THEN (((use_arg_then2 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma seq_wf_ind *) let seq_wf_ind = Sections.section_proof ["P"] `(!s:(A)list. (!l. LENGTH l < LENGTH s ==> P l) ==> P s) ==> (!s. P s)` [ (((fun arg_tac -> (use_arg_then2 ("WF_MEASURE", [WF_MEASURE])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`LENGTH:(A)list->num`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC); ((((((fun arg_tac -> arg_tac (Arg_theorem (GEN_ALL WF_IND)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEASURE", [MEASURE]))(thm_tac (new_rewrite [] []))))) THEN ((fun arg_tac -> (conv_thm_tac DISCH_THEN) (fun fst_arg -> (use_arg_then2 ("P", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac MP_TAC)) THEN (move ["h"]) THEN (move ["h2"]) THEN (move ["s"])) THEN (((use_arg_then2 ("h", [])) (disch_tac [])) THEN (clear_assumption "h") THEN (exact_tac)) THEN (done_tac)); ];; (* Lemma length_eq_imp_length_tl_eq *) let length_eq_imp_length_tl_eq = Sections.section_proof ["s1";"s2"] `LENGTH (s1:(A)list) = LENGTH (s2:(A)list) ==> LENGTH (TL s1) = LENGTH (TL s2)` [ ((((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN (move ["s2"])) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(thm_tac (new_rewrite [] []))))); ((((((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("LENGTH_EQ_NIL", [LENGTH_EQ_NIL]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((BETA_TAC THEN (move ["len_eq"])) THEN ((((use_arg_then2 ("TL", [TL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("LENGTH_TL", [LENGTH_TL]))(thm_tac (new_rewrite [] [])))))); ((((use_arg_then2 ("len_eq", [])) (disch_tac [])) THEN (clear_assumption "len_eq") THEN ((use_arg_then2 ("contraL", [contraL])) (disch_tac [])) THEN (clear_assumption "contraL") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(thm_tac (new_rewrite [] [])))) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("len_eq", [])) (disch_tac [])) THEN (clear_assumption "len_eq") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma ge_length_imp_EL_eq *) let ge_length_imp_EL_eq = Sections.section_proof ["k";"s1";"s2"] `LENGTH s1 = LENGTH s2 /\ LENGTH s1 <= k ==> EL k s1 = EL k s2` [ ((((THENL) (((use_arg_then2 ("s2", [])) (disch_tac [])) THEN (clear_assumption "s2") THEN ((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN ((use_arg_then2 ("k", [])) (disch_tac [])) THEN (clear_assumption "k") THEN elim) [ALL_TAC; ((move ["k"]) THEN (move ["IH"]))]) THEN (move ["s1"]) THEN (move ["s2"])) THEN (repeat_tactic 1 9 (((use_arg_then2 ("EL", [EL]))(thm_tac (new_rewrite [] [])))))); (((((use_arg_then2 ("leqn0", [leqn0]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN ((move ["len_eq"]) THEN (move ["s1_0"])))) THEN (((use_arg_then2 ("s1_0", [])) (disch_tac [])) THEN ((use_arg_then2 ("len_eq", [])) (disch_tac [])) THEN (clear_assumption "len_eq") THEN BETA_TAC)); ((((((use_arg_then2 ("s1_0", []))(thm_tac (new_rewrite [1] [])))) THEN (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("LENGTH_EQ_NIL", [LENGTH_EQ_NIL]))(thm_tac (new_rewrite [] [])))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (BETA_TAC THEN (case THEN ((move ["len_eq"]) THEN (move ["len_le"])))); (((fun arg_tac -> arg_tac (Arg_term (`LENGTH s2 = 0`))) (disch_eq_tac "s2_len" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); ((((use_arg_then2 ("s2_len", [])) (disch_tac [])) THEN ((use_arg_then2 ("len_eq", [])) (disch_tac [])) THEN (clear_assumption "len_eq") THEN BETA_TAC) THEN (((((use_arg_then2 ("s2_len", []))(thm_tac (new_rewrite [1] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("LENGTH_EQ_NIL", [LENGTH_EQ_NIL]))(thm_tac (new_rewrite [] [])))))) 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 ("IH", [])) (disch_tac [])) THEN (clear_assumption "IH") THEN (DISCH_THEN apply_tac)) THEN ((((fun arg_tac -> (use_arg_then2 ("length_eq_imp_length_tl_eq", [length_eq_imp_length_tl_eq])) (fun fst_arg -> (use_arg_then2 ("len_eq", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (simp_tac))); ((THENL_FIRST) (((use_arg_then2 ("LENGTH_TL", [LENGTH_TL]))(thm_tac (new_rewrite [] [])))) ((((use_arg_then2 ("s2_len", [])) (disch_tac [])) THEN (clear_assumption "s2_len") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("len_eq", [])) (disch_tac [])) THEN (clear_assumption "len_eq") THEN ((use_arg_then2 ("len_le", [])) (disch_tac [])) THEN (clear_assumption "len_le") THEN ((use_arg_then2 ("s2_len", [])) (disch_tac [])) THEN (clear_assumption "s2_len") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma mem_nseq *) let mem_nseq = Sections.section_proof ["n";"x";"y"] `y <- nseq n x <=> 0 < n /\ y = x` [ (((((use_arg_then2 ("MEM_EXISTS_EL", [MEM_EXISTS_EL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_nseq", [size_nseq]))(thm_tac (new_rewrite [] []))))) THEN ((THENL) (split_tac) [((case THEN (move ["i"])) THEN (case THEN (move ["i_lt"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))); ((case THEN (move ["n_gt0"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))])); (((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_nseq", [size_nseq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_nseq", [nth_nseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("i_lt", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); (((fun arg_tac -> arg_tac (Arg_term (`0`))) (term_tac exists_tac)) THEN ((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_nseq", [size_nseq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_nseq", [nth_nseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("n_gt0", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma mem_flatten *) let mem_flatten = Sections.section_proof ["x";"L"] `MEM x (flatten L) <=> ?l. MEM l L /\ MEM x l` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("L", [])) (disch_tac [])) THEN (clear_assumption "L") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) (((((use_arg_then2 ("flatten0", [flatten0]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac))); ((((use_arg_then2 ("flatten_cons", [flatten_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_cat", [mem_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] []))))); (((THENL) ((THENL) (split_tac) [((THENL) case [(move ["xh"]); ((case THEN (move ["l"])) THEN (move ["h"]))]); ((case THEN (move ["l"])) THEN (case THEN ((move ["h1"]) THEN (move ["xl"]))))]) [((use_arg_then2 ("h", [])) (term_tac exists_tac)); ((use_arg_then2 ("l", [])) (term_tac exists_tac)); (ALL_TAC)]) THEN (BETA_TAC THEN ((TRY done_tac)))); (((THENL) (((use_arg_then2 ("h1", [])) (disch_tac [])) THEN (clear_assumption "h1") THEN case) [((((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))); (move ["lt"])]) THEN (DISJ2_TAC) THEN ((use_arg_then2 ("l", [])) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma size1 *) let size1 = Sections.section_proof ["x"] `sizel [x] = 1` [ (((((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 ("ONE", [ONE]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma size1_eq *) let size1_eq = Sections.section_proof ["s"] `sizel s = 1 <=> ?x. s = [x]` [ ((THENL_LAST) ((THENL) (split_tac) [ALL_TAC; ((case THEN (move ["x"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))]) ((((use_arg_then2 ("size1", [size1]))(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 ["h"]) THEN (move ["t"]))]) ((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (arith_tac) THEN (done_tac))); ((((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ONE", [ONE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_eq0", [size_eq0]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN ((use_arg_then2 ("h", [])) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma cons_head_drop1 *) let cons_head_drop1 = Sections.section_proof ["x0";"s"] `0 < sizel s ==> s = (headl x0 s) :: (dropl 1 s)` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN ((repeat_tactic 0 10 (((fun arg_tac ->(use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg1 -> (use_arg_then2 ("ltn0", [ltn0]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ONE", [ONE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("head", [head]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("drop", [drop]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma last_eq *) let last_eq = Sections.section_proof ["a";"b";"s"] `0 < sizel s ==> last a s = last b s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("last", [last]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma last_drop *) let last_drop = Sections.section_proof ["x0";"s";"n"] `n < sizel s ==> last x0 (dropl n s) = last x0 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 ["h"]) THEN (move ["t"]) THEN (move ["Ih"]) THEN ((THENL) case [ALL_TAC; (move ["n"])]))]) THEN (((((fun arg_tac ->(use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg1 -> (use_arg_then2 ("size_cons", [size_cons]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("drop", [drop]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (move ["n_lt"]))); (((((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("last", [last]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("last_eq", [last_eq])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("h", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("n_lt", [])) (disch_tac [])) THEN (clear_assumption "n_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Finalization of the section Misc *) let length_le_1 = Sections.finalize_theorem length_le_1;; let count0 = Sections.finalize_theorem count0;; let count_filterI = Sections.finalize_theorem count_filterI;; let seq_eq_mkseq = Sections.finalize_theorem seq_eq_mkseq;; let seq_wf_ind = Sections.finalize_theorem seq_wf_ind;; let length_eq_imp_length_tl_eq = Sections.finalize_theorem length_eq_imp_length_tl_eq;; let ge_length_imp_EL_eq = Sections.finalize_theorem ge_length_imp_EL_eq;; let mem_nseq = Sections.finalize_theorem mem_nseq;; let mem_flatten = Sections.finalize_theorem mem_flatten;; let size1 = Sections.finalize_theorem size1;; let size1_eq = Sections.finalize_theorem size1_eq;; let cons_head_drop1 = Sections.finalize_theorem cons_head_drop1;; let last_eq = Sections.finalize_theorem last_eq;; let last_drop = Sections.finalize_theorem last_drop;; Sections.end_section "Misc";; (* Section MoreZip *) Sections.begin_section "MoreZip";; (* Lemma mem_zip *) let mem_zip = Sections.section_proof ["s1";"s2";"a";"b"] `MEM (a,b) (zip s1 s2) ==> MEM a s1 /\ MEM b 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 ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t2"]))])) THEN ((((use_arg_then2 ("zip", [zip]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("PAIR_EQ", [PAIR_EQ]))(thm_tac (new_rewrite [] [])))))); (((THENL) case [(case THEN ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))); (DISCH_THEN (fun snd_th -> (use_arg_then2 ("Ih", [])) (thm_tac (match_mp_then snd_th MP_TAC))))]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (done_tac)); ];; (* Lemma EL_zip *) let EL_zip = Sections.section_proof ["s1";"s2";"i"] `sizel s1 = sizel s2 /\ i < sizel s1 ==> EL i (zip s1 s2) = (EL i s1, EL i s2)` [ (BETA_TAC THEN (case THEN ((move ["size_eq"]) THEN (move ["i_lt"])))); ((fun arg_tac -> arg_tac (Arg_term (`HD s1`))) (term_tac (set_tac "x0"))); ((fun arg_tac -> arg_tac (Arg_term (`HD s2`))) (term_tac (set_tac "y0"))); ((THENL_FIRST) (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`x0,y0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`zip s1 s2`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) (((((use_arg_then2 ("size1_zip", [size1_zip]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("i_lt", []))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("nth_zip", [nth_zip]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("PAIR_EQ", [PAIR_EQ]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("EL_nth", [EL_nth]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma take_zip *) let take_zip = Sections.section_proof ["s1";"s2";"n"] `take n (zip s1 s2) = zip (take n s1) (take n s2)` [ ((((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((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 ["h1"]) THEN (move ["t1"]) THEN (move ["Ih1"]))]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t2"]))])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("zip", [zip]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("zip", [zip]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((THENL) case [ALL_TAC; (move ["n"])]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("zip", [zip]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma drop_zip *) let drop_zip = Sections.section_proof ["s1";"s2";"n"] `dropl n (zip s1 s2) = zip (dropl n s1) (dropl n s2)` [ ((((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN ((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 ["h1"]) THEN (move ["t2"]) THEN (move ["Ih1"]))]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t2"]))])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("drop", [drop]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("zip", [zip]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("drop", [drop]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("zip", [zip]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((THENL) case [ALL_TAC; (move ["n"])]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("drop", [drop]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("zip", [zip]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma rot_zip *) let rot_zip = Sections.section_proof ["s1";"s2";"n"] `sizel s1 = sizel s2 ==> rot n (zip s1 s2) = zip (rot n s1) (rot n s2)` [ (BETA_TAC THEN (move ["size_eq"])); (((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop_zip", [drop_zip]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take_zip", [take_zip]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("zip_cat", [zip_cat]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("rot", [rot]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_eq", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma rotr_zip *) let rotr_zip = Sections.section_proof ["s1";"s2";"n"] `sizel s1 = sizel s2 ==> rotr n (zip s1 s2) = zip (rotr n s1) (rotr n s2)` [ (BETA_TAC THEN (move ["size_eq"])); (((repeat_tactic 1 9 (((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size1_zip", [size1_zip]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_eq", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("rot_zip", [rot_zip]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Finalization of the section MoreZip *) let mem_zip = Sections.finalize_theorem mem_zip;; let EL_zip = Sections.finalize_theorem EL_zip;; let take_zip = Sections.finalize_theorem take_zip;; let drop_zip = Sections.finalize_theorem drop_zip;; let rot_zip = Sections.finalize_theorem rot_zip;; let rotr_zip = Sections.finalize_theorem rotr_zip;; Sections.end_section "MoreZip";; (* Section MoreUniq *) Sections.begin_section "MoreUniq";; (* Lemma uniq_small_size *) let uniq_small_size = Sections.section_proof ["l"] `sizel l < 2 ==> uniq l` [ (((THENL) (((use_arg_then2 ("l", [])) (disch_tac [])) THEN (clear_assumption "l") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN ((((use_arg_then2 ("uniq", [uniq]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN case) [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("uniq", [uniq]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma mem_imp_not_uniq_cat *) let mem_imp_not_uniq_cat = Sections.section_proof ["x";"l1";"l2"] `MEM x l1 /\ MEM x l2 ==> ~(uniq (cat l1 l2))` [ ((BETA_TAC THEN (case THEN ((move ["x_l1"]) THEN (move ["x_l2"])))) THEN ((((use_arg_then2 ("cat_uniq", [cat_uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("negb_and", [negb_and]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("negbK", [negbK]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac))); ((DISJ2_TAC) THEN (DISJ1_TAC) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma uniq_nthP *) let uniq_nthP = Sections.section_proof ["x0";"s"] `uniq s <=> (!i j. i < j /\ j < sizel s ==> ~(nth x0 s i = nth x0 s j))` [ ((THENL_FIRST) (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("uniq", [uniq]))(thm_tac (new_rewrite [] [])))) 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 [] []))))))) ((arith_tac) THEN (done_tac))); ((THENL) (split_tac) [((case THEN ((move ["n_mem"]) THEN (move ["uniq_t"]))) THEN (move ["i"]) THEN (move ["j"]) THEN (case THEN ((move ["i_lt_j"]) THEN (move ["j_lt"])))); (move ["h"])]); ((((THENL) (((use_arg_then2 ("j_lt", [])) (disch_tac [])) THEN (clear_assumption "j_lt") THEN ((use_arg_then2 ("i_lt_j", [])) (disch_tac [])) THEN (clear_assumption "i_lt_j") THEN ((use_arg_then2 ("j", [])) (disch_tac [])) THEN (clear_assumption "j") THEN ((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN case) [ALL_TAC; (move ["i"])]) THEN ((THENL) case [ALL_TAC; (move ["j"])])) THEN (TRY ((arith_tac)))); (((((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))))) THEN (move ["_"]) THEN (move ["j_lt"])); ((((use_arg_then2 ("n_mem", [])) (disch_tac [])) THEN (clear_assumption "n_mem") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); (((repeat_tactic 1 9 (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))))) THEN (move ["i_lt_j"]) THEN (move ["j_lt"])); ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("iffLR", [iffLR])) (fun fst_arg -> (use_arg_then2 ("IH", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("uniq_t", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); (split_tac); ((((use_arg_then2 ("h", [])) (disch_tac [])) THEN (clear_assumption "h") THEN ((use_arg_then2 ("contraL", [contraL])) (disch_tac [])) THEN (clear_assumption "contraL") THEN (DISCH_THEN apply_tac) THEN (move ["mem_h"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("NOT_FORALL_THM", [NOT_FORALL_THM]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("NOT_IMP", [NOT_IMP]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negbK", [negbK]))(thm_tac (new_rewrite [] [])))))); (((fun arg_tac -> arg_tac (Arg_term (`0`))) (term_tac exists_tac)) THEN ((fun arg_tac -> arg_tac (Arg_term (`SUC (indexl h t)`))) (term_tac exists_tac))); (((((use_arg_then2 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] [])))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (move ["i"]) THEN (move ["j"]) THEN (case THEN ((move ["i_lt_j"]) THEN (move ["j_lt"])))); ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("h", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`SUC i`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`SUC j`))) (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 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("j_lt", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("i_lt_j", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma uniq_map_nth *) let uniq_map_nth = Sections.section_proof ["x0";"p";"s"] `uniq s /\ uniq p /\ all (\i:num. i < sizel s) p ==> uniq (map (nth x0 s) p)` [ (((((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN ALL_TAC THEN (case THEN (move ["uniq_s"])) THEN (case THEN (move ["uniq_p"])) THEN (move ["in_p"])); (((((use_arg_then2 ("map_inj_in_uniq", [map_inj_in_uniq]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (move ["i"]) THEN (move ["j"]) THEN (case THEN ALL_TAC) THEN (case THEN ((move ["i_p"]) THEN (move ["j_p"])))); (((((fun arg_tac -> (use_arg_then2 ("nth_uniq", [nth_uniq])) (fun fst_arg -> (use_arg_then2 ("uniq_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("in_p", []))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma uniq_index_inj *) let uniq_index_inj = Sections.section_proof ["x";"y";"s"] `uniq s /\ x <- s /\ y <- s ==> (indexl x s = indexl y s <=> x = y)` [ ((BETA_TAC THEN (case THEN (move ["uniq_s"])) THEN (case THEN (move ["xs"])) THEN (move ["ys"])) THEN ((THENL) (split_tac) [ALL_TAC; ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))])); ((((use_arg_then2 ("ys", [])) (disch_tac [])) THEN (clear_assumption "ys") THEN ((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN BETA_TAC) THEN (((repeat_tactic 1 9 (((use_arg_then2 ("MEM_EXISTS_EL", [MEM_EXISTS_EL]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ALL_TAC THEN (case THEN (move ["i"])) THEN (case THEN (move ["i_lt"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (case THEN (move ["j"])) THEN (case THEN (move ["j_lt"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))); ((((repeat_tactic 1 9 (((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("index_uniq", [index_uniq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Finalization of the section MoreUniq *) let uniq_small_size = Sections.finalize_theorem uniq_small_size;; let mem_imp_not_uniq_cat = Sections.finalize_theorem mem_imp_not_uniq_cat;; let uniq_nthP = Sections.finalize_theorem uniq_nthP;; let uniq_map_nth = Sections.finalize_theorem uniq_map_nth;; let uniq_index_inj = Sections.finalize_theorem uniq_index_inj;; Sections.end_section "MoreUniq";; (* Section MoreIndex *) Sections.begin_section "MoreIndex";; (* Lemma index_nil *) let index_nil = Sections.section_proof ["x"] `indexl x [] = 0` [ (((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("find", [find]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma index_cons *) let index_cons = Sections.section_proof ["x";"h";"t"] `indexl x (h :: t) = if x = h then 0 else SUC (indexl x t)` [ (((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [1] [])))) THEN (((use_arg_then2 ("find", [find]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("pred1", [pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index", [index]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((fun arg_tac -> arg_tac (Arg_term (`x = h`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) THEN (done_tac)); ];; (* Lemma index_eq_size *) let index_eq_size = Sections.section_proof ["x";"s"] `~(MEM x s) <=> indexl x s = sizel s` [ (((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_find", [has_find]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn_neqAle", [ltn_neqAle]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("find_size", [find_size]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbT", [andbT]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("negbK", [negbK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma index_head *) let index_head = Sections.section_proof ["x0";"s"] `indexl (headl x0 s) s = 0` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN ((((use_arg_then2 ("index", [index]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("find", [find]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("head", [head]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma index_take *) let index_take = Sections.section_proof ["s";"n";"x"] `indexl x (take n s) = if indexl x s < n then (indexl x s) else 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 ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((THENL) case [ALL_TAC; (move ["n"])])) THEN ((((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_nil", [index_nil]))(thm_tac (new_rewrite [] [])))))) THEN (TRY ((arith_tac)))); (repeat_tactic 1 9 (((use_arg_then2 ("index_cons", [index_cons]))(thm_tac (new_rewrite [] []))))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`x = h`))) (disch_eq_tac "x_eq_h" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) ((arith_tac) THEN (done_tac))); (((((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> arg_tac (Arg_term (`_1 < n:num`))) (disch_tac [])) THEN case) THEN (done_tac)); ];; (* Lemma index_drop_le *) let index_drop_le = Sections.section_proof ["s";"n";"x"] `n <= indexl x s ==> indexl x (dropl n s) = indexl x 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 ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((THENL) case [ALL_TAC; (move ["n"])])) THEN ((((use_arg_then2 ("drop", [drop]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_nil", [index_nil]))(thm_tac (new_rewrite [] [])))))) THEN (TRY ((arith_tac)))); (repeat_tactic 1 9 (((use_arg_then2 ("index_cons", [index_cons]))(thm_tac (new_rewrite [] []))))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`x = h`))) (disch_eq_tac "x_eq_h" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) ((arith_tac) THEN (done_tac))); ((((((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subSS", [subSS]))(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("Ih", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma index_drop_uniq *) let index_drop_uniq = Sections.section_proof ["s";"n";"x"] `uniq s ==> indexl x (dropl n s) = if n <= indexl x s then (indexl x s - n) else (sizel s - n)` [ (BETA_TAC THEN (move ["uniq_s"])); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`n < sizel s`))) (disch_eq_tac "n_lt" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); ((((use_arg_then2 ("drop_oversize", [drop_oversize]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqNgt", [leqNgt]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("index_nil", [index_nil]))(thm_tac (new_rewrite [] []))))); ((((use_arg_then2 ("n_lt", [])) (disch_tac [])) THEN (clear_assumption "n_lt") THEN ((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("index_size", [index_size])) (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 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`n:num <= _`))) (disch_eq_tac "n_le" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) ((((use_arg_then2 ("index_drop_le", [index_drop_le]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("size_drop", [size_drop]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_eq_size", [index_eq_size]))(gsym_then (thm_tac (new_rewrite [] [])))))); (((use_arg_then2 ("uniq_s", [])) (disch_tac [])) THEN (clear_assumption "uniq_s") THEN ((use_arg_then2 ("contraL", [contraL])) (disch_tac [])) THEN (clear_assumption "contraL") THEN (DISCH_THEN apply_tac) THEN (move ["mem_drop"])); ((((fun arg_tac -> (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))) (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 (((fun arg_tac -> (use_arg_then2 ("mem_imp_not_uniq_cat", [mem_imp_not_uniq_cat])) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("mem_drop", [mem_drop]))(thm_tac (new_rewrite [] []))))); ((((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_take", [index_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] []))))); ((in_tac ["n_le"] false (((use_arg_then2 ("NOT_LE", [NOT_LE]))(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("n_le", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("n_lt", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Finalization of the section MoreIndex *) let index_nil = Sections.finalize_theorem index_nil;; let index_cons = Sections.finalize_theorem index_cons;; let index_eq_size = Sections.finalize_theorem index_eq_size;; let index_head = Sections.finalize_theorem index_head;; let index_take = Sections.finalize_theorem index_take;; let index_drop_le = Sections.finalize_theorem index_drop_le;; let index_drop_uniq = Sections.finalize_theorem index_drop_uniq;; Sections.end_section "MoreIndex";; (* Section MorePermEq *) Sections.begin_section "MorePermEq";; (* Lemma perm_eq_cat *) let perm_eq_cat = Sections.section_proof ["s1";"t1";"s2";"t2"] `perm_eq s1 s2 /\ perm_eq t1 t2 ==> perm_eq (s1 ++ t1) (s2 ++ t2)` [ ((((repeat_tactic 1 9 (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("count_cat", [count_cat]))(thm_tac (new_rewrite [] [])))))) THEN ALL_TAC THEN (case THEN ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) THEN (done_tac)); ];; (* Lemma perm_eq0r *) let perm_eq0r = Sections.section_proof ["s"] `perm_eq s [] <=> s = []` [ (((THENL) (split_tac) [(DISCH_THEN (fun snd_th -> (use_arg_then2 ("perm_eq_size", [perm_eq_size])) (thm_tac (match_mp_then snd_th MP_TAC)))); (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_eq0", [size_eq0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq0l *) let perm_eq0l = Sections.section_proof ["s"] `perm_eq [] s <=> s = []` [ (((((use_arg_then2 ("perm_eq_sym", [perm_eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_eq0r", [perm_eq0r]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_pred1P *) let perm_eq_pred1P = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 <=> (!x. count (pred1 x) s1 = count (pred1 x) s2)` [ ((THENL_FIRST) ((THENL) (split_tac) [ALL_TAC; (move ["count_eq"])]) (((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) 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 ["_"])) THEN (done_tac)); ];; (* Lemma perm_eq_filter *) let perm_eq_filter = Sections.section_proof ["a";"s1";"s2"] `perm_eq s1 s2 ==> perm_eq (filter a s1) (filter a s2)` [ ((((repeat_tactic 1 9 (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("count_filterI", [count_filterI]))(thm_tac (new_rewrite [] [])))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_undup *) let perm_eq_undup = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> perm_eq (undup s1) (undup s2)` [ ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (move ["h_mem"])); ((((use_arg_then2 ("perm_eq_pred1P", [perm_eq_pred1P]))(thm_tac (new_rewrite [] [])))) THEN (move ["x"])); (((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 ("undup_uniq", [undup_uniq]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("mem_undup", [mem_undup]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("h_mem", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_map *) let perm_eq_map = Sections.section_proof ["f";"s1";"s2"] `perm_eq s1 s2 ==> perm_eq (map f s1) (map f s2)` [ ((((repeat_tactic 1 9 (((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("count_map", [count_map]))(thm_tac (new_rewrite [] [])))))) THEN (move ["eq"]) THEN (move ["P"])) THEN (done_tac)); ];; (* Lemma uniq_perm_eq_alt *) let uniq_perm_eq_alt = Sections.section_proof ["s1";"s2"] `uniq s1 /\ sizel s1 = sizel s2 /\ (!x. x <- s1 <=> x <- s2) ==> perm_eq s1 s2` [ (BETA_TAC THEN (case THEN (move ["uniq1"])) THEN (case THEN (move ["size_eq"])) THEN (move ["mem"])); (((use_arg_then2 ("uniq_perm_eq", [uniq_perm_eq])) (thm_tac apply_tac)) THEN (repeat_tactic 1 9 (((split_tac) THEN ((TRY done_tac)))))); ((((fun arg_tac -> (use_arg_then2 ("perm_uniq", [perm_uniq])) (fun fst_arg -> (use_arg_then2 ("mem", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma all_perm_eq *) let all_perm_eq = Sections.section_proof ["a";"s1";"s2"] `perm_eq s1 s2 ==> (all a s1 <=> all a s2)` [ ((BETA_TAC THEN (move ["perm"])) THEN (((use_arg_then2 ("perm", [])) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["eq"]))); (((repeat_tactic 1 9 (((use_arg_then2 ("all_count", [all_count]))(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("perm_eq_size", [perm_eq_size])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Finalization of the section MorePermEq *) let perm_eq_cat = Sections.finalize_theorem perm_eq_cat;; let perm_eq0r = Sections.finalize_theorem perm_eq0r;; let perm_eq0l = Sections.finalize_theorem perm_eq0l;; let perm_eq_pred1P = Sections.finalize_theorem perm_eq_pred1P;; let perm_eq_filter = Sections.finalize_theorem perm_eq_filter;; let perm_eq_undup = Sections.finalize_theorem perm_eq_undup;; let perm_eq_map = Sections.finalize_theorem perm_eq_map;; let uniq_perm_eq_alt = Sections.finalize_theorem uniq_perm_eq_alt;; let all_perm_eq = Sections.finalize_theorem all_perm_eq;; Sections.end_section "MorePermEq";; (* Section MoreSubseq *) Sections.begin_section "MoreSubseq";; (* Lemma all_subseq *) let all_subseq = Sections.section_proof ["s1";"s2";"P"] `subseq s1 s2 /\ all P s2 ==> all P s1` [ (((((use_arg_then2 ("all_filterP", [all_filterP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN ((move ["sub"]) THEN (move ["eq"])))) THEN (((use_arg_then2 ("sub", [])) (disch_tac [])) THEN (clear_assumption "sub") THEN BETA_TAC)); ((((((use_arg_then2 ("eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("subseq_filter", [subseq_filter]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma subseq_tl *) let subseq_tl = Sections.section_proof ["h";"t";"s"] `subseq (h :: t) s ==> subseq t s` [ ((BETA_TAC THEN (move ["h"])) THEN ((use_arg_then2 ("subseq_trans", [subseq_trans])) (thm_tac apply_tac)) THEN ((fun arg_tac -> arg_tac (Arg_term (`h :: t`))) (term_tac exists_tac)) THEN (((use_arg_then2 ("subseq_cons", [subseq_cons]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Finalization of the section MoreSubseq *) let all_subseq = Sections.finalize_theorem all_subseq;; let subseq_tl = Sections.finalize_theorem subseq_tl;; Sections.end_section "MoreSubseq";; (* Section Delete *) Sections.begin_section "Delete";; (Sections.add_section_type (mk_var ("x", (`:A`))));; (Sections.add_section_type (mk_var ("s", (`:(A)list`))); Sections.add_section_type (mk_var ("s1", (`:(A)list`))); Sections.add_section_type (mk_var ("s2", (`:(A)list`))));; (Sections.add_section_var (mk_var ("x0", (`:A`))));; (* Lemma delete1_eq_at *) let delete1_eq_at = Sections.section_proof ["x";"s"] `delete1 x s = delete_at (indexl x s) s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("delete1", [delete1]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("delete_at", [delete_at]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("index_cons", [index_cons]))(thm_tac (new_rewrite [] [])))))); ((((fun arg_tac -> arg_tac (Arg_term (`x = h`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) THEN ((((use_arg_then2 ("delete_at", [delete_at]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma delete1_hd *) let delete1_hd = Sections.section_proof ["h";"t"] `delete1 h (h :: t) = t` [ ((((use_arg_then2 ("delete1", [delete1]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma count_delete_at *) let count_delete_at = Sections.section_proof ["i";"s";"P"] `i < sizel s ==> count P (delete_at i s) = count P s - if P (nth x0 s i) then 1 else 0` [ ((((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 ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((THENL) case [ALL_TAC; (move ["i"])])) THEN ((((use_arg_then2 ("delete_at", [delete_at]))(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 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (TRY ((arith_tac)))); (((((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (move ["i_lt"])); ((((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((fun arg_tac -> arg_tac (Arg_term (`if P h then 1 else 0`))) (term_tac (set_tac "n"))); ((fun arg_tac -> arg_tac (Arg_term (`if _1 then _2 else _3`))) (term_tac (set_tac "k"))); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`count P t = 0`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`k = 0 \/ k = 1`))) (term_tac (have_gen_tac []ALL_TAC))) ((((use_arg_then2 ("k_def", [])) (disch_tac [])) THEN (clear_assumption "k_def") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`k = 0`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))))) ((repeat_tactic 1 9 (((use_arg_then2 ("subn0", [subn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((((use_arg_then2 ("k_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((THENL_FIRST) (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`~P (nth x0 t i)`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))))) ((ALL_TAC) THEN (done_tac)))); ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN BETA_TAC) THEN ((((use_arg_then2 ("count0", [count0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("all_predC", [all_predC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("hasPn", [hasPn]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (DISCH_THEN apply_tac) THEN (((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma count_delete1 *) let count_delete1 = Sections.section_proof ["x";"s";"P"] `x <- s ==> count P (delete1 x s) = count P s - if P x then 1 else 0` [ ((BETA_TAC THEN (move ["mem_x"])) THEN ((((use_arg_then2 ("delete1_eq_at", [delete1_eq_at]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_delete_at", [count_delete_at]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma delete_at_eq *) let delete_at_eq = Sections.section_proof ["i";"s"] `delete_at i s = s <=> sizel s <= i` [ ((THENL_ROT (-1)) ((((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 ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((THENL) case [ALL_TAC; (move ["i"])])) THEN ((((use_arg_then2 ("delete_at", [delete_at]))(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 ((arith_tac))))); (((((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IH", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("eqseq_cons", [eqseq_cons]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((((fun arg_tac -> arg_tac (Arg_theorem (ARITH_RULE `!n. ~(SUC n <= 0)`)))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (((fun arg_tac -> arg_tac (Arg_theorem (ARITH_RULE `(!n. n = n:num)`))) (disch_tac [])) THEN BETA_TAC THEN ((fun arg_tac -> (conv_thm_tac DISCH_THEN) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel t`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac MP_TAC))); ((((use_arg_then2 ("contraL", [contraL])) (disch_tac [])) THEN (clear_assumption "contraL") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [1] []))))) THEN ((((use_arg_then2 ("size", [size]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("LENGTH", [LENGTH]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma delete_at_eq_imp *) let delete_at_eq_imp = Sections.section_proof ["i";"s"] `~(i < sizel s) ==> delete_at i s = s` [ (((((use_arg_then2 ("leqNgt", [leqNgt]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("delete_at_eq", [delete_at_eq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma not_mem_delete1 *) let not_mem_delete1 = Sections.section_proof ["x";"s"] `~(x <- s) ==> delete1 x s = s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN (((((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("delete1", [delete1]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("negb_or", [negb_or]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IH", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) THEN (done_tac)); ];; (* Lemma size_delete_at *) let size_delete_at = Sections.section_proof ["i";"s"] `sizel (delete_at i s) = sizel s - if i < sizel s then 1 else 0` [ ((THENL_LAST) (((fun arg_tac -> arg_tac (Arg_term (`i < sizel s`))) (disch_eq_tac "lt" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) (((((use_arg_then2 ("delete_at_eq_imp", [delete_at_eq_imp]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("subn0", [subn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((repeat_tactic 1 9 (((use_arg_then2 ("count_predT", [count_predT]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("count_delete_at", [count_delete_at]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("predT", [predT]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma size_delete1 *) let size_delete1 = Sections.section_proof ["x";"s"] `sizel (delete1 x s) = sizel s - if x <- s then 1 else 0` [ (((((use_arg_then2 ("delete1_eq_at", [delete1_eq_at]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_delete_at", [size_delete_at]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma subseq_delete_at *) let subseq_delete_at = Sections.section_proof ["i";"s"] `subseq (delete_at i s) s` [ ((((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 ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((THENL) case [ALL_TAC; (move ["i"])])) THEN ((((use_arg_then2 ("delete_at", [delete_at]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("subseq0", [subseq0]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("subseq_cons", [subseq_cons]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("cat1s", [cat1s]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("cat1s", [cat1s])) (fun fst_arg -> (use_arg_then2 ("h", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("t", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("subseq_cat", [subseq_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subseq_refl", [subseq_refl]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma subseq_delete1 *) let subseq_delete1 = Sections.section_proof ["x";"s"] `subseq (delete1 x s) s` [ (((((use_arg_then2 ("delete1_eq_at", [delete1_eq_at]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subseq_delete_at", [subseq_delete_at]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma mem_delete_at *) let mem_delete_at = Sections.section_proof ["i";"s";"y"] `y <- delete_at i s ==> y <- s` [ (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("mem_subseq", [mem_subseq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (DISCH_THEN apply_tac) THEN (((use_arg_then2 ("subseq_delete_at", [subseq_delete_at])) (disch_tac [])) THEN (clear_assumption "subseq_delete_at") THEN (exact_tac)) THEN (done_tac)); ];; (* Lemma mem_delete1 *) let mem_delete1 = Sections.section_proof ["x";"y";"s"] `y <- delete1 x s ==> y <- s` [ (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("mem_subseq", [mem_subseq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (DISCH_THEN apply_tac) THEN (((use_arg_then2 ("subseq_delete1", [subseq_delete1])) (disch_tac [])) THEN (clear_assumption "subseq_delete1") THEN (exact_tac)) THEN (done_tac)); ];; (* Lemma perm_eq_delete_at *) let perm_eq_delete_at = Sections.section_proof ["i";"s1";"s2"] `i < sizel s1 /\ perm_eq s1 s2 ==> perm_eq (delete_at i s1) (delete_at (indexl (nth x0 s1 i) s2) s2)` [ ((BETA_TAC THEN (case THEN ((move ["i_lt"]) THEN (move ["p_eq"])))) THEN ((fun arg_tac -> arg_tac (Arg_term (`nth x0 s1 i`))) (term_tac (set_tac "x")))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`x <- s2`))) (term_tac (have_gen_tac [](move ["x_s2"])))) (((((fun arg_tac -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (fun fst_arg -> (use_arg_then2 ("p_eq", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("x_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["P"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("count_delete_at", [count_delete_at]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); ((((use_arg_then2 ("p_eq", [])) (disch_tac [])) THEN (clear_assumption "p_eq") THEN BETA_TAC) THEN ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("x_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_delete_at_1 *) let perm_eq_delete_at_1 = Sections.section_proof ["i";"s1";"s2"] `i < sizel s1 /\ perm_eq s1 s2 ==> perm_eq (delete_at i s1) (delete1 (nth x0 s1 i) s2)` [ ((((use_arg_then2 ("delete1_eq_at", [delete1_eq_at]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_eq_delete_at", [perm_eq_delete_at])) (disch_tac [])) THEN (clear_assumption "perm_eq_delete_at") THEN (exact_tac)) THEN (done_tac)); ];; (* Lemma perm_eq_delete1 *) let perm_eq_delete1 = Sections.section_proof ["x";"s1";"s2"] `perm_eq s1 s2 ==> perm_eq (delete1 x s1) (delete1 x s2)` [ ((THENL_ROT (-1)) ((BETA_TAC THEN (move ["p_eq"])) THEN (((fun arg_tac -> arg_tac (Arg_term (`x <- s1`))) (disch_eq_tac "mem" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)))); (((repeat_tactic 1 9 (((use_arg_then2 ("not_mem_delete1", [not_mem_delete1]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (fun fst_arg -> (use_arg_then2 ("p_eq", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); (((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["P"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("count_delete1", [count_delete1]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((fun arg_tac -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (fun fst_arg -> (use_arg_then2 ("p_eq", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((TRY done_tac)))); ((((use_arg_then2 ("p_eq", [])) (disch_tac [])) THEN (clear_assumption "p_eq") THEN BETA_TAC) THEN ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_cons_delete_at *) let perm_eq_cons_delete_at = Sections.section_proof ["i";"s"] `i < sizel s ==> perm_eq (nth x0 s i :: delete_at i s) s` [ ((BETA_TAC THEN (move ["i_lt"])) THEN ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["P"])) THEN ((((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_delete_at", [count_delete_at]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); ((THENL_LAST) (((fun arg_tac -> arg_tac (Arg_term (`P _`))) (disch_eq_tac "Px" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) (((((use_arg_then2 ("subn0", [subn0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((THENL_FIRST) (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`0 < count P s`))) (term_tac (have_gen_tac []ALL_TAC)))) ((arith_tac) 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 ((fun arg_tac -> arg_tac (Arg_term (`nth x0 s i`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("Px", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbT", [andbT]))(thm_tac (new_rewrite [] [])))))); (((((use_arg_then2 ("EL_nth", [EL_nth]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("MEM_EL", [MEM_EL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma perm_eq_cons_delete1 *) let perm_eq_cons_delete1 = Sections.section_proof ["x";"s"] `x <- s ==> perm_eq (x :: delete1 x s) s` [ ((use_arg_then2 ("perm_eq_cons_delete_at", [perm_eq_cons_delete_at])) (fun arg -> thm_tac MP_TAC arg THEN (move ["th"]))); ((BETA_TAC THEN (move ["xs"])) THEN ((((use_arg_then2 ("delete1_eq_at", [delete1_eq_at]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("nth_index", [nth_index])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (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 ("s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("th", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma nth_delete_at *) let nth_delete_at = Sections.section_proof ["i";"s";"k"] `nth x0 (delete_at k s) i = nth x0 s (if i < k then i else SUC i)` [ ((((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN ((use_arg_then2 ("k", [])) (disch_tac [])) THEN (clear_assumption "k") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IHs"]))]) THEN ((THENL) case [ALL_TAC; (move ["k"])]) THEN (move ["i"])) THEN ((((use_arg_then2 ("delete_at", [delete_at]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN case) [ALL_TAC; (move ["i"])]) THEN ((((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("fun_if", [fun_if]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IHs", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma nth_delete1 *) let nth_delete1 = Sections.section_proof ["x0";"x";"s";"i"] `nth x0 (delete1 x s) i = nth x0 s (if i < indexl x s then i else SUC i)` [ (((((use_arg_then2 ("delete1_eq_at", [delete1_eq_at]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_delete_at", [nth_delete_at]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma EL_delete_at *) let EL_delete_at = Sections.section_proof ["i";"k";"s"] `i < sizel (delete_at k s) ==> EL i (delete_at k s) = EL (if i < k then i else SUC i) s` [ (((use_arg_then2 ("size_delete_at", [size_delete_at]))(thm_tac (new_rewrite [] [])))); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`k < sizel s`))) (disch_eq_tac "k_lt" [])) THEN case THEN (simp_tac) THEN (move ["i_lt"]) THEN (process_fst_eq_tac))); (((((use_arg_then2 ("delete_at_eq_imp", [delete_at_eq_imp]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((use_arg_then2 ("perm_eq_cons_delete_at", [perm_eq_cons_delete_at])) (fun arg -> thm_tac MP_TAC arg THEN (move ["th"]))); ((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_delete_at", [size_delete_at]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("k_lt", []))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))); (((((use_arg_then2 ("nth_delete_at", [nth_delete_at]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("EL_nth", [EL_nth]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma uniq_delete_at *) let uniq_delete_at = Sections.section_proof ["i";"s"] `uniq s ==> uniq (delete_at i s)` [ (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("subseq_uniq", [subseq_uniq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (DISCH_THEN apply_tac) THEN ((use_arg_then2 ("subseq_delete_at", [subseq_delete_at])) (thm_tac apply_tac)) THEN (done_tac)); ];; (* Lemma uniq_delete1 *) let uniq_delete1 = Sections.section_proof ["x";"s"] `uniq s ==> uniq (delete1 x s)` [ (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("subseq_uniq", [subseq_uniq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (DISCH_THEN apply_tac) THEN ((use_arg_then2 ("subseq_delete1", [subseq_delete1])) (thm_tac apply_tac)) THEN (done_tac)); ];; (* Lemma mem_delete1_uniq *) let mem_delete1_uniq = Sections.section_proof ["x";"s"] `uniq s /\ x <- s ==> (!y. y <- delete1 x s <=> ~(y = x) /\ y <- s)` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN (((((use_arg_then2 ("delete1", [delete1]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (((fun arg_tac -> arg_tac (Arg_theorem (GEN_ALL uniq)))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN ALL_TAC) THEN (case THEN ((move ["h_mem"]) THEN (move ["uniq_t"]))))); (((fun arg_tac -> arg_tac (Arg_term (`x = h`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); ((BETA_TAC THEN (move ["y"])) THEN ((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (split_tac)); ((BETA_TAC THEN (move ["y_mem"])) THEN ((((use_arg_then2 ("y_mem", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (((use_arg_then2 ("h_mem", [])) (disch_tac [])) THEN (clear_assumption "h_mem") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); (((((use_arg_then2 ("andb_orr", [andb_orr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andNb", [andNb]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("orFb", [orFb]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (done_tac)); ((BETA_TAC THEN (move ["x_mem"]) THEN (move ["y"])) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] []))))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`y = h`))) (disch_eq_tac "eq2" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac))); ((((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Finalization of the section Delete *) let delete1_eq_at = Sections.finalize_theorem delete1_eq_at;; let delete1_hd = Sections.finalize_theorem delete1_hd;; let count_delete_at = Sections.finalize_theorem count_delete_at;; let count_delete1 = Sections.finalize_theorem count_delete1;; let delete_at_eq = Sections.finalize_theorem delete_at_eq;; let delete_at_eq_imp = Sections.finalize_theorem delete_at_eq_imp;; let not_mem_delete1 = Sections.finalize_theorem not_mem_delete1;; let size_delete_at = Sections.finalize_theorem size_delete_at;; let size_delete1 = Sections.finalize_theorem size_delete1;; let subseq_delete_at = Sections.finalize_theorem subseq_delete_at;; let subseq_delete1 = Sections.finalize_theorem subseq_delete1;; let mem_delete_at = Sections.finalize_theorem mem_delete_at;; let mem_delete1 = Sections.finalize_theorem mem_delete1;; let perm_eq_delete_at = Sections.finalize_theorem perm_eq_delete_at;; let perm_eq_delete_at_1 = Sections.finalize_theorem perm_eq_delete_at_1;; let perm_eq_delete1 = Sections.finalize_theorem perm_eq_delete1;; let perm_eq_cons_delete_at = Sections.finalize_theorem perm_eq_cons_delete_at;; let perm_eq_cons_delete1 = Sections.finalize_theorem perm_eq_cons_delete1;; let nth_delete_at = Sections.finalize_theorem nth_delete_at;; let nth_delete1 = Sections.finalize_theorem nth_delete1;; let EL_delete_at = Sections.finalize_theorem EL_delete_at;; let uniq_delete_at = Sections.finalize_theorem uniq_delete_at;; let uniq_delete1 = Sections.finalize_theorem uniq_delete1;; let mem_delete1_uniq = Sections.finalize_theorem mem_delete1_uniq;; Sections.end_section "Delete";; (* Section ListsAndSets *) Sections.begin_section "ListsAndSets";; (* Lemma list_of_empty_set *) let list_of_empty_set = Sections.section_proof [] `list_of_set {} = []` [ (((((use_arg_then2 ("LENGTH_EQ_NIL", [LENGTH_EQ_NIL]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("LENGTH_LIST_OF_SET", [LENGTH_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("CARD_CLAUSES", [CARD_CLAUSES]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("FINITE_EMPTY", [FINITE_EMPTY]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma set_of_list_subseq *) let set_of_list_subseq = Sections.section_proof ["s1";"s2"] `subseq s1 s2 ==> set_of_list s1 SUBSET set_of_list s2` [ (((((use_arg_then2 ("SUBSET", [SUBSET]))(thm_tac (new_rewrite [] [])))) THEN (move ["s12"]) THEN (move ["x"])) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (move ["mem"])) THEN (((fun arg_tac -> (use_arg_then2 ("mem_subseq", [mem_subseq])) (fun fst_arg -> (use_arg_then2 ("s12", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (exact_tac)) THEN (done_tac)); ];; (* Lemma set_of_list_filter *) let set_of_list_filter = Sections.section_proof ["P";"s"] `set_of_list (filter P s) = {x | MEM x s /\ P x}` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((((use_arg_then2 ("filter", [filter]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))))); (((((use_arg_then2 ("set_of_list", [set_of_list]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("EMPTY_GSPEC", [EMPTY_GSPEC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((fun arg_tac -> arg_tac (Arg_term (`P h`))) (disch_eq_tac "c" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((fun arg_tac -> arg_tac (Arg_theorem (GEN_ALL set_of_list)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("c", [])) (disch_tac [])) THEN (clear_assumption "c") THEN BETA_TAC) THEN (SET_TAC[]) THEN (done_tac)); ((((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("c", [])) (disch_tac [])) THEN (clear_assumption "c") THEN BETA_TAC) THEN (SET_TAC[]) THEN (done_tac)); ];; (* Lemma set_of_list_undup *) let set_of_list_undup = Sections.section_proof ["s"] `set_of_list (undup s) = set_of_list s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((((use_arg_then2 ("undup", [undup]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); ((((fun arg_tac -> arg_tac (Arg_term (`MEM h t`))) (disch_eq_tac "mem_h" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) THEN ((repeat_tactic 1 9 (((fun arg_tac -> arg_tac (Arg_theorem (GEN_ALL set_of_list)))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ABSORPTION", [ABSORPTION]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma set_of_list_flatten *) let set_of_list_flatten = Sections.section_proof ["s"] `set_of_list (flatten s) = UNIONS {set_of_list l | MEM l s}` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((((use_arg_then2 ("flatten", [flatten]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("foldr", [foldr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))))); ((((use_arg_then2 ("set_of_list", [set_of_list]))(thm_tac (new_rewrite [] [])))) THEN (SET_TAC[]) THEN (done_tac)); (((((use_arg_then2 ("flatten", [flatten]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("APPEND_cat", [APPEND_cat]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("SET_OF_LIST_APPEND", [SET_OF_LIST_APPEND]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] []))))) THEN (SET_TAC[]) THEN (done_tac)); ];; (* Lemma uniq_list_of_set *) let uniq_list_of_set = Sections.section_proof ["s"] `FINITE s ==> uniq (list_of_set s)` [ ((BETA_TAC THEN (move ["fin_s"])) THEN (((use_arg_then2 ("count_mem_uniq", [count_mem_uniq])) (thm_tac apply_tac)) THEN (move ["x"]))); ((((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`x IN s`))) (disch_eq_tac "xs" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); ((((((use_arg_then2 ("count0", [count0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("allP", [allP]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (move ["y"])) THEN (((((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["ys"]))); ((((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`list_of_set s`))) (term_tac (set_tac "l"))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`x <- l`))) (term_tac (have_gen_tac [](move ["xl"])))) (((((use_arg_then2 ("l_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`0 < sizel l`))) (term_tac (have_gen_tac [](move ["l_gt0"])))) ((((use_arg_then2 ("xl", [])) (disch_tac [])) THEN (clear_assumption "xl") THEN BETA_TAC) THEN ((((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_find", [has_find]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac))); (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`count (predC (pred1 x)) l = sizel l - 1`))) (term_tac (have_gen_tac []ALL_TAC)))); ((((fun arg_tac -> (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))) (fun fst_arg -> (use_arg_then2 ("l", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN ((use_arg_then2 ("xl", [])) (disch_tac [])) THEN (clear_assumption "xl") THEN BETA_TAC) THEN ((((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("count_filter", [count_filter]))(thm_tac (new_rewrite [] [])))) THEN ((fun arg_tac -> arg_tac (Arg_term (`filter _1 l`))) (term_tac (set_tac "l2")))); ((((use_arg_then2 ("anti_leq", [anti_leq])) (disch_tac [])) THEN (clear_assumption "anti_leq") THEN (DISCH_THEN apply_tac)) THEN (split_tac)); ((((use_arg_then2 ("l2_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((THENL) (((use_arg_then2 ("xl", [])) (disch_tac [])) THEN (clear_assumption "xl") THEN ((use_arg_then2 ("l", [])) (disch_tac [])) THEN (clear_assumption "l") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("filter", [filter]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("predC", [predC]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("pred1", [pred1]))(gsym_then (thm_tac (new_rewrite [] []))))))); ((THENL) case [((((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)); (move ["mem_x"])]); ((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("count_filter", [count_filter]))(gsym_then (thm_tac (new_rewrite [] [])))))); ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("count_size", [count_size])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`predC (pred1 x)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("t", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`0 < sizel t`))) (term_tac (have_gen_tac []ALL_TAC))) ((((use_arg_then2 ("mem_x", [])) (disch_tac [])) THEN (clear_assumption "mem_x") THEN BETA_TAC) THEN ((((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_find", [has_find]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac))); ((((fun arg_tac -> arg_tac (Arg_term (`h = x`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("IH", [])) (fun fst_arg -> (use_arg_then2 ("mem_x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((((fun arg_tac -> (use_arg_then2 ("LENGTH_LIST_OF_SET", [LENGTH_LIST_OF_SET])) (fun fst_arg -> (use_arg_then2 ("fin_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (((((use_arg_then2 ("l_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (move ["size_eq"]))); ((((use_arg_then2 ("leq_trans", [leq_trans])) (disch_tac [])) THEN (clear_assumption "leq_trans") THEN (DISCH_THEN apply_tac)) THEN ((fun arg_tac -> arg_tac (Arg_term (`CARD (set_of_list l DELETE x)`))) (term_tac exists_tac))); ((((use_arg_then2 ("CARD_DELETE", [CARD_DELETE]))(thm_tac (new_rewrite [1] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_SET_OF_LIST", [FINITE_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("xl", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); ((((use_arg_then2 ("l_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("SET_OF_LIST_OF_SET", [SET_OF_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("l_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] []))))); (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`set_of_list l2 = s DELETE x`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(gsym_then (thm_tac (new_rewrite [] []))))))))); (((((use_arg_then2 ("size", [size]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("CARD_SET_OF_LIST_LE", [CARD_SET_OF_LIST_LE]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((((use_arg_then2 ("EXTENSION", [EXTENSION]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_DELETE", [IN_DELETE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (move ["y"])); (((((use_arg_then2 ("l2_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_filter", [mem_filter]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("l_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("predC", [predC]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("andbC", [andbC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_list_of_set *) let perm_eq_list_of_set = Sections.section_proof ["l";"s"] `FINITE s ==> (perm_eq l (list_of_set s) <=> sizel l = CARD s /\ (!x. x <- l <=> x IN s))` [ ((BETA_TAC THEN (move ["fin_s"])) THEN ((THENL) (split_tac) [(move ["p_eq"]); (case THEN ((move ["size_eq"]) THEN (move ["mem_eq"])))])); (((((fun arg_tac -> (use_arg_then2 ("perm_eq_size", [perm_eq_size])) (fun fst_arg -> (use_arg_then2 ("p_eq", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("LENGTH_LIST_OF_SET", [LENGTH_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN ((simp_tac THEN TRY done_tac))) THEN (move ["y"])); (((((fun arg_tac -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (fun fst_arg -> (use_arg_then2 ("p_eq", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((THENL_LAST) ((((use_arg_then2 ("uniq_perm_eq", [uniq_perm_eq]))(thm_tac (new_rewrite [] [])))) THEN ((THENL) (split_tac) [ALL_TAC; (move ["y"])])) ((((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("uniq_list_of_set", [uniq_list_of_set]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("andbT", [andbT]))(thm_tac (new_rewrite [] []))))); (((((fun arg_tac -> (use_arg_then2 ("uniq_size_uniq", [uniq_size_uniq])) (fun fst_arg -> (fun arg_tac -> (use_arg_then2 ("uniq_list_of_set", [uniq_list_of_set])) (fun fst_arg -> (use_arg_then2 ("fin_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size", [size]))(thm_tac (new_rewrite [2] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("LENGTH_LIST_OF_SET", [LENGTH_LIST_OF_SET]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (move ["y"])); ((((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma perm_eq_set_of_list *) let perm_eq_set_of_list = Sections.section_proof ["l";"s"] `FINITE s /\ perm_eq l (list_of_set s) ==> set_of_list l = s` [ (BETA_TAC THEN (case THEN (move ["fin_s"])) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (move ["mem"])); ((((((use_arg_then2 ("EXTENSION", [EXTENSION]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem", []))(thm_tac (new_rewrite [] []))))) THEN (move ["x"])) THEN (((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma card_set_of_list_uniq *) let card_set_of_list_uniq = Sections.section_proof ["l"] `uniq l ==> CARD (set_of_list l) = sizel l` [ ((BETA_TAC THEN (move ["uniq_l"])) THEN (((use_arg_then2 ("anti_leq", [anti_leq])) (disch_tac [])) THEN (clear_assumption "anti_leq") THEN (DISCH_THEN apply_tac)) THEN ((((use_arg_then2 ("size", [size]))(thm_tac (new_rewrite [1] [])))) THEN (((use_arg_then2 ("CARD_SET_OF_LIST_LE", [CARD_SET_OF_LIST_LE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] [])))))); (((((use_arg_then2 ("LENGTH_LIST_OF_SET", [LENGTH_LIST_OF_SET]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_SET_OF_LIST", [FINITE_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("uniq_leq_size", [uniq_leq_size]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("uniq_l", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] []))))) THEN (move ["x"]) THEN (move ["mem_x"])); (((((use_arg_then2 ("MEM_LIST_OF_SET", [MEM_LIST_OF_SET]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_SET_OF_LIST", [FINITE_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma BIJ_from_lists *) let BIJ_from_lists = Sections.section_proof ["s1";"s2"] `uniq s1 /\ uniq s2 /\ sizel s1 = sizel s2 ==> BIJ (\x. EL (indexl x s1) s2) (set_of_list s1) (set_of_list s2)` [ (BETA_TAC THEN (case THEN (move ["uniq_s1"])) THEN (case THEN (move ["uniq_s2"])) THEN (move ["size_eq"])); (((((use_arg_then2 ("BIJ", [BIJ]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("INJ", [INJ]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("SURJ", [SURJ]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (repeat_tactic 1 9 (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] [])))))) THEN (split_tac)); ((THENL) (split_tac) [((move ["x"]) THEN (move ["mem_x"])); ((move ["x"]) THEN (move ["y"]) THEN (case THEN (move ["xs1"])) THEN (case THEN (move ["ys2"])))]); (((((use_arg_then2 ("MEM_EL", [MEM_EL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((repeat_tactic 1 9 (((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))); (((((use_arg_then2 ("nth_uniq", [nth_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("uniq_index_inj", [uniq_index_inj]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((THENL_FIRST) ((split_tac) THEN (move ["x"]) THEN (move ["mem_x"])) (((((use_arg_then2 ("MEM_EL", [MEM_EL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((fun arg_tac -> arg_tac (Arg_term (`nth ((@)UNIV) s1 (indexl x s2)`))) (term_tac exists_tac)); ((((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_eq", []))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("index_uniq", [index_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_eq", []))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("EL_index", [EL_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma set_of_list_iota *) let set_of_list_iota = Sections.section_proof ["m";"n"] `set_of_list (iota m n) = if n = 0 then {} else m..m + n - 1` [ (((((use_arg_then2 ("EXTENSION", [EXTENSION]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_iota", [mem_iota]))(thm_tac (new_rewrite [] []))))) THEN (move ["i"])); (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN case) [ALL_TAC; (move ["n"])]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (((fun arg_tac ->(use_arg_then2 ("NOT_IN_EMPTY", [NOT_IN_EMPTY]))(fun tmp_arg1 -> (use_arg_then2 ("IN_NUMSEG", [IN_NUMSEG]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma perm_eq_set_of_list_eq *) let perm_eq_set_of_list_eq = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> set_of_list s1 = set_of_list s2` [ ((((((use_arg_then2 ("EXTENSION", [EXTENSION]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] [])))))) THEN (move ["perm"]) THEN (move ["x"])) THEN (((fun arg_tac -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Finalization of the section ListsAndSets *) let list_of_empty_set = Sections.finalize_theorem list_of_empty_set;; let set_of_list_subseq = Sections.finalize_theorem set_of_list_subseq;; let set_of_list_filter = Sections.finalize_theorem set_of_list_filter;; let set_of_list_undup = Sections.finalize_theorem set_of_list_undup;; let set_of_list_flatten = Sections.finalize_theorem set_of_list_flatten;; let uniq_list_of_set = Sections.finalize_theorem uniq_list_of_set;; let perm_eq_list_of_set = Sections.finalize_theorem perm_eq_list_of_set;; let perm_eq_set_of_list = Sections.finalize_theorem perm_eq_set_of_list;; let card_set_of_list_uniq = Sections.finalize_theorem card_set_of_list_uniq;; let BIJ_from_lists = Sections.finalize_theorem BIJ_from_lists;; let set_of_list_iota = Sections.finalize_theorem set_of_list_iota;; let perm_eq_set_of_list_eq = Sections.finalize_theorem perm_eq_set_of_list_eq;; Sections.end_section "ListsAndSets";; (* Section ListSum *) Sections.begin_section "ListSum";; (Sections.add_section_type (mk_var ("f", (`:A->real`))));; (* Lemma list_sum_nil *) let list_sum_nil = Sections.section_proof ["f"] `list_sum [] f = &0` [ (((((use_arg_then2 ("list_sum", [list_sum]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("foldr", [foldr]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_cons *) let list_sum_cons = Sections.section_proof ["h";"t";"f"] `list_sum (h :: t) f = f h + list_sum t f` [ (((((use_arg_then2 ("list_sum", [list_sum]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("foldr", [foldr]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("list_sum", [list_sum]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma list_sum_cat *) let list_sum_cat = Sections.section_proof ["s1";"s2";"f"] `list_sum (s1 ++ s2) f = list_sum s1 f + list_sum s2 f` [ (((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("cat", [cat]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_ADD_LID", [REAL_ADD_LID]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((repeat_tactic 1 9 (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("REAL_ADD_ASSOC", [REAL_ADD_ASSOC]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_add *) let list_sum_add = Sections.section_proof ["s";"f1";"f2"] `list_sum s (\x. f1 x + f2 x) = list_sum s f1 + list_sum s f2` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_ADD_LID", [REAL_ADD_LID]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac))); ((((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma list_sum_lmul *) let list_sum_lmul = Sections.section_proof ["s";"f";"c"] `list_sum s (\x. c * f x) = c * list_sum s f` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_MUL_RZERO", [REAL_MUL_RZERO]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((repeat_tactic 1 9 (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma list_sum_rmul *) let list_sum_rmul = Sections.section_proof ["s";"f";"c"] `list_sum s (\x. f x * c) = c * list_sum s f` [ (((((use_arg_then2 ("list_sum_lmul", [list_sum_lmul]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("REAL_MUL_SYM", [REAL_MUL_SYM]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_delete1 *) let list_sum_delete1 = Sections.section_proof ["x";"s";"f"] `list_sum (delete1 x s) f = list_sum s f - if x <- s then f x else &0` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("delete1", [delete1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_SUB_RZERO", [REAL_SUB_RZERO]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`x = h`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) (((((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac))); (((repeat_tactic 1 9 (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma list_sum_perm_eq *) let list_sum_perm_eq = Sections.section_proof ["s1";"s2";"f"] `perm_eq s1 s2 ==> list_sum s1 f = list_sum s2 f` [ ((THENL_FIRST) (((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 ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN (move ["s2"])) (((((use_arg_then2 ("perm_eq0l", [perm_eq0l]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((BETA_TAC THEN (move ["p_eq"])) THEN (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))); ((THENL_ROT (-1)) (((fun arg_tac -> (use_arg_then2 ("IH", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`delete1 h s2`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("list_sum_delete1", [list_sum_delete1]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (fun fst_arg -> (use_arg_then2 ("p_eq", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`t = delete1 h (h :: t)`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))))) ((((use_arg_then2 ("perm_eq_delete1", [perm_eq_delete1]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("delete1", [delete1]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma list_sum_nseq *) let list_sum_nseq = Sections.section_proof ["x";"n";"f"] `list_sum (nseq n x) f = &n * f x` [ (((THENL) (((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN elim) [ALL_TAC; ((move ["n"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("nseq", [nseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ncons", [ncons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("iter", [iter]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_MUL_LZERO", [REAL_MUL_LZERO]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(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 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ADD1", [ADD1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("REAL_OF_NUM_ADD", [REAL_OF_NUM_ADD]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma list_sum_eq *) let list_sum_eq = Sections.section_proof ["s";"f";"g"] `(!x. x <- s ==> f x = g x) ==> list_sum s f = list_sum s g` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN (((repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] []))))) THEN (move ["eq"]))); ((THENL_FIRST) ((repeat_tactic 1 9 (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))) THEN (congr_tac (`_1 + _2:real`))) ((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (move ["x"]) THEN (move ["mem_x"])) THEN (((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma list_sum_nth_eq *) let list_sum_nth_eq = Sections.section_proof ["x1";"x2";"s1";"s2";"f";"g"] `sizel s1 = sizel s2 /\ (!i. i < sizel s1 ==> f (nth x1 s1 i) = g (nth x2 s2 i)) ==> list_sum s1 f = list_sum s2 g` [ ((((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 ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((THENL) case [ALL_TAC; ((move ["a"]) THEN (move ["b"]))])) THEN ((repeat_tactic 1 9 (((fun arg_tac ->(use_arg_then2 ("size_cons", [size_cons]))(fun tmp_arg1 -> (use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] [])))))) THEN (TRY ((arith_tac)))); (((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["size_eq"])) THEN (move ["el_eq"])) THEN (repeat_tactic 1 9 (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] [])))))); ((THENL_FIRST) (congr_tac (`_1 + _2:real`)) ((((fun arg_tac -> (use_arg_then2 ("el_eq", [])) (fun fst_arg -> (fun arg_tac -> (use_arg_then2 ("gtS0", [gtS0])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel t`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (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 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((fun arg_tac -> (use_arg_then2 ("IH", [])) (fun fst_arg -> (use_arg_then2 ("b", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (move ["i"]) THEN (move ["i_lt"])); ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("iffRL", [iffRL])) (fun fst_arg -> (fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltSS", [ltSS])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`sizel t`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("i_lt", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("el_eq", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_const *) let list_sum_const = Sections.section_proof ["s";"c"] `list_sum s (\x. c) = &(sizel s) * c` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_MUL_LZERO", [REAL_MUL_LZERO]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ADD1", [ADD1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("REAL_OF_NUM_ADD", [REAL_OF_NUM_ADD]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma list_sum_eq0 *) let list_sum_eq0 = Sections.section_proof ["s";"f"] `(!x. x <- s ==> f x = &0) ==> list_sum s f = &0` [ ((BETA_TAC THEN (move ["eq0"])) THEN ((((fun arg_tac -> (use_arg_then2 ("REAL_MUL_RZERO", [REAL_MUL_RZERO])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`&(sizel s)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("list_sum_const", [list_sum_const]))(gsym_then (thm_tac (new_rewrite [] []))))))); ((((use_arg_then2 ("list_sum_eq", [list_sum_eq])) (disch_tac [])) THEN (clear_assumption "list_sum_eq") THEN (DISCH_THEN apply_tac) THEN (move ["x"]) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("eq0", [])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN (done_tac)); ];; (* Lemma list_sum_ge0 *) let list_sum_ge0 = Sections.section_proof ["s";"f"] `(!x. x <- s ==> &0 <= f x) ==> &0 <= list_sum s f` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((fun arg_tac ->(use_arg_then2 ("list_sum_nil", [list_sum_nil]))(fun tmp_arg1 -> (use_arg_then2 ("list_sum_cons", [list_sum_cons]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_LE_REFL", [REAL_LE_REFL]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); ((THENL_LAST) (((((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (move ["f_ge0"])) THEN ((((use_arg_then2 ("REAL_LE_ADD", [REAL_LE_ADD]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("andbT", [andbT]))(thm_tac (new_rewrite [] []))))))) (((use_arg_then2 ("f_ge0", [])) (disch_tac [])) THEN (clear_assumption "f_ge0") THEN (exact_tac))); ((BETA_TAC THEN (move ["x"]) THEN (move ["mem_x"])) THEN (((use_arg_then2 ("f_ge0", [])) (disch_tac [])) THEN (clear_assumption "f_ge0") THEN (exact_tac)) THEN (done_tac)); ];; (* Lemma list_sum_nth_le2 *) let list_sum_nth_le2 = Sections.section_proof ["x1";"x2";"s";"t";"f";"g"] `sizel t = sizel s /\ (!i. i < sizel s ==> f (nth x1 s i) <= g (nth x2 t i)) ==> list_sum s f <= list_sum t g` [ ((((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 ["h1"]) THEN (move ["t1"]) THEN (move ["IH1"]))]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t2"]))])) THEN ((repeat_tactic 1 9 (((fun arg_tac ->(use_arg_then2 ("list_sum_nil", [list_sum_nil]))(fun tmp_arg1 -> (use_arg_then2 ("list_sum_cons", [list_sum_cons]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("REAL_LE_REFL", [REAL_LE_REFL]))(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 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (TRY ((arith_tac)))); ((((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN ALL_TAC THEN (case THEN (move ["size_eq"])) THEN (move ["h"])); ((((use_arg_then2 ("REAL_LE_ADD2", [REAL_LE_ADD2]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IH1", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_eq", []))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)); ((BETA_TAC THEN (move ["i"]) THEN (move ["i_lt"])) THEN (((fun arg_tac -> (use_arg_then2 ("h", [])) (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 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("i_lt", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ((((fun arg_tac -> (use_arg_then2 ("h", [])) (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 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma list_sum_undup *) let list_sum_undup = Sections.section_proof ["s";"f"] `list_sum s f = list_sum (undup s) (\x. &(count (pred1 x) s) * f x)` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("undup", [undup]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] [])))))); ((((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("REAL_OF_NUM_ADD", [REAL_OF_NUM_ADD]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("REAL_ADD_RDISTRIB", [REAL_ADD_RDISTRIB]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_add", [list_sum_add]))(thm_tac (new_rewrite [] []))))); (((fun arg_tac -> arg_tac (Arg_term (`h <- t`))) (disch_eq_tac "mem_h" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); ((((use_arg_then2 ("IH", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((congr_tac (`_1 + _2:real`)) THEN ((TRY done_tac)))); (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("list_sum_perm_eq", [list_sum_perm_eq])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`undup t`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`h :: delete1 h (undup t)`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))); (((((use_arg_then2 ("perm_eq_sym", [perm_eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_eq_cons_delete1", [perm_eq_cons_delete1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_undup", [mem_undup]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [1] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("REAL_MUL_LID", [REAL_MUL_LID]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("REAL_ADD_RID", [REAL_ADD_RID])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`f h`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN (((use_arg_then2 ("REAL_EQ_ADD_LCANCEL", [REAL_EQ_ADD_LCANCEL]))(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_eq0", [list_sum_eq0]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (move ["x"])); (((((use_arg_then2 ("mem_delete1_uniq", [mem_delete1_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("undup_uniq", [undup_uniq]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("mem_undup", [mem_undup]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (move ["h"]) THEN (simp_tac)); (((((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("h", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (((use_arg_then2 ("REAL_MUL_LZERO", [REAL_MUL_LZERO]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((repeat_tactic 1 9 (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (((use_arg_then2 ("IH", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [1] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("REAL_MUL_LID", [REAL_MUL_LID]))(thm_tac (new_rewrite [] []))))); ((repeat_tactic 1 9 (((use_arg_then2 ("REAL_ADD_ASSOC", [REAL_ADD_ASSOC]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("REAL_EQ_ADD_RCANCEL", [REAL_EQ_ADD_RCANCEL]))(thm_tac (new_rewrite [] []))))); ((fun arg_tac -> arg_tac (Arg_term (`count (pred1 h) t = 0`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))); ((((use_arg_then2 ("mem_h", [])) (disch_tac [])) THEN (clear_assumption "mem_h") THEN BETA_TAC) THEN ((((use_arg_then2 ("has_pred1", [has_pred1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("has_count", [has_count]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("REAL_MUL_LZERO", [REAL_MUL_LZERO]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("REAL_ADD_RID", [REAL_ADD_RID]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("REAL_ADD_RID", [REAL_ADD_RID])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`f h`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN (((use_arg_then2 ("REAL_EQ_ADD_LCANCEL", [REAL_EQ_ADD_LCANCEL]))(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("eq_sym", [eq_sym]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_eq0", [list_sum_eq0]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("mem_undup", [mem_undup]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("pred1", [pred1]))(thm_tac (new_rewrite [] []))))) THEN (move ["x"]) THEN (move ["mem_x"]) THEN (simp_tac)); ((THENL_FIRST) (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`~(h = x)`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))))))) (((simp_tac) THEN (((use_arg_then2 ("REAL_MUL_LZERO", [REAL_MUL_LZERO]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((((use_arg_then2 ("mem_h", [])) (disch_tac [])) THEN (clear_assumption "mem_h") THEN ((use_arg_then2 ("contra", [contra])) (disch_tac [])) THEN (clear_assumption "contra") THEN (DISCH_THEN apply_tac) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_set_of_list *) let list_sum_set_of_list = Sections.section_proof ["s";"f"] `uniq s ==> list_sum s f = sum (set_of_list s) f` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("set_of_list", [set_of_list]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("SUM_CLAUSES", [SUM_CLAUSES]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_SET_OF_LIST", [FINITE_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); ((((((use_arg_then2 ("uniq", [uniq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (DISCH_THEN (fun snd_th -> (use_arg_then2 ("IH", [])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_list_of_set *) let list_sum_list_of_set = Sections.section_proof ["s";"f"] `FINITE s ==> list_sum (list_of_set s) f = sum s f` [ ((BETA_TAC THEN (move ["fin_s"])) THEN ((((use_arg_then2 ("list_sum_set_of_list", [list_sum_set_of_list]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("uniq_list_of_set", [uniq_list_of_set]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("SET_OF_LIST_OF_SET", [SET_OF_LIST_OF_SET]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_nth *) let list_sum_nth = Sections.section_proof ["x0";"s";"f"] `list_sum s f = list_sum (iota 0 (sizel s)) (\i. f (nth x0 s i))` [ (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("list_sum_nth_eq", [list_sum_nth_eq])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (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 (DISCH_THEN apply_tac)); (((((use_arg_then2 ("size_iota", [size_iota]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["i"]) THEN (move ["i_lt"])); (((((use_arg_then2 ("nth_iota", [nth_iota]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_EL *) let list_sum_EL = Sections.section_proof ["s";"f"] `~(s = []) ==> list_sum s f = sum (0..sizel s - 1) (\i. f (EL i s))` [ ((((use_arg_then2 ("size_eq0", [size_eq0]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (move ["size_neq"])); ((((fun arg_tac -> (use_arg_then2 ("list_sum_nth", [list_sum_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`(@)UNIV`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_set_of_list", [list_sum_set_of_list]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("iota_uniq", [iota_uniq]))(thm_tac (new_rewrite [] [])))))); ((((use_arg_then2 ("set_of_list_iota", [set_of_list_iota]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_neq", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))); (((use_arg_then2 ("SUM_EQ", [SUM_EQ])) (thm_tac apply_tac)) THEN ((((use_arg_then2 ("IN_NUMSEG", [IN_NUMSEG]))(thm_tac (new_rewrite [] [])))) THEN (move ["i"]) THEN (move ["ineqs"]) THEN (simp_tac))); (((((use_arg_then2 ("EL_nth", [EL_nth]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("size_neq", [])) (disch_tac [])) THEN (clear_assumption "size_neq") THEN ((use_arg_then2 ("ineqs", [])) (disch_tac [])) THEN (clear_assumption "ineqs") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma list_sum_EL_alt *) let list_sum_EL_alt = Sections.section_proof ["s";"f"] `list_sum s f = sum (1..sizel s) (\i. f (EL (i - 1) s))` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN (((fun arg_tac ->(use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg1 -> (use_arg_then2 ("size_cons", [size_cons]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> arg_tac (Arg_theorem (GEN_ALL SUM_CLAUSES_NUMSEG)))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("ONE", [ONE]))(thm_tac (new_rewrite [1] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("ADD1", [ADD1]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("SUM_OFFSET", [SUM_OFFSET]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_EL", [list_sum_EL]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))); (((use_arg_then2 ("SUM_EQ", [SUM_EQ])) (thm_tac apply_tac)) THEN ((((use_arg_then2 ("IN_NUMSEG", [IN_NUMSEG]))(thm_tac (new_rewrite [] [])))) THEN (move ["i"]) THEN (move ["ineqs"]) THEN (simp_tac))); (((((use_arg_then2 ("ADD1", [ADD1]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sum_iota *) let list_sum_iota = Sections.section_proof ["m";"n";"g"] `list_sum (iota m n) g = if (n = 0) then &0 else sum (m..m + n - 1) g` [ ((((use_arg_then2 ("list_sum_set_of_list", [list_sum_set_of_list]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("iota_uniq", [iota_uniq]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("set_of_list_iota", [set_of_list_iota]))(thm_tac (new_rewrite [] []))))); ((((fun arg_tac -> arg_tac (Arg_term (`n = 0`))) (disch_tac [])) THEN case THEN (simp_tac)) THEN (((use_arg_then2 ("SUM_CLAUSES", [SUM_CLAUSES]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma count_eq_list_sum *) let count_eq_list_sum = Sections.section_proof ["a";"s"] `&(count a s) = list_sum s (\x. if a x then &1 else &0)` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN ((((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac ->(use_arg_then2 ("list_sum_nil", [list_sum_nil]))(fun tmp_arg1 -> (use_arg_then2 ("list_sum_cons", [list_sum_cons]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("REAL_OF_NUM_ADD", [REAL_OF_NUM_ADD]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("IH", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("fun_if", [fun_if]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma count_eq_nsum *) let count_eq_nsum = Sections.section_proof ["a";"s"] `~(s = []) ==> count a s = nsum (0..sizel s - 1) (\i. if a (EL i s) then 1 else 0)` [ (BETA_TAC THEN (move ["s_n_nil"])); (((((use_arg_then2 ("REAL_OF_NUM_EQ", [REAL_OF_NUM_EQ]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("count_eq_list_sum", [count_eq_list_sum]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_EL", [list_sum_EL]))(thm_tac (new_rewrite [] [])))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("REAL_OF_NUM_SUM", [REAL_OF_NUM_SUM]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_NUMSEG", [FINITE_NUMSEG]))(thm_tac (new_rewrite [] []))))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("fun_if", [fun_if]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma count_eq_list_sum_iota *) let count_eq_list_sum_iota = Sections.section_proof ["x0";"a";"s"] `&(count a s) = list_sum (iota 0 (sizel s)) (\i. if a (nth x0 s i) then &1 else &0)` [ ((((use_arg_then2 ("count_eq_list_sum", [count_eq_list_sum]))(thm_tac (new_rewrite [] [])))) THEN ((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("list_sum_nth_eq", [list_sum_nth_eq])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac apply_tac))); ((((((use_arg_then2 ("size_iota", [size_iota]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["i"]) THEN (move ["i_lt"])) THEN ((((use_arg_then2 ("nth_iota", [nth_iota]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Finalization of the section ListSum *) let list_sum_nil = Sections.finalize_theorem list_sum_nil;; let list_sum_cons = Sections.finalize_theorem list_sum_cons;; let list_sum_cat = Sections.finalize_theorem list_sum_cat;; let list_sum_add = Sections.finalize_theorem list_sum_add;; let list_sum_lmul = Sections.finalize_theorem list_sum_lmul;; let list_sum_rmul = Sections.finalize_theorem list_sum_rmul;; let list_sum_delete1 = Sections.finalize_theorem list_sum_delete1;; let list_sum_perm_eq = Sections.finalize_theorem list_sum_perm_eq;; let list_sum_nseq = Sections.finalize_theorem list_sum_nseq;; let list_sum_eq = Sections.finalize_theorem list_sum_eq;; let list_sum_nth_eq = Sections.finalize_theorem list_sum_nth_eq;; let list_sum_const = Sections.finalize_theorem list_sum_const;; let list_sum_eq0 = Sections.finalize_theorem list_sum_eq0;; let list_sum_ge0 = Sections.finalize_theorem list_sum_ge0;; let list_sum_nth_le2 = Sections.finalize_theorem list_sum_nth_le2;; let list_sum_undup = Sections.finalize_theorem list_sum_undup;; let list_sum_set_of_list = Sections.finalize_theorem list_sum_set_of_list;; let list_sum_list_of_set = Sections.finalize_theorem list_sum_list_of_set;; let list_sum_nth = Sections.finalize_theorem list_sum_nth;; let list_sum_EL = Sections.finalize_theorem list_sum_EL;; let list_sum_EL_alt = Sections.finalize_theorem list_sum_EL_alt;; let list_sum_iota = Sections.finalize_theorem list_sum_iota;; let count_eq_list_sum = Sections.finalize_theorem count_eq_list_sum;; let count_eq_nsum = Sections.finalize_theorem count_eq_nsum;; let count_eq_list_sum_iota = Sections.finalize_theorem count_eq_list_sum_iota;; Sections.end_section "ListSum";; (* Section ListSumn *) Sections.begin_section "ListSumn";; (Sections.add_section_type (mk_var ("f", (`:A->num`))));; (* Lemma list_sumn_nil *) let list_sumn_nil = Sections.section_proof ["f"] `list_sumn [] f = 0` [ (((((use_arg_then2 ("list_sumn", [list_sumn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("foldr", [foldr]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma list_sumn_cons *) let list_sumn_cons = Sections.section_proof ["h";"t";"f"] `list_sumn (CONS h t) f = f h + list_sumn t f` [ (((((use_arg_then2 ("list_sumn", [list_sumn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("foldr", [foldr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sumn", [list_sumn]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma list_sum_eq_list_sumn *) let list_sum_eq_list_sumn = Sections.section_proof ["s";"f"] `list_sum s ((&) o f) = &(list_sumn s f)` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) (((((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sumn_nil", [list_sumn_nil]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("list_sumn_cons", [list_sumn_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sum_cons", [list_sum_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("REAL_OF_NUM_ADD", [REAL_OF_NUM_ADD]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("o_THM", [o_THM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma count_flatten *) let count_flatten = Sections.section_proof ["s";"a"] `count a (flatten s) = list_sumn (map (count a) s) I` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((((use_arg_then2 ("flatten", [flatten]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("foldr", [foldr]))(thm_tac (new_rewrite [] [])))))); (((((use_arg_then2 ("count", [count]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("map", [map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sumn_nil", [list_sumn_nil]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((((use_arg_then2 ("flatten", [flatten]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("map", [map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("list_sumn_cons", [list_sumn_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("count_cat", [count_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("I_THM", [I_THM]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_flatten *) let perm_eq_flatten = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> perm_eq (flatten s1) (flatten s2)` [ ((BETA_TAC THEN (move ["perm"])) THEN ((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["a"]))); ((repeat_tactic 1 9 (((use_arg_then2 ("count_flatten", [count_flatten]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("REAL_OF_NUM_EQ", [REAL_OF_NUM_EQ]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("list_sum_eq_list_sumn", [list_sum_eq_list_sumn]))(gsym_then (thm_tac (new_rewrite [] []))))))); (((use_arg_then2 ("list_sum_perm_eq", [list_sum_perm_eq])) (thm_tac apply_tac)) THEN (((use_arg_then2 ("perm_eq_map", [perm_eq_map]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Finalization of the section ListSumn *) let list_sumn_nil = Sections.finalize_theorem list_sumn_nil;; let list_sumn_cons = Sections.finalize_theorem list_sumn_cons;; let list_sum_eq_list_sumn = Sections.finalize_theorem list_sum_eq_list_sumn;; let count_flatten = Sections.finalize_theorem count_flatten;; let perm_eq_flatten = Sections.finalize_theorem perm_eq_flatten;; Sections.end_section "ListSumn";; (* Section PermEqPermutes *) Sections.begin_section "PermEqPermutes";; (Sections.add_section_var (mk_var ("x0", (`:A`))));; (* Lemma perm_eq_bij *) let perm_eq_bij = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> (?p. p permutes (0..sizel s1 - 1) /\ (!i. i < sizel s1 ==> nth x0 s2 i = nth x0 s1 (p i)))` [ (((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 ["h"]) THEN (move ["t"]) THEN (move ["IH"]))]) THEN (move ["s2"])); (((((use_arg_then2 ("perm_eq0l", [perm_eq0l]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))); (((fun arg_tac -> arg_tac (Arg_term (`I`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("sub0n", [sub0n]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("NUMSEG_SING", [NUMSEG_SING]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("PERMUTES_SING", [PERMUTES_SING]))(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 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))) THEN (move ["perm"])); (((fun arg_tac -> (use_arg_then2 ("IH", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`delete1 h s2`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN ((use_arg_then2 ("IH", [])) (disch_tac [])) THEN (clear_assumption "IH") THEN BETA_TAC THEN (move ["_"])); ((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("delete1_hd", [delete1_hd])) (fun fst_arg -> (use_arg_then2 ("h", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("t", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN (((fun arg_tac -> (use_arg_then2 ("perm_eq_delete1", [perm_eq_delete1])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (BETA_TAC THEN (case THEN (move ["q"])) THEN (case THEN (move ["perm_q"])) THEN (move ["del_eq"])); ((fun arg_tac -> arg_tac (Arg_term (`indexl h s2`))) (term_tac (set_tac "k"))); ((fun arg_tac -> arg_tac (Arg_term (`\i. if sizel t < i then i else if i = k then 0 else SUC (q (if i < k then i else i - 1))`))) (term_tac (set_tac "p"))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`h <- s2`))) (term_tac (have_gen_tac [](move ["hs2"])))) (((((fun arg_tac -> (use_arg_then2 ("perm_eq_mem", [perm_eq_mem])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`k < sizel s2`))) (term_tac (have_gen_tac [](move ["k_lt"])))) (((((use_arg_then2 ("k_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`sizel t = sizel s2 - 1`))) (term_tac (have_gen_tac [](move ["size_t"])))) (((((fun arg_tac -> (use_arg_then2 ("perm_eq_size", [perm_eq_size])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`i < k:num ==> p i = SUC (q i)`))) (term_tac (have_gen_tac ["i"](move ["p1"])))) (((((use_arg_then2 ("p_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_t", []))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`p k = 0`))) (term_tac (have_gen_tac [](move ["p2"])))) (((((use_arg_then2 ("p_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_t", []))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((fun arg_tac -> arg_tac (Arg_term (`k < i:num /\ i <= sizel t ==> p i = SUC (q (i - 1))`))) (term_tac (have_gen_tac ["i"](move ["p3"])))); (((((use_arg_then2 ("p_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_t", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`sizel t < i ==> p i = i`))) (term_tac (have_gen_tac ["i"](move ["p4"])))) ((((((use_arg_then2 ("p_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((((use_arg_then2 ("perm_q", [])) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("PERMUTES_FINITE_SURJECTIVE", [PERMUTES_FINITE_SURJECTIVE]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_NUMSEG", [FINITE_NUMSEG]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("IN_NUMSEG", [IN_NUMSEG]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("leq0n", [leq0n]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac))); (BETA_TAC THEN (case THEN (move ["_"])) THEN (case THEN (move ["q_in"])) THEN (move ["q_exists"])); (((use_arg_then2 ("p", [])) (term_tac exists_tac)) THEN (split_tac)); ((((use_arg_then2 ("PERMUTES_FINITE_SURJECTIVE", [PERMUTES_FINITE_SURJECTIVE]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_NUMSEG", [FINITE_NUMSEG]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("IN_NUMSEG", [IN_NUMSEG]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("leq0n", [leq0n]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)); ((THENL_FIRST) ((THENL) (split_tac) [((move ["n"]) THEN (move ["n_le"])); ALL_TAC]) (((((use_arg_then2 ("p4", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("NOT_LE", [NOT_LE]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac))); ((THENL_ROT (-1)) ((split_tac) THEN (move ["n"]) THEN (move ["n_le"]))); (((THENL) (((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN case) [ALL_TAC; (move ["n"])]) THEN (move ["n_le"])); (((use_arg_then2 ("k", [])) (term_tac exists_tac)) THEN ((((use_arg_then2 ("p2", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_t", []))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) ((((fun arg_tac -> (use_arg_then2 ("q_exists", [])) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (ANTS_TAC)) ((((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); (BETA_TAC THEN (case THEN (move ["m"])) THEN (case THEN (move ["m_le"])) THEN (move ["q_eq"])); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`if m < k then m else m + 1`))) (term_tac exists_tac)) THEN (split_tac)) ((((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN ((use_arg_then2 ("m_le", [])) (disch_tac [])) THEN (clear_assumption "m_le") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`m < k:num`))) (disch_eq_tac "m_lt_k" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) ((((use_arg_then2 ("p1", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("p3", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ADD1", [ADD1]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("q_eq", []))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))); ((((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN ((use_arg_then2 ("m_le", [])) (disch_tac [])) THEN (clear_assumption "m_le") THEN ((use_arg_then2 ("m_lt_k", [])) (disch_tac [])) THEN (clear_assumption "m_lt_k") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL) (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltngtP", [ltngtP])) (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 ("k", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [(move ["n_lt"]); ALL_TAC]); (((((use_arg_then2 ("p1", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN ((use_arg_then2 ("n_lt", [])) (disch_tac [])) THEN (clear_assumption "n_lt") THEN ((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN ((fun arg_tac -> (use_arg_then2 ("q_in", [])) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (((use_arg_then2 ("size_t", []))(thm_tac (new_rewrite [] [])))) THEN (arith_tac) THEN (done_tac)); ((THENL_LAST) ((THENL) case [(move ["k_lt"]); (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) (((((use_arg_then2 ("p2", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq0n", [leq0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("p3", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((fun arg_tac -> (use_arg_then2 ("q_in", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`n - 1`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("leq_sub2r", [leq_sub2r]))(thm_tac (new_rewrite [] [])))) THEN ((simp_tac THEN TRY done_tac))) THEN (((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN ((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); (BETA_TAC THEN (move ["i"]) THEN (move ["i_lt"])); ((THENL) (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("ltngtP", [ltngtP])) (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 ("k", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case) [(move ["i_lt_k"]); ALL_TAC]); ((THENL_FIRST) ((((fun arg_tac -> (use_arg_then2 ("del_eq", [])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (ANTS_TAC)) ((((use_arg_then2 ("size_t", [])) (disch_tac [])) THEN (clear_assumption "size_t") THEN ((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN ((use_arg_then2 ("i_lt_k", [])) (disch_tac [])) THEN (clear_assumption "i_lt_k") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); (((((use_arg_then2 ("nth_delete1", [nth_delete1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("k_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("i_lt_k", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("COND_CLAUSES", [COND_CLAUSES]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("p1", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((THENL_LAST) ((THENL) case [(move ["k_lt_i"]); (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) (((((use_arg_then2 ("p2", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("k_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((THENL_FIRST) ((((fun arg_tac -> (use_arg_then2 ("del_eq", [])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`i - 1`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (ANTS_TAC)) ((((use_arg_then2 ("k_lt_i", [])) (disch_tac [])) THEN (clear_assumption "k_lt_i") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); (((((use_arg_then2 ("nth_delete1", [nth_delete1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("k_def", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((fun arg_tac -> arg_tac (Arg_theorem (ARITH_RULE `k < i ==> ~(i - 1 < k) /\ SUC (i - 1) = i`)))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("COND_CLAUSES", [COND_CLAUSES]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("p3", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("k_lt_i", []))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma permutes_imp_perm_eq_iota *) let permutes_imp_perm_eq_iota = Sections.section_proof ["p";"n"] `p permutes 0..n ==> perm_eq (mkseq p (n + 1)) (iota 0 (n + 1))` [ (BETA_TAC THEN (move ["p_perm"])); (((((use_arg_then2 ("uniq_perm_eq_alt", [uniq_perm_eq_alt]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_iota", [size_iota]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (split_tac)); (((((fun arg_tac -> (use_arg_then2 ("uniq_nthP", [uniq_nthP])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] []))))) THEN (move ["i"]) THEN (move ["j"]) THEN (case THEN ((move ["i_lt"]) THEN (move ["j_lt"])))); ((THENL_FIRST) ((repeat_tactic 1 9 (((use_arg_then2 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) ((((use_arg_then2 ("j_lt", [])) (disch_tac [])) THEN (clear_assumption "j_lt") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((((fun arg_tac -> (use_arg_then2 ("PERMUTES_INJECTIVE", [PERMUTES_INJECTIVE])) (fun fst_arg -> (use_arg_then2 ("p_perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("p_perm", [])) (disch_tac [])) THEN (clear_assumption "p_perm") THEN BETA_TAC) THEN ((((use_arg_then2 ("PERMUTES_FINITE_SURJECTIVE", [PERMUTES_FINITE_SURJECTIVE]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("FINITE_NUMSEG", [FINITE_NUMSEG]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("IN_NUMSEG", [IN_NUMSEG]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("leq0n", [leq0n]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac))); (BETA_TAC THEN (case THEN (move ["_"])) THEN (case THEN (move ["p_ineqs"])) THEN (move ["p_exists"]) THEN (move ["i"])); (((((use_arg_then2 ("mem_iota", [mem_iota]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM_EXISTS_EL", [MEM_EXISTS_EL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq0n", [leq0n]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN ((THENL) (split_tac) [((case THEN (move ["j"])) THEN (case THEN (move ["j_lt"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))); ALL_TAC])); ((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((((use_arg_then2 ("j_lt", [])) (disch_tac [])) THEN (clear_assumption "j_lt") THEN ((fun arg_tac -> (use_arg_then2 ("p_ineqs", [])) (fun fst_arg -> (use_arg_then2 ("j", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); (((((use_arg_then2 ("ADD1", [ADD1]))(gsym_then (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 (move ["i_le"])); (((fun arg_tac -> (use_arg_then2 ("p_exists", [])) (fun fst_arg -> (use_arg_then2 ("i_le", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC THEN (case THEN (move ["j"])) THEN (case THEN (move ["j_le"])) THEN (move ["pj_eq"])); (((use_arg_then2 ("j", [])) (term_tac exists_tac)) THEN ((((fun arg_tac -> (use_arg_then2 ("EL_nth", [EL_nth])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltE", [ltE]))(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 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltE", [ltE]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("leqSS", [leqSS]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma perm_eq_iota *) let perm_eq_iota = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 ==> (?l. perm_eq l (iota 0 (sizel s1)) /\ s2 = map (nth x0 s1) l)` [ ((THENL) (((use_arg_then2 ("s1", [])) (disch_tac [])) THEN (clear_assumption "s1") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]); (((((use_arg_then2 ("perm_eq0l", [perm_eq0l]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN ((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("iota", [iota]))(thm_tac (new_rewrite [] [])))))); (((fun arg_tac -> arg_tac (Arg_term (`[]`))) (term_tac exists_tac)) THEN ((((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("map", [map]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((BETA_TAC THEN (move ["perm"])) THEN (((fun arg_tac -> (use_arg_then2 ("perm_eq_bij", [perm_eq_bij])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (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 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (move ["p"])) THEN (case THEN (move ["p_perm"])) THEN (move ["nth_eq"]))); ((fun arg_tac -> arg_tac (Arg_term (`sizel t`))) (term_tac (set_tac "n"))); ((fun arg_tac -> arg_tac (Arg_term (`mkseq p (SUC n)`))) (term_tac exists_tac)); ((((use_arg_then2 ("ADD1", [ADD1]))(thm_tac (new_rewrite [1; 2] [])))) THEN (((use_arg_then2 ("permutes_imp_perm_eq_iota", [permutes_imp_perm_eq_iota]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] []))))); (((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))) (thm_tac apply_tac)) THEN ((((use_arg_then2 ("size_map", [size_map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("perm_eq_size", [perm_eq_size])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac))); (BETA_TAC THEN (move ["i"]) THEN (move ["i_lt"])); ((((use_arg_then2 ("nth_map", [nth_map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("x0", [])) (term_tac exists_tac)) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_eq", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_permutesP *) let perm_eq_permutesP = Sections.section_proof ["s1";"s2"] `perm_eq s1 s2 <=> sizel s1 = sizel s2 /\ ?p. p permutes 0..sizel s1 - 1 /\ (!i. i < sizel s1 ==> nth x0 s2 i = nth x0 s1 (p i))` [ ((THENL) (split_tac) [(move ["perm"]); ((case THEN (move ["size_eq"])) THEN (case THEN (move ["p"])) THEN (case THEN ((DISCH_THEN (fun snd_th -> (use_arg_then2 ("permutes_imp_perm_eq_iota", [permutes_imp_perm_eq_iota])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN (move ["perm"]) THEN (move ["nth_eq"]))))]); (((((fun arg_tac -> (use_arg_then2 ("perm_eq_size", [perm_eq_size])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN ((use_arg_then2 ("perm_eq_bij", [perm_eq_bij])) (thm_tac apply_tac)) THEN (done_tac)); (((((use_arg_then2 ("perm_eqP", [perm_eqP]))(thm_tac (new_rewrite [] [])))) THEN (move ["a"])) THEN ((((use_arg_then2 ("REAL_OF_NUM_EQ", [REAL_OF_NUM_EQ]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((fun arg_tac -> (use_arg_then2 ("count_eq_list_sum_iota", [count_eq_list_sum_iota])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))))); (((fun arg_tac -> arg_tac (Arg_term (`sizel s1 = 0`))) (disch_eq_tac "eq0" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("eq0", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("iota", [iota]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("list_sum_nil", [list_sum_nil]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); (in_tac ["perm"] false (((fun arg_tac -> (fun arg_tac -> arg_tac (Arg_theorem (ARITH_RULE `!n. ~(n = 0) ==> n - 1 + 1 = n`))) (fun fst_arg -> (use_arg_then2 ("eq0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))); ((((fun arg_tac -> (use_arg_then2 ("list_sum_perm_eq", [list_sum_perm_eq])) (fun fst_arg -> (use_arg_then2 ("perm", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("list_sum_nth_eq", [list_sum_nth_eq])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`0`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (thm_tac apply_tac))); (((((use_arg_then2 ("size_mkseq", [size_mkseq]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_iota", [size_iota]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (move ["i"]) THEN (move ["i_lt"])); (((((use_arg_then2 ("nth_mkseq", [nth_mkseq]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_iota", [nth_iota]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("add0n", [add0n]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_eq", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Finalization of the section PermEqPermutes *) let perm_eq_bij = Sections.finalize_theorem perm_eq_bij;; let permutes_imp_perm_eq_iota = Sections.finalize_theorem permutes_imp_perm_eq_iota;; let perm_eq_iota = Sections.finalize_theorem perm_eq_iota;; let perm_eq_permutesP = Sections.finalize_theorem perm_eq_permutesP;; Sections.end_section "PermEqPermutes";; (* Section BelastButlast *) Sections.begin_section "BelastButlast";; (* Lemma head_belast *) let head_belast = Sections.section_proof ["x0";"x";"s"] `0 < sizel s ==> headl x0 (belast x s) = x` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["_"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("head", [head]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma nth_belast *) let nth_belast = Sections.section_proof ["x0";"s";"x";"i"] `i < sizel s ==> nth x0 (belast x s) i = if i = 0 then x else nth x0 s (i - 1)` [ ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") THEN ((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 ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((THENL) case [ALL_TAC; ((move ["i"]) THEN (move ["x"]))])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); ((BETA_TAC THEN (move ["x"]) THEN (move ["lt"])) THEN ((((use_arg_then2 ("nth0", [nth0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("head_belast", [head_belast]))(thm_tac (new_rewrite [] []))))) 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 (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["i_lt"])); ((((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))); ((((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN case) [ALL_TAC; (move ["j"])]) THEN (simp_tac)) THEN ((((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma take_belast *) let take_belast = Sections.section_proof ["s";"x";"n"] `n < sizel s /\ 0 < n ==> take n (belast x s) = x :: take (n - 1) s` [ ((((THENL) (((use_arg_then2 ("x", [])) (disch_tac [])) THEN (clear_assumption "x") 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 ["h"]) THEN (move ["t"]) THEN (move ["Ih"]))]) THEN ((THENL) case [ALL_TAC; ((move ["n"]) THEN (move ["x"]))])) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))) THEN (move ["ineqs"])); ((THENL_FIRST) ((THENL) (((use_arg_then2 ("ineqs", [])) (disch_tac [])) THEN (clear_assumption "ineqs") THEN ((use_arg_then2 ("n", [])) (disch_tac [])) THEN (clear_assumption "n") THEN case) [(move ["_"]); ((move ["n"]) THEN (move ["ineqs"]))]) (((((use_arg_then2 ("ONE", [ONE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("subnn", [subnn]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac))); (((((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma butlast_eq_take *) let butlast_eq_take = Sections.section_proof ["s"] `butlast s = take (sizel s - 1) s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) THEN (move ["Ih"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("butlast", [butlast]))(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 ("take", [take]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ONE", [ONE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subnn", [subnn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma butlast_cons *) let butlast_cons = Sections.section_proof ["h";"t"] `butlast (h :: t) = if t = [] then [] else h :: butlast t` [ (((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN case) [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) THEN ((repeat_tactic 1 9 (((use_arg_then2 ("butlast", [butlast]))(thm_tac (new_rewrite [] []))))) THEN (simp_tac) THEN (((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma butlast_BUTLAST *) let butlast_BUTLAST = Sections.section_proof [] `butlast = BUTLAST` [ (((use_arg_then2 ("FUN_EQ_THM", [FUN_EQ_THM]))(thm_tac (new_rewrite [] [])))); (((THENL) elim [ALL_TAC; ((move ["h"]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) THEN (move ["Ih"]))]) THEN ((((fun arg_tac -> arg_tac (Arg_theorem (GEN_ALL BUTLAST)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("butlast", [butlast]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); (((((use_arg_then2 ("NOT_CONS_NIL", [NOT_CONS_NIL]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma size_butlast *) let size_butlast = Sections.section_proof ["s"] `sizel (butlast s) = sizel s - 1` [ (((((use_arg_then2 ("butlast_eq_take", [butlast_eq_take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_take", [size_take]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma butlast_belast *) let butlast_belast = Sections.section_proof ["s";"x"] `0 < sizel s ==> belast x s = x :: butlast 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 ["h"]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) THEN (move ["Ih"]) THEN (move ["x"]) THEN (move ["_"]))]) THEN ((repeat_tactic 0 10 (((fun arg_tac ->(use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg1 -> (use_arg_then2 ("ltn0", [ltn0]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("butlast", [butlast]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); ((((use_arg_then2 ("Ih", [])) (disch_tac [])) THEN (clear_assumption "Ih") THEN BETA_TAC) THEN (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma cat_butlast_last *) let cat_butlast_last = Sections.section_proof ["x0";"s"] `0 < sizel s ==> s = butlast s ++ [last x0 s]` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN ((THENL) case [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) THEN (move ["Ih"]) THEN (move ["_"]))]) THEN ((repeat_tactic 0 10 (((fun arg_tac ->(use_arg_then2 ("size_nil", [size_nil]))(fun tmp_arg1 -> (use_arg_then2 ("ltn0", [ltn0]))(fun tmp_arg2 -> arg_tac (Arg_theorem (CONJ (get_arg_thm tmp_arg1) (get_arg_thm tmp_arg2))))))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("butlast", [butlast]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("last", [last]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("cat", [cat]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))); ((((use_arg_then2 ("Ih", [])) (disch_tac [])) THEN (clear_assumption "Ih") THEN BETA_TAC) THEN (((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("last", [last]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [1] []))))) THEN (done_tac)); ];; (* Finalization of the section BelastButlast *) let head_belast = Sections.finalize_theorem head_belast;; let nth_belast = Sections.finalize_theorem nth_belast;; let take_belast = Sections.finalize_theorem take_belast;; let butlast_eq_take = Sections.finalize_theorem butlast_eq_take;; let butlast_cons = Sections.finalize_theorem butlast_cons;; let butlast_BUTLAST = Sections.finalize_theorem butlast_BUTLAST;; let size_butlast = Sections.finalize_theorem size_butlast;; let butlast_belast = Sections.finalize_theorem butlast_belast;; let cat_butlast_last = Sections.finalize_theorem cat_butlast_last;; Sections.end_section "BelastButlast";; (* Section MoreRot *) Sections.begin_section "MoreRot";; (* Lemma rot_nil *) let rot_nil = Sections.section_proof ["n"] `rot n [] = []` [ (((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("drop", [drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("take", [take]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("cat", [cat]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma rotr_nil *) let rotr_nil = Sections.section_proof ["n"] `rotr n [] = []` [ (((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_nil", [rot_nil]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma perm_eq_rot *) let perm_eq_rot = Sections.section_proof ["n";"s"] `perm_eq (rot n s) s` [ (((((use_arg_then2 ("perm_rot", [perm_rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("perm_eq_refl", [perm_eq_refl]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma nth_rot *) let nth_rot = Sections.section_proof ["x0";"s";"k";"i"] `k <= sizel s /\ i < sizel s ==> nth x0 (rot k s) i = nth x0 s ((k + i) MOD sizel s)` [ (BETA_TAC THEN (move ["ineqs"])); ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] []))))); (((fun arg_tac -> arg_tac (Arg_term (`i:num < _`))) (disch_eq_tac "i_lt" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((use_arg_then2 ("nth_drop", [nth_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MOD_LT", [MOD_LT]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("ineqs", [])) (disch_tac [])) THEN (clear_assumption "ineqs") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`i - (sizel s - k) = (k + i) - sizel s`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) ((((use_arg_then2 ("ineqs", [])) (disch_tac [])) THEN (clear_assumption "ineqs") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((THENL_FIRST) (((use_arg_then2 ("nth_take", [nth_take]))(thm_tac (new_rewrite [] [])))) ((((use_arg_then2 ("ineqs", [])) (disch_tac [])) THEN (clear_assumption "ineqs") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`k + i = 1 * sizel s + ((k + i) - sizel s)`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [2] []))))))) ((((use_arg_then2 ("ineqs", [])) (disch_tac [])) THEN (clear_assumption "ineqs") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((((use_arg_then2 ("MOD_MULT_ADD", [MOD_MULT_ADD]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MOD_LT", [MOD_LT]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((((use_arg_then2 ("ineqs", [])) (disch_tac [])) THEN (clear_assumption "ineqs") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma rot_to_index_explicit *) let rot_to_index_explicit = Sections.section_proof ["s";"x"] `MEM x s ==> rot (indexl x s) s = x :: dropl 1 (rot (indexl x s) s)` [ (BETA_TAC THEN (move ["mem_x"])); ((fun arg_tac -> arg_tac (Arg_term (`0 < sizel s /\ indexl x s < sizel s`))) (term_tac (have_gen_tac [](move ["ineqs"])))); (((((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_x", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("has_predT", [has_predT]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("predT", [predT]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andbT", [andbT]))(thm_tac (new_rewrite [] []))))) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac)); (((((fun arg_tac -> (use_arg_then2 ("cons_head_drop1", [cons_head_drop1])) (fun fst_arg -> (use_arg_then2 ("x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [1] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN ((congr_tac (`_1 :: _2`)) THEN ((TRY done_tac)))); (((((use_arg_then2 ("nth0", [nth0]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_rot", [nth_rot]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltnW", [ltnW]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MOD_LT", [MOD_LT]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma rot_to_index *) let rot_to_index = Sections.section_proof ["s";"x"] `MEM x s ==> ?t. rot (indexl x s) s = x :: t` [ (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("rot_to_index_explicit", [rot_to_index_explicit])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN ((fun arg_tac -> arg_tac (Arg_term (`dropl 1 (rot (indexl x s) s)`))) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma shift_right *) let shift_right = Sections.section_proof ["h";"t"] `rotr 1 [] = [] /\ rotr 1 (h :: t) = belast (last h t) (h :: t)` [ (((((use_arg_then2 ("rotr_nil", [rotr_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [1] [])))) THEN (((use_arg_then2 ("rotr1_rcons", [rotr1_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma nth_shift_left *) let nth_shift_left = Sections.section_proof ["x0";"s";"i"] `i < sizel s ==> nth x0 (rot 1 s) i = if (i = sizel s - 1) then nth x0 s 0 else nth x0 s (i + 1)` [ (BETA_TAC THEN (move ["i_lt"])); ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn_neqAle", [ltn_neqAle]))(thm_tac (new_rewrite [] []))))); (((fun arg_tac -> arg_tac (Arg_term (`i = sizel s - 1`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); ((THENL_FIRST) ((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_take", [nth_take]))(thm_tac (new_rewrite [] []))))) ((((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((congr_tac (`nth x0 s _`)) THEN (((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`i <= sizel s - 1`))) (term_tac (have_gen_tac []((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac))))) ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); (((((use_arg_then2 ("nth_drop", [nth_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addnC", [addnC]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN ((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma nth_shift_right *) let nth_shift_right = Sections.section_proof ["x0";"s";"i"] `i < sizel s ==> nth x0 (rotr 1 s) i = if (i = 0) then nth x0 s (sizel s - 1) else nth x0 s (i - 1)` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN elim) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["Ih"]) THEN (move ["i_lt"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((((use_arg_then2 ("shift_right", [shift_right]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`i = 0`))) (disch_eq_tac "i_eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) (((((use_arg_then2 ("i_eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("last_nth", [last_nth])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((fun arg_tac -> (use_arg_then2 ("num_CASES", [num_CASES])) (fun fst_arg -> (use_arg_then2 ("i", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN case THEN ((TRY done_tac)) THEN (case THEN (move ["m"])) THEN (move ["i_eq"])); ((((use_arg_then2 ("i_eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("EQ_SYM_EQ", [EQ_SYM_EQ]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_rcons", [nth_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_belast", [size_belast]))(thm_tac (new_rewrite [] []))))); ((((use_arg_then2 ("i_eq", [])) (disch_tac [])) THEN (clear_assumption "i_eq") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma rot_rot_eq_rot *) let rot_rot_eq_rot = Sections.section_proof ["s";"m";"n"] `?k. rot m (rot n s) = rot k s` [ ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`m <= sizel s`))) (disch_eq_tac "m_le" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); (((use_arg_then2 ("n", [])) (term_tac exists_tac)) THEN ((((use_arg_then2 ("rot_oversize", [rot_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("m_le", [])) (disch_tac [])) THEN (clear_assumption "m_le") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`n <= sizel s`))) (disch_eq_tac "n_le" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); (((use_arg_then2 ("m", [])) (term_tac exists_tac)) THEN ((((fun arg_tac -> (use_arg_then2 ("rot_oversize", [rot_oversize])) (fun fst_arg -> (use_arg_then2 ("n", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("rot_add_mod", [rot_add_mod]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((fun arg_tac -> arg_tac (Arg_term (`if _ then _1 else _2`))) (term_tac (set_tac "k"))); (((use_arg_then2 ("k", [])) (term_tac exists_tac)) THEN (done_tac)); ];; (* Lemma index_rot *) let index_rot = Sections.section_proof ["s";"n";"x"] `uniq s /\ n < sizel s /\ MEM x s ==> indexl x (rot n s) = if n <= indexl x s then (indexl x s - n) else (indexl x s + sizel s - n)` [ (BETA_TAC THEN (case THEN (move ["uniq_s"])) THEN (case THEN (move ["n_lt"])) THEN (move ["mem_x"])); ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_cat", [index_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_drop_uniq", [index_drop_uniq]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("index_take", [index_take]))(thm_tac (new_rewrite [] []))))); ((fun arg_tac -> arg_tac (Arg_term (`indexl x s`))) (term_tac (set_tac "i"))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`i < sizel s`))) (term_tac (have_gen_tac [](move ["i_lt"])))) ((((use_arg_then2 ("mem_x", [])) (disch_tac [])) THEN (clear_assumption "mem_x") THEN BETA_TAC) THEN ((((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("i_def", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((((use_arg_then2 ("n_lt", [])) (disch_tac [])) THEN (clear_assumption "n_lt") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma rotr1_eq_cons *) let rotr1_eq_cons = Sections.section_proof ["h";"t"] `rotr 1 (h :: t) = last h t :: belast h t` [ (((((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [1] [])))) THEN (((use_arg_then2 ("rotr1_rcons", [rotr1_rcons]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Finalization of the section MoreRot *) let rot_nil = Sections.finalize_theorem rot_nil;; let rotr_nil = Sections.finalize_theorem rotr_nil;; let perm_eq_rot = Sections.finalize_theorem perm_eq_rot;; let nth_rot = Sections.finalize_theorem nth_rot;; let rot_to_index_explicit = Sections.finalize_theorem rot_to_index_explicit;; let rot_to_index = Sections.finalize_theorem rot_to_index;; let shift_right = Sections.finalize_theorem shift_right;; let nth_shift_left = Sections.finalize_theorem nth_shift_left;; let nth_shift_right = Sections.finalize_theorem nth_shift_right;; let rot_rot_eq_rot = Sections.finalize_theorem rot_rot_eq_rot;; let index_rot = Sections.finalize_theorem index_rot;; let rotr1_eq_cons = Sections.finalize_theorem rotr1_eq_cons;; Sections.end_section "MoreRot";; (* Section NextPrev *) Sections.begin_section "NextPrev";; (* Lemma next_el_outside *) let next_el_outside = Sections.section_proof ["s";"x"] `~(MEM x s) ==> next_el s x = x` [ ((repeat_tactic 1 9 (((use_arg_then2 ("index_eq_size", [index_eq_size]))(thm_tac (new_rewrite [] []))))) THEN (move ["i_eq"])); ((((use_arg_then2 ("next_el", [next_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("i_eq", []))(thm_tac (new_rewrite [] []))))); ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("sub0n", [sub0n]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("head", [head]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> arg_tac (Arg_theorem (ARITH_RULE `!n. ~(SUC n = SUC n - 1)`)))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (((repeat_tactic 1 9 (((use_arg_then2 ("nth_default", [nth_default]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma prev_el_outside *) let prev_el_outside = Sections.section_proof ["s";"x"] `~(MEM x s) ==> prev_el s x = x` [ (((((use_arg_then2 ("prev_el", [prev_el]))(thm_tac (new_rewrite [] [])))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma next_el_rot *) let next_el_rot = Sections.section_proof ["x";"s"] `MEM x s ==> next_el s x = headl x (rot (indexl x s + 1) s)` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["x_list"]))]) ((((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("next_el", [next_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))); (((fun arg_tac -> arg_tac (Arg_term (`indexl x _ = _2`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_oversize", [rot_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth0", [nth0]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subn_gt0", [subn_gt0]))(thm_tac (new_rewrite [] []))))); ((((use_arg_then2 ("LT_LE", [LT_LE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn1", [addn1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltE", [ltE]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("x_list", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqSS", [eqSS]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (((((use_arg_then2 ("nth_drop", [nth_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma prev_el_rot *) let prev_el_rot = Sections.section_proof ["x";"s"] `MEM x s ==> prev_el s x = headl x (rotr 1 (rot (indexl x s) s))` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["x_list"]))]) ((((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("prev_el", [prev_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("x_list", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)); (((fun arg_tac -> arg_tac (Arg_term (`indexl x _ = _2`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot0", [rot0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lastI", [lastI]))(thm_tac (new_rewrite [2] [])))) THEN (((use_arg_then2 ("rotr1_rcons", [rotr1_rcons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("head", [head]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("last", [last]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("rot_add_mod", [rot_add_mod]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("leq_pred", [leq_pred]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leq_eqVlt", [leq_eqVlt]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] []))))); (((fun arg_tac -> arg_tac (Arg_term (`indexl x (CONS h t) = 1`))) (disch_eq_tac "eq2" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((use_arg_then2 ("eq2", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subnn", [subnn]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth0", [nth0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn1", [addn1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("rot_oversize", [rot_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("leqnn", [leqnn]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`SUC (sizel t) < sizel t + indexl x (CONS h t)`))) (term_tac (have_gen_tac [](move ["neq"])))) ((((use_arg_then2 ("eq2", [])) (disch_tac [])) THEN (clear_assumption "eq2") THEN ((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((((use_arg_then2 ("leqNgt", [leqNgt]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("neq", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("rot", [rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth0", [nth0]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_cat", [nth_cat]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_drop", [size_drop]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subn_gt0", [subn_gt0]))(thm_tac (new_rewrite [] []))))); ((fun arg_tac -> arg_tac (Arg_term (`(sizel t + indexl x (CONS h t)) - SUC (sizel t) < sizel (CONS h t)`))) (term_tac (have_gen_tac []((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac))))); ((((use_arg_then2 ("eq2", [])) (disch_tac [])) THEN (clear_assumption "eq2") THEN ((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN ((use_arg_then2 ("x_list", [])) (disch_tac [])) THEN (clear_assumption "x_list") THEN BETA_TAC) THEN ((((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ((((use_arg_then2 ("nth_drop", [nth_drop]))(thm_tac (new_rewrite [] [])))) THEN ((congr_tac (`nth x _1 _2`)) THEN ((TRY done_tac)))); ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma next_el_alt *) let next_el_alt = Sections.section_proof ["x0";"x";"s"] `MEM x s ==> next_el s x = nth x0 (rot 1 s) (indexl x s)` [ ((BETA_TAC THEN (move ["xs"])) THEN ((((use_arg_then2 ("next_el", [next_el]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> (use_arg_then2 ("nth_shift_left", [nth_shift_left])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth0", [nth0]))(gsym_then (thm_tac (new_rewrite [] []))))))); ((((fun arg_tac -> arg_tac (Arg_term (`indexl x s = _`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) THEN ((use_arg_then2 ("set_nth_default", [set_nth_default])) (thm_tac apply_tac)) THEN (((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN ((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN BETA_TAC) THEN (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma prev_el_alt *) let prev_el_alt = Sections.section_proof ["x0";"x";"s"] `MEM x s ==> prev_el s x = nth x0 (rotr 1 s) (indexl x s)` [ ((BETA_TAC THEN (move ["xs"])) THEN ((((use_arg_then2 ("prev_el", [prev_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("xs", []))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((fun arg_tac -> (use_arg_then2 ("nth_shift_right", [nth_shift_right])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("nth_last", [nth_last]))(gsym_then (thm_tac (new_rewrite [] []))))))); ((((fun arg_tac -> arg_tac (Arg_term (`indexl x s = _`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) THEN ((use_arg_then2 ("set_nth_default", [set_nth_default])) (thm_tac apply_tac)) THEN (((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN ((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN BETA_TAC) THEN (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma mem_next_el *) let mem_next_el = Sections.section_proof ["x";"s"] `MEM x s ==> MEM (next_el s x) s` [ ((BETA_TAC THEN (move ["xs"])) THEN ((((fun arg_tac -> (use_arg_then2 ("next_el_alt", [next_el_alt])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`HD s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("mem_rot", [mem_rot])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`1`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma mem_prev_el *) let mem_prev_el = Sections.section_proof ["x";"s"] `MEM x s ==> MEM (prev_el s x) s` [ ((BETA_TAC THEN (move ["xs"])) THEN ((((fun arg_tac -> (use_arg_then2 ("prev_el_alt", [prev_el_alt])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`HD s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("mem_rotr", [mem_rotr])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`1`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_rotr", [size_rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma prev_next_id *) let prev_next_id = Sections.section_proof ["x";"s"] `uniq s ==> prev_el s (next_el s x) = x` [ ((THENL_LAST) (((fun arg_tac -> arg_tac (Arg_term (`MEM x s`))) (disch_eq_tac "xs" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) (((((use_arg_then2 ("next_el_outside", [next_el_outside]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("prev_el_outside", [prev_el_outside]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (BETA_TAC THEN (move ["uniq_s"])); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`0 < sizel s`))) (term_tac (have_gen_tac [](move ["size_gt"])))) (((((use_arg_then2 ("has_predT", [has_predT]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("predT", [predT]))(thm_tac (new_rewrite [] []))))) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac))); ((((fun arg_tac -> (use_arg_then2 ("prev_el_alt", [prev_el_alt])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`HD s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("mem_next_el", [mem_next_el]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("next_el_alt", [next_el_alt])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`HD s`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((((use_arg_then2 ("nth_shift_left", [nth_shift_left]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))); (((fun arg_tac -> arg_tac (Arg_term (`indexl x s = sizel s - 1`))) (disch_eq_tac "eq1" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((use_arg_then2 ("nth_shift_right", [nth_shift_right]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_uniq", [index_uniq]))(thm_tac (new_rewrite [] [])))) THEN ((simp_tac THEN TRY done_tac)) THEN (((use_arg_then2 ("eq1", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((((use_arg_then2 ("nth_shift_right", [nth_shift_right]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_uniq", [index_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("uniq_s", []))(thm_tac (new_rewrite [] [])))))) THEN (TRY (((((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN ((use_arg_then2 ("eq1", [])) (disch_tac [])) THEN (clear_assumption "eq1") THEN BETA_TAC) THEN (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (arith_tac))))); (((((use_arg_then2 ("addn1", [addn1]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eqS0", [eqS0]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma next_prev_id *) let next_prev_id = Sections.section_proof ["x";"s"] `uniq s ==> next_el s (prev_el s x) = x` [ ((THENL_LAST) (((fun arg_tac -> arg_tac (Arg_term (`MEM x s`))) (disch_eq_tac "xs" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) (((((use_arg_then2 ("prev_el_outside", [prev_el_outside]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("next_el_outside", [next_el_outside]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((BETA_TAC THEN (move ["uniq_s"])) THEN ((fun arg_tac -> arg_tac (Arg_term (`HD s`))) (term_tac (set_tac "x0")))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`0 < sizel s`))) (term_tac (have_gen_tac [](move ["size_gt"])))) (((((use_arg_then2 ("has_predT", [has_predT]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("hasP", [hasP]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("predT", [predT]))(thm_tac (new_rewrite [] []))))) THEN ((use_arg_then2 ("x", [])) (term_tac exists_tac)) THEN (done_tac))); ((((fun arg_tac -> (use_arg_then2 ("next_el_alt", [next_el_alt])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("mem_prev_el", [mem_prev_el]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("prev_el_alt", [prev_el_alt])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((((use_arg_then2 ("nth_shift_right", [nth_shift_right]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))); (((fun arg_tac -> arg_tac (Arg_term (`indexl x s = 0`))) (disch_eq_tac "eq1" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); (((((use_arg_then2 ("nth_shift_left", [nth_shift_left]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_uniq", [index_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("uniq_s", []))(thm_tac (new_rewrite [] []))))) THEN (simp_tac)) THEN (TRY (((((use_arg_then2 ("size_gt", [])) (disch_tac [])) THEN (clear_assumption "size_gt") THEN BETA_TAC) THEN (arith_tac))))); (((((use_arg_then2 ("eq1", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((((use_arg_then2 ("nth_shift_left", [nth_shift_left]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_uniq", [index_uniq]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("uniq_s", []))(thm_tac (new_rewrite [] [])))))) THEN (TRY (((((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN ((use_arg_then2 ("eq1", [])) (disch_tac [])) THEN (clear_assumption "eq1") THEN BETA_TAC) THEN (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (arith_tac))))); ((fun arg_tac -> arg_tac (Arg_term (`~(indexl x s - 1 = sizel s - 1)`))) (term_tac (have_gen_tac []((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN (simp_tac))))); ((((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN ((use_arg_then2 ("eq1", [])) (disch_tac [])) THEN (clear_assumption "eq1") THEN BETA_TAC) THEN (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); (((((use_arg_then2 ("subnK", [subnK]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("eq1", [])) (disch_tac [])) THEN (clear_assumption "eq1") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma next_el_mod *) let next_el_mod = Sections.section_proof ["x0";"s";"x"] `MEM x s ==> next_el s x = nth x0 s ((indexl x s + 1) MOD sizel s)` [ ((BETA_TAC THEN (move ["xs"])) THEN ((((use_arg_then2 ("next_el", [next_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("nth0", [nth0]))(gsym_then (thm_tac (new_rewrite [] []))))))); ((fun arg_tac -> arg_tac (Arg_term (`sizel s`))) (term_tac (set_tac "n"))); ((fun arg_tac -> arg_tac (Arg_term (`1 <= n /\ ~(n = 0)`))) (term_tac (have_gen_tac [](case THEN ((move ["ge1"]) THEN (move ["neq0"])))))); ((((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN BETA_TAC) THEN (((((use_arg_then2 ("MEM_EXISTS_EL", [MEM_EXISTS_EL]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size", [size]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] []))))) THEN ALL_TAC THEN (case THEN (move ["i"]))) THEN (arith_tac) THEN (done_tac)); (((fun arg_tac -> arg_tac (Arg_term (`indexl x s = _`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); ((((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("subnK", [subnK]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("muln1", [muln1])) (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 [1] []))))) THEN (((use_arg_then2 ("MOD_MULT", [MOD_MULT]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); (((use_arg_then2 ("set_nth_default", [set_nth_default])) (thm_tac apply_tac)) THEN ((((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("lt0n", [lt0n]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`indexl x s + 1 < n`))) (term_tac (have_gen_tac [](move ["lt"])))); ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN ((use_arg_then2 ("xs", [])) (disch_tac [])) THEN (clear_assumption "xs") THEN BETA_TAC) THEN ((((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] []))))) THEN (arith_tac) THEN (done_tac)); (((((use_arg_then2 ("MOD_LT", [MOD_LT]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN ((use_arg_then2 ("set_nth_default", [set_nth_default])) (thm_tac apply_tac)) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma next_el_power *) let next_el_power = Sections.section_proof ["x0";"s";"x";"i"] `uniq s /\ MEM x s ==> (next_el s POWER i) x = nth x0 s ((indexl x s + i) MOD (sizel s))` [ (BETA_TAC THEN (case THEN ((move ["uniq_s"]) THEN (move ["mem_x"])))); ((fun arg_tac -> arg_tac (Arg_term (`sizel s`))) (term_tac (set_tac "n"))); ((fun arg_tac -> arg_tac (Arg_term (`indexl x s`))) (term_tac (set_tac "k"))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`k < n:num`))) (term_tac (have_gen_tac [](move ["k_lt"])))) (((((use_arg_then2 ("k_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("n_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((THENL) (((use_arg_then2 ("i", [])) (disch_tac [])) THEN (clear_assumption "i") THEN elim) [ALL_TAC; ((move ["i"]) THEN (move ["Ih"]))]); (((((use_arg_then2 ("Hypermap.POWER_0", [Hypermap.POWER_0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("I_THM", [I_THM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MOD_LT", [MOD_LT]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("k_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`~(n = 0)`))) (term_tac (have_gen_tac [](move ["neq0"])))); ((((use_arg_then2 ("mem_x", [])) (disch_tac [])) THEN (clear_assumption "mem_x") THEN ((use_arg_then2 ("contraL", [contraL])) (disch_tac [])) THEN (clear_assumption "contraL") THEN (DISCH_THEN apply_tac)) THEN (((((use_arg_then2 ("n_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_eq0", [size_eq0]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ((((use_arg_then2 ("Hypermap.COM_POWER", [Hypermap.COM_POWER]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("o_THM", [o_THM]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Ih", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("next_el_mod", [next_el_mod]))(thm_tac (new_rewrite [] []))))); (((((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("DIVISION", [DIVISION]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ((((fun arg_tac -> (use_arg_then2 ("index_uniq", [index_uniq])) (fun fst_arg -> (use_arg_then2 ("uniq_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("DIVISION", [DIVISION]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((TRY done_tac))); (congr_tac (`nth x0 s _`)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`k + SUC i = (k + i) + 1`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) ((arith_tac) THEN (done_tac))); (((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("MOD_ADD_MOD", [MOD_ADD_MOD])) (fun fst_arg -> (use_arg_then2 ("neq0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`k + i:num`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`n = 1`))) (disch_eq_tac "eq1" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) (((((use_arg_then2 ("eq1", []))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("MOD_1", [MOD_1]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac))); (((((fun arg_tac -> (use_arg_then2 ("MOD_LT", [MOD_LT])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`1`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (((use_arg_then2 ("neq0", [])) (disch_tac [])) THEN (clear_assumption "neq0") THEN ((use_arg_then2 ("eq1", [])) (disch_tac [])) THEN (clear_assumption "eq1") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); ];; (* Lemma next_el_orbit *) let next_el_orbit = Sections.section_proof ["s";"x"] `uniq s /\ MEM x s ==> orbit_map (next_el s) x = set_of_list s` [ (BETA_TAC THEN (case THEN ((move ["uniq_s"]) THEN (move ["mem_x"])))); ((fun arg_tac -> arg_tac (Arg_term (`sizel s`))) (term_tac (set_tac "n"))); ((fun arg_tac -> arg_tac (Arg_term (`HD s`))) (term_tac (set_tac "x0"))); ((fun arg_tac -> arg_tac (Arg_term (`~(n = 0)`))) (term_tac (have_gen_tac [](move ["neq0"])))); ((((use_arg_then2 ("mem_x", [])) (disch_tac [])) THEN (clear_assumption "mem_x") THEN ((use_arg_then2 ("contraL", [contraL])) (disch_tac [])) THEN (clear_assumption "contraL") THEN (DISCH_THEN apply_tac)) THEN (((((use_arg_then2 ("n_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("size_eq0", [size_eq0]))(thm_tac (new_rewrite [] []))))) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); (((((use_arg_then2 ("Hypermap.orbit_map", [Hypermap.orbit_map]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("EXTENSION", [EXTENSION]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_ELIM_THM", [IN_ELIM_THM]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac)) THEN (move ["d"])); ((THENL) (split_tac) [((case THEN (move ["i"])) THEN (case THEN (move ["i_ge0"])) THEN (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))); (move ["mem_d"])]); (((((fun arg_tac -> (use_arg_then2 ("next_el_power", [next_el_power])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("mem_nth", [mem_nth]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("DIVISION", [DIVISION]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`indexl x s`))) (term_tac (set_tac "k"))); ((fun arg_tac -> arg_tac (Arg_term (`indexl d s`))) (term_tac (set_tac "i"))); ((fun arg_tac -> arg_tac (Arg_term (`k < n /\ i < n:num`))) (term_tac (have_gen_tac [](case THEN ((move ["k_lt"]) THEN (move ["i_lt"])))))); (((((use_arg_then2 ("n_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("k_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("i_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("index_mem", [index_mem]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`n - k + i:num`))) (term_tac exists_tac)); ((((use_arg_then2 ("GE", [GE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("LE_0", [LE_0]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("andTb", [andTb]))(thm_tac (new_rewrite [] []))))); ((((fun arg_tac -> (use_arg_then2 ("next_el_power", [next_el_power])) (fun fst_arg -> (use_arg_then2 ("x0", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("k_def", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("n_def", []))(thm_tac (new_rewrite [] []))))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`k + n - k + i = n + i:num`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) ((((use_arg_then2 ("k_lt", [])) (disch_tac [])) THEN (clear_assumption "k_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); (((((fun arg_tac -> (use_arg_then2 ("mul1n", [mul1n])) (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 [1] []))))) THEN (((use_arg_then2 ("MOD_MULT_ADD", [MOD_MULT_ADD]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MOD_LT", [MOD_LT]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("i_def", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("nth_index", [nth_index]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma next_el_rot_eq *) let next_el_rot_eq = Sections.section_proof ["s";"n"] `uniq s ==> next_el (rot n s) = next_el s` [ ((BETA_TAC THEN (move ["uniq_s"])) THEN ((((use_arg_then2 ("FUN_EQ_THM", [FUN_EQ_THM]))(thm_tac (new_rewrite [] [])))) THEN (move ["x"]))); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`n < sizel s`))) (disch_eq_tac "n_lt" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); (((((use_arg_then2 ("rot_oversize", [rot_oversize]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("NOT_LT", [NOT_LT]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`MEM x s`))) (disch_eq_tac "mem_x" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); (((repeat_tactic 1 9 (((use_arg_then2 ("next_el_outside", [next_el_outside]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("mem_rot", [mem_rot]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`MEM x (rot n s)`))) (term_tac (have_gen_tac [](move ["mem_rot"])))) ((((use_arg_then2 ("mem_rot", [mem_rot]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((repeat_tactic 1 9 (((use_arg_then2 ("next_el_rot", [next_el_rot]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth0", [nth0]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN (((use_arg_then2 ("index_rot", [index_rot]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((fun arg_tac -> arg_tac (Arg_term (`indexl x s`))) (term_tac (set_tac "i"))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`i < sizel s`))) (term_tac (have_gen_tac [](move ["i_lt"])))) ((((use_arg_then2 ("mem_x", [])) (disch_tac [])) THEN (clear_assumption "mem_x") THEN BETA_TAC) THEN (((use_arg_then2 ("index_mem", [index_mem]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((fun arg_tac -> arg_tac (Arg_term (`0 < sizel s`))) (term_tac (have_gen_tac [](move ["size_gt0"])))); (((THENL) (((use_arg_then2 ("mem_x", [])) (disch_tac [])) THEN (clear_assumption "mem_x") THEN ((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]))]) THEN ((((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("gtS0", [gtS0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((fun arg_tac -> arg_tac (Arg_term (`i + 1 <= sizel s /\ n <= sizel s /\ i - n + 1 <= sizel s /\ ~(0 = sizel s)`))) (term_tac (have_gen_tac [](move ["ineqs"])))); ((((use_arg_then2 ("n_lt", [])) (disch_tac [])) THEN (clear_assumption "n_lt") THEN ((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac)); (((fun arg_tac -> arg_tac (Arg_term (`n:num <= _`))) (disch_eq_tac "n_le" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)); ((repeat_tactic 1 9 (((use_arg_then2 ("nth_rot", [nth_rot]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("DIVISION", [DIVISION]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((TRY done_tac))); ((((fun arg_tac -> (use_arg_then2 ("MOD_LT", [MOD_LT])) (fun fst_arg -> (use_arg_then2 ("n_lt", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN (((use_arg_then2 ("MOD_ADD_MOD", [MOD_ADD_MOD]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); (((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`n + i - n + 1 = i + 1`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) ((((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))) THEN (done_tac)); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`(i + sizel s - n) + 1 <= sizel s`))) (term_tac (have_gen_tac [](move ["ineq2"])))) ((((use_arg_then2 ("i_lt", [])) (disch_tac [])) THEN (clear_assumption "i_lt") THEN ((use_arg_then2 ("n_le", [])) (disch_tac [])) THEN (clear_assumption "n_le") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((repeat_tactic 1 9 (((use_arg_then2 ("nth_rot", [nth_rot]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 0 10 (((use_arg_then2 ("size_rot", [size_rot]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 0 10 (((use_arg_then2 ("DIVISION", [DIVISION]))(gsym_then (thm_tac (new_rewrite [] [])))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("addn0", [addn0]))(thm_tac (new_rewrite [] [])))))); ((((fun arg_tac -> (use_arg_then2 ("MOD_LT", [MOD_LT])) (fun fst_arg -> (use_arg_then2 ("n_lt", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [1] []))))) THEN (((use_arg_then2 ("MOD_ADD_MOD", [MOD_ADD_MOD]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))); ((THENL_FIRST) ((fun arg_tac -> arg_tac (Arg_term (`n + (i + sizel s - n) + 1 = 1 * sizel s + (i + 1)`))) (term_tac (have_gen_tac [](((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))))) ((((use_arg_then2 ("n_lt", [])) (disch_tac [])) THEN (clear_assumption "n_lt") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); ((((use_arg_then2 ("MOD_MULT_ADD", [MOD_MULT_ADD]))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma next_el_inj *) let next_el_inj = Sections.section_proof ["s";"x";"y"] `uniq s ==> (next_el s x = next_el s y <=> x = y)` [ ((BETA_TAC THEN (move ["uniq_s"])) THEN ((THENL) (split_tac) [ALL_TAC; ((((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)))])); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`MEM x s`))) (disch_eq_tac "mem_x" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); (((((use_arg_then2 ("next_el_outside", [next_el_outside]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac))) THEN (move ["x_eq"])); ((THENL_FIRST) (((THENL_ROT 1)) ((fun arg_tac -> arg_tac (Arg_term (`~MEM y s`))) (term_tac (have_gen_tac [](move ["mem_y"]))))) ((((use_arg_then2 ("x_eq", [])) (disch_tac [])) THEN (clear_assumption "x_eq") THEN BETA_TAC) THEN (((use_arg_then2 ("next_el_outside", [next_el_outside]))(thm_tac (new_rewrite [] [])))) THEN (done_tac))); ((((use_arg_then2 ("mem_x", [])) (disch_tac [])) THEN (clear_assumption "mem_x") 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_next_el", [mem_next_el])) (thm_tac (match_mp_then snd_th MP_TAC))))) THEN (((use_arg_then2 ("x_eq", []))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (done_tac)); ((THENL_ROT (-1)) (((fun arg_tac -> arg_tac (Arg_term (`MEM y s`))) (disch_eq_tac "mem_y" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac))); ((((fun arg_tac -> (use_arg_then2 ("next_el_outside", [next_el_outside])) (fun fst_arg -> (use_arg_then2 ("mem_y", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (move ["y_eq"])); ((((fun arg_tac -> (use_arg_then2 ("mem_next_el", [mem_next_el])) (fun fst_arg -> (use_arg_then2 ("mem_x", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (disch_tac [])) THEN BETA_TAC) THEN ((((use_arg_then2 ("y_eq", []))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("mem_y", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); (((DISCH_THEN (fun snd_th -> (fun arg_tac -> (use_arg_then2 ("congr1", [congr1])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`prev_el 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 (repeat_tactic 1 9 (((use_arg_then2 ("prev_next_id", [prev_next_id]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma prev_el_rot_eq *) let prev_el_rot_eq = Sections.section_proof ["s";"n"] `uniq s ==> prev_el (rot n s) = prev_el s` [ ((((use_arg_then2 ("FUN_EQ_THM", [FUN_EQ_THM]))(thm_tac (new_rewrite [] [])))) THEN (move ["uniq_s"]) THEN (move ["x"])); (((((fun arg_tac -> (use_arg_then2 ("next_el_inj", [next_el_inj])) (fun fst_arg -> (use_arg_then2 ("uniq_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("next_el_rot_eq", [next_el_rot_eq])) (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 [1] []))))) THEN ((TRY done_tac)) THEN (repeat_tactic 1 9 (((use_arg_then2 ("next_prev_id", [next_prev_id]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("rot_uniq", [rot_uniq]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma prev_el_inj *) let prev_el_inj = Sections.section_proof ["s";"x";"y"] `uniq s ==> (prev_el s x = prev_el s y <=> x = y)` [ ((BETA_TAC THEN (move ["uniq_s"])) THEN (((THENL) (split_tac) [ALL_TAC; (((conv_thm_tac DISCH_THEN)(thm_tac (new_rewrite [] []))))]) THEN ((TRY done_tac)))); (((((fun arg_tac -> (use_arg_then2 ("next_el_inj", [next_el_inj])) (fun fst_arg -> (use_arg_then2 ("uniq_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("next_prev_id", [next_prev_id]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma next_el_permutes *) let next_el_permutes = Sections.section_proof ["s"] `uniq s ==> (next_el s) permutes (set_of_list s)` [ ((((((use_arg_then2 ("permutes", [permutes]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("IN_SET_OF_LIST", [IN_SET_OF_LIST]))(thm_tac (new_rewrite [] []))))) THEN (move ["uniq_s"])) THEN ((THENL) (split_tac) [(move ["x"]); (move ["y"])])); (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("next_el_outside", [next_el_outside])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC) THEN (done_tac)); ((((use_arg_then2 ("EXISTS_UNIQUE_ALT", [EXISTS_UNIQUE_ALT]))(thm_tac (new_rewrite [] [])))) THEN (((fun arg_tac -> arg_tac (Arg_term (`prev_el s y`))) (term_tac exists_tac)) THEN (move ["z"]))); (((((fun arg_tac -> (fun arg_tac -> (use_arg_then2 ("prev_el_inj", [prev_el_inj])) (fun fst_arg -> (fun arg_tac -> arg_tac (Arg_term (`next_el s z`))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun fst_arg -> (use_arg_then2 ("uniq_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(gsym_then (thm_tac (new_rewrite [] []))))) THEN (((use_arg_then2 ("prev_next_id", [prev_next_id]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((fun arg_tac -> (use_arg_then2 ("eq_sym", [eq_sym])) (fun fst_arg -> (use_arg_then2 ("z", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma inverse_next_el *) let inverse_next_el = Sections.section_proof ["s"] `uniq s ==> inverse (next_el s) = prev_el s` [ ((((use_arg_then2 ("FUN_EQ_THM", [FUN_EQ_THM]))(thm_tac (new_rewrite [] [])))) THEN (move ["uniq_s"]) THEN (move ["x"])); (((((fun arg_tac -> (use_arg_then2 ("PERMUTES_INVERSE_EQ", [PERMUTES_INVERSE_EQ])) (fun fst_arg -> (fun arg_tac -> (use_arg_then2 ("next_el_permutes", [next_el_permutes])) (fun fst_arg -> (use_arg_then2 ("uniq_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("next_prev_id", [next_prev_id]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma prev_el_permutes *) let prev_el_permutes = Sections.section_proof ["s"] `uniq s ==> (prev_el s) permutes (set_of_list s)` [ ((BETA_TAC THEN (move ["uniq_s"])) THEN ((((use_arg_then2 ("inverse_next_el", [inverse_next_el]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("PERMUTES_INVERSE", [PERMUTES_INVERSE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("next_el_permutes", [next_el_permutes]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma inverse_prev_el *) let inverse_prev_el = Sections.section_proof ["s"] `uniq s ==> inverse (prev_el s) = next_el s` [ ((BETA_TAC THEN (move ["uniq_s"])) THEN ((((use_arg_then2 ("inverse_next_el", [inverse_next_el]))(gsym_then (thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)))); ((((fun arg_tac -> (fun arg_tac -> arg_tac (Arg_theorem (GEN_ALL PERMUTES_INVERSE_INVERSE))) (fun fst_arg -> (fun arg_tac -> (use_arg_then2 ("next_el_permutes", [next_el_permutes])) (fun fst_arg -> (use_arg_then2 ("uniq_s", [])) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg))) (fun snd_arg -> combine_args_then arg_tac fst_arg snd_arg)))(thm_tac (new_rewrite [] [])))) THEN (done_tac)); ];; (* Lemma next_el_rotr_eq *) let next_el_rotr_eq = Sections.section_proof ["s";"n"] `uniq s ==> next_el (rotr n s) = next_el s` [ (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("next_el_rot_eq", [next_el_rot_eq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (move ["eq"])) THEN ((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma prev_el_rotr_eq *) let prev_el_rotr_eq = Sections.section_proof ["s";"n"] `uniq s ==> prev_el (rotr n s) = prev_el s` [ (((DISCH_THEN (fun snd_th -> (use_arg_then2 ("prev_el_rot_eq", [prev_el_rot_eq])) (thm_tac (match_mp_then snd_th MP_TAC)))) THEN BETA_TAC THEN (move ["eq"])) THEN ((((use_arg_then2 ("rotr", [rotr]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("eq", []))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma next_el_hd_cons2 *) let next_el_hd_cons2 = Sections.section_proof ["h1";"h2";"t"] `next_el (h1 :: (h2 :: t)) h1 = h2` [ ((((use_arg_then2 ("next_el", [next_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("Seq.index_head", [Seq.index_head]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))))); ((THENL_FIRST) (((fun arg_tac -> arg_tac (Arg_term (`0 = _`))) (disch_eq_tac "eq" [])) THEN case THEN (simp_tac) THEN (process_fst_eq_tac)) ((((use_arg_then2 ("eq", [])) (disch_tac [])) THEN (clear_assumption "eq") THEN BETA_TAC) THEN (arith_tac) THEN (done_tac))); (((((use_arg_then2 ("addn1", [addn1]))(thm_tac (new_rewrite [] [])))) THEN (repeat_tactic 1 9 (((use_arg_then2 ("nth", [nth]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Lemma next_el_hd_cons *) let next_el_hd_cons = Sections.section_proof ["h";"t"] `0 < sizel t ==> next_el (h :: t) h = HD t` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN case) [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("next_el_hd_cons2", [next_el_hd_cons2]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("HD", [HD]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma next_el_hd_belast *) let next_el_hd_belast = Sections.section_proof ["h";"t"] `1 < sizel t ==> next_el (belast h t) h = HD t` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN case) [ALL_TAC; ((move ["h2"]) THEN (move ["t"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); ((((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("HD", [HD]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ONE", [ONE]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltSS", [ltSS]))(thm_tac (new_rewrite [] []))))); ((THENL_FIRST) ((THENL) (((use_arg_then2 ("t", [])) (disch_tac [])) THEN (clear_assumption "t") THEN case) [ALL_TAC; ((move ["h3"]) THEN (move ["t"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("belast", [belast]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("next_el_hd_cons2", [next_el_hd_cons2]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma next_el_last *) let next_el_last = Sections.section_proof ["x0";"s"] `0 < sizel s /\ uniq s ==> next_el s (last x0 s) = HD s` [ ((THENL_FIRST) ((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (case THEN (move ["_"])) THEN (move ["uniq_s"]))]) (((((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN (done_tac))); (((((use_arg_then2 ("next_el", [next_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("last", [last]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("index_last", [index_last]))(thm_tac (new_rewrite [] [])))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("size_cons", [size_cons]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("succnK", [succnK]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("head", [head]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("HD", [HD]))(thm_tac (new_rewrite [] []))))) THEN (done_tac)); ];; (* Lemma prev_el_hd *) let prev_el_hd = Sections.section_proof ["x0";"s"] `0 < sizel s ==> prev_el s (HD s) = last x0 s` [ (((THENL) (((use_arg_then2 ("s", [])) (disch_tac [])) THEN (clear_assumption "s") THEN case) [ALL_TAC; ((move ["h"]) THEN (move ["t"]) THEN (move ["_"]))]) THEN ((repeat_tactic 0 10 (((use_arg_then2 ("size_nil", [size_nil]))(thm_tac (new_rewrite [] []))))) THEN (repeat_tactic 0 10 (((use_arg_then2 ("ltn0", [ltn0]))(thm_tac (new_rewrite [] []))))) THEN ((TRY done_tac)) THEN (((use_arg_then2 ("HD", [HD]))(thm_tac (new_rewrite [] [])))))); (((((use_arg_then2 ("prev_el", [prev_el]))(thm_tac (new_rewrite [] [])))) THEN (((use_arg_then2 ("MEM", [MEM]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (((use_arg_then2 ("Seq.index_head", [Seq.index_head]))(thm_tac (new_rewrite [] [])))) THEN (simp_tac) THEN (repeat_tactic 1 9 (((use_arg_then2 ("last", [last]))(thm_tac (new_rewrite [] [])))))) THEN (done_tac)); ];; (* Finalization of the section NextPrev *) let next_el_outside = Sections.finalize_theorem next_el_outside;; let prev_el_outside = Sections.finalize_theorem prev_el_outside;; let next_el_rot = Sections.finalize_theorem next_el_rot;; let prev_el_rot = Sections.finalize_theorem prev_el_rot;; let next_el_alt = Sections.finalize_theorem next_el_alt;; let prev_el_alt = Sections.finalize_theorem prev_el_alt;; let mem_next_el = Sections.finalize_theorem mem_next_el;; let mem_prev_el = Sections.finalize_theorem mem_prev_el;; let prev_next_id = Sections.finalize_theorem prev_next_id;; let next_prev_id = Sections.finalize_theorem next_prev_id;; let next_el_mod = Sections.finalize_theorem next_el_mod;; let next_el_power = Sections.finalize_theorem next_el_power;; let next_el_orbit = Sections.finalize_theorem next_el_orbit;; let next_el_rot_eq = Sections.finalize_theorem next_el_rot_eq;; let next_el_inj = Sections.finalize_theorem next_el_inj;; let prev_el_rot_eq = Sections.finalize_theorem prev_el_rot_eq;; let prev_el_inj = Sections.finalize_theorem prev_el_inj;; let next_el_permutes = Sections.finalize_theorem next_el_permutes;; let inverse_next_el = Sections.finalize_theorem inverse_next_el;; let prev_el_permutes = Sections.finalize_theorem prev_el_permutes;; let inverse_prev_el = Sections.finalize_theorem inverse_prev_el;; let next_el_rotr_eq = Sections.finalize_theorem next_el_rotr_eq;; let prev_el_rotr_eq = Sections.finalize_theorem prev_el_rotr_eq;; let next_el_hd_cons2 = Sections.finalize_theorem next_el_hd_cons2;; let next_el_hd_cons = Sections.finalize_theorem next_el_hd_cons;; let next_el_hd_belast = Sections.finalize_theorem next_el_hd_belast;; let next_el_last = Sections.finalize_theorem next_el_last;; let prev_el_hd = Sections.finalize_theorem prev_el_hd;; Sections.end_section "NextPrev";; (* Close the module *) end;;