-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathFloverTactics.sml
147 lines (125 loc) · 4.07 KB
/
FloverTactics.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
(*
Some tactics which ease proving goals
*)
structure FloverTactics =
struct
local open intLib wordsLib in end;
open set_relationTheory;
open BasicProvers Defn HolKernel Parse Tactic monadsyntax
alistTheory arithmeticTheory bagTheory boolLib boolSimps bossLib
combinTheory dep_rewrite finite_mapTheory indexedListsTheory
listTheory llistTheory markerLib
optionTheory pairLib pairTheory pred_setTheory
quantHeuristicsLib relationTheory res_quanTheory rich_listTheory
sortingTheory sptreeTheory stringTheory sumTheory wordsTheory simpLib;
open ExpressionsTheory CommandsTheory;
fun elim_conj thm =
let val (hypl, concl) = dest_thm thm in
if is_conj concl
then
let val (thm1, thm2) = CONJ_PAIR thm in
elim_conj thm1 \\ elim_conj thm2
end
else
ASSUME_TAC thm
end;
fun elim_exist1 thm =
let val (hypl, concl) = dest_thm thm in
if is_exists concl
then CHOOSE_THEN elim_exist thm
else elim_conj thm
end
and elim_exist thm =
let val (hypl, concl) = dest_thm thm in
if is_exists concl
then CHOOSE_THEN elim_exist1 thm
else elim_conj thm
end;
fun inversion pattern cases_thm =
qpat_x_assum pattern
(fn thm => elim_exist (ONCE_REWRITE_RULE [cases_thm] thm));
fun qexistsl_tac termlist =
case termlist of
[] => ALL_TAC
| t::tel => qexists_tac t \\ qexistsl_tac tel;
fun specialize pat_hyp pat_thm =
qpat_x_assum pat_hyp
(fn hyp =>
(qspec_then pat_thm ASSUME_TAC hyp) ORELSE
(qpat_assum pat_thm
(fn asm => ASSUME_TAC (MP hyp asm))));
fun rw_asm pat_asm =
qpat_x_assum pat_asm
(fn asm =>
(once_rewrite_tac [asm] \\ ASSUME_TAC asm));
fun rw_asm_star pat_asm =
qpat_x_assum pat_asm
(fn asm =>
fs [Once asm] \\ ASSUME_TAC asm);
fun rw_sym_asm pat_asm =
qpat_x_assum pat_asm
(fn asm =>
(once_rewrite_tac [GSYM asm] \\ ASSUME_TAC asm));
fun rw_thm_asm pat_asm thm =
qpat_x_assum pat_asm
(fn asm =>
(ASSUME_TAC (ONCE_REWRITE_RULE[thm] asm)));
(* Destruct like tactic, by Michael Norrish, see HOL-info **)
(* Given theorem
P x y z ==> ?w. Q w
introduce P x y z as a subgoal and Q w for some w as hypothesis *)
fun destruct th =
let
val hyp_to_prove = lhand (concl th)
in
SUBGOAL_THEN hyp_to_prove (fn thm => STRIP_ASSUME_TAC (MP th thm))
end
fun impl_subgoal_tac th =
let
val hyp_to_prove = lhand (concl th)
in
SUBGOAL_THEN hyp_to_prove (fn thm => assume_tac (MP th thm))
end
val flover_eval_tac :tactic=
let val _ = computeLib.del_funs([sptreeTheory.lookup_def])
val _ = computeLib.add_funs([sptreeTheory.lookup_compute]) in
computeLib.EVAL_TAC
\\ fs[sptreeTheory.lookup_def]
\\ rpt strip_tac
\\ fs[sptreeTheory.lookup_def]
\\ EVAL_TAC
end;
fun iter_exists_tac ind n =
fn tm =>
if ind < n
then
(part_match_exists_tac
(fn concl => List.nth (strip_conj concl, ind)) tm)
ORELSE (iter_exists_tac (ind+1) n tm)
else
FAIL_TAC (concat ["No matching clause found for ", term_to_string tm]) ;
val try_all:term -> tactic =
fn tm =>
fn (asl, g) =>
let
val len = length (strip_conj (snd (dest_exists g))) in
iter_exists_tac 0 len tm (asl, g)
end;
val find_exists_tac =
first_assum (try_all o concl);
val bool_simps = Q.prove (
‘(∀ P. (P ∧ F) = F) ∧
(∀ P. (F ∨ P) = P) ∧
(∀ P Q. (if P then Q else F) = (P ∧ Q))’, fs[]);
val cond_simp = Q.prove (
‘(if P then Q else R) = (P /\ Q \/ ~P /\ R)’,
TOP_CASE_TAC);
val flover_ss =
(mk_simpset ([DatatypeSimps.case_cong_ss [“:real expr”, “:real cmd”]]
@ ssfrags_of bool_ss))
&& [option_case_eq |> GEN “v:'b” |> Q.ISPEC ‘T’ |> SIMP_RULE bool_ss [],
pair_case_eq |> GEN “v:'a” |> Q.ISPEC ‘T’ |> SIMP_RULE bool_ss [],
expr_case_eq |> GEN “v:'a” |> Q.ISPEC ‘T’ |> SIMP_RULE bool_ss [],
cmd_case_eq |> GEN “v:'a” |> Q.ISPEC ‘T’ |> SIMP_RULE bool_ss [],
bool_simps, cond_simp, PULL_EXISTS];
end