(* =========================================================== *)
(* Additional list definitions and theorems *)
(* Author: Alexey Solovyev *)
(* Date: 2012-10-27 *)
(* =========================================================== *)
module More_list = struct
(* definitions *)
(* lemmas *)
let EL_TABLE = prove(`!(f:num->A) n i. i < n ==>
EL i (
TABLE f n) = f i`,
REPEAT GEN_TAC THEN SPEC_TAC (`n:num`, `n:num`) THEN
INDUCT_TAC THENL [ ARITH_TAC; ALL_TAC ] THEN
REWRITE_TAC[
TABLE;
REVERSE_TABLE;
REVERSE;
EL_APPEND] THEN
REWRITE_TAC[GSYM
TABLE;
LENGTH_TABLE] THEN
DISCH_TAC THEN COND_CASES_TAC THENL
[
FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
ALL_TAC
] THEN
SUBGOAL_THEN `i = n:num` (fun
th -> REWRITE_TAC[
th]) THENL
[
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[ARITH_RULE `n - n = 0`;
EL;
HD]);;
let LIST_EL_EQ = prove(`!ul vl:(A)list. ul = vl <=>
(
LENGTH ul =
LENGTH vl /\ (!j. j <
LENGTH ul ==>
EL j ul =
EL j vl))`,
REPEAT STRIP_TAC THEN
EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
SPEC_TAC (`vl:(A)list`, `vl:(A)list`) THEN SPEC_TAC (`ul:(A)list`, `ul:(A)list`) THEN
LIST_INDUCT_TAC THEN LIST_INDUCT_TAC THEN SIMP_TAC[
LENGTH_EQ_NIL;
EQ_SYM_EQ;
LENGTH; ARITH_RULE `~(0 = SUC a)`] THEN
POP_ASSUM (fun
th -> ALL_TAC) THEN
REWRITE_TAC[ARITH_RULE `SUC a = SUC b <=> a = b`] THEN
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `t':(A)list`) THEN
ASM_REWRITE_TAC[] THEN
ANTS_TAC THENL
[
REPEAT STRIP_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `SUC j`) THEN
ASM_REWRITE_TAC[ARITH_RULE `SUC a < SUC b <=> a < b`;
EL;
TL];
ALL_TAC
] THEN
DISCH_TAC THEN
FIRST_X_ASSUM (MP_TAC o SPEC `0`) THEN
ASM_SIMP_TAC[ARITH_RULE `0 < SUC a`;
EL;
HD]);;
let L_SEQ_CONS = prove(`!n m. n <= m ==>
l_seq n m = CONS n (
l_seq (n + 1) m)`,
REPEAT STRIP_TAC THEN
REWRITE_TAC[
LIST_EL_EQ;
LENGTH_L_SEQ;
LENGTH] THEN CONJ_TAC THENL
[
ASM_ARITH_TAC;
ALL_TAC
] THEN
INDUCT_TAC THENL
[
ASM_SIMP_TAC[
EL_L_SEQ] THEN ASM_REWRITE_TAC[
EL;
HD] THEN ARITH_TAC;
DISCH_TAC THEN
ASM_SIMP_TAC[
EL_L_SEQ] THEN ASM_REWRITE_TAC[
EL;
TL] THEN
MP_TAC (SPECL [`j:num`; `m:num`; `n + 1`]
EL_L_SEQ) THEN ANTS_TAC THENL
[
ASM_ARITH_TAC;
ALL_TAC
] THEN
DISCH_THEN (fun
th -> REWRITE_TAC[
th]) THEN ARITH_TAC
]);;
let EL_BUTLAST = prove(`!(l:(A)list) i. i <
LENGTH l - 1 ==>
EL i (
BUTLAST l) =
EL i l`,
MATCH_MP_TAC
list_INDUCT THEN REWRITE_TAC[
BUTLAST;
LENGTH] THEN REPEAT STRIP_TAC THEN
COND_CASES_TAC THENL
[
UNDISCH_TAC `i < SUC (
LENGTH (a1:(A)list)) - 1` THEN
ASM_REWRITE_TAC[
LENGTH] THEN ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[
EL_CONS] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
FIRST_X_ASSUM (MP_TAC o SPEC `i - 1`) THEN
ANTS_TAC THENL
[
ASM_ARITH_TAC;
ALL_TAC
] THEN
REWRITE_TAC[]);;
end;;