1 |
|
2 (* Title: HOL/Tools/Presburger/presburger.ML |
1 (* Title: HOL/Tools/Presburger/presburger.ML |
3 ID: $Id$ |
2 ID: $Id$ |
4 Author: Amine Chaieb, TU Muenchen |
3 Author: Amine Chaieb, TU Muenchen |
5 *) |
4 *) |
6 |
5 |
7 signature PRESBURGER = |
6 signature PRESBURGER = |
8 sig |
7 sig |
9 val cooper_tac: bool -> thm list -> thm list -> Proof.context -> int -> Tactical.tactic |
8 val cooper_tac: bool -> thm list -> thm list -> Proof.context -> int -> tactic |
10 end; |
9 end; |
11 |
10 |
12 structure Presburger : PRESBURGER = |
11 structure Presburger : PRESBURGER = |
13 struct |
12 struct |
14 |
13 |
15 open Conv; |
14 open Conv; |
16 val comp_ss = HOL_ss addsimps @{thms "Groebner_Basis.comp_arith"}; |
15 val comp_ss = HOL_ss addsimps @{thms "Groebner_Basis.comp_arith"}; |
17 |
16 |
18 fun strip_imp_cprems ct = |
17 fun strip_objimp ct = |
19 case term_of ct of |
18 (case Thm.term_of ct of |
20 Const ("==>", _) $ _ $ _ => Thm.dest_arg1 ct :: strip_imp_cprems (Thm.dest_arg ct) |
19 Const ("op -->", _) $ _ $ _ => |
21 | _ => []; |
20 let val (A, B) = Thm.dest_binop ct |
22 |
21 in A :: strip_objimp B end |
23 val cprems_of = strip_imp_cprems o cprop_of; |
22 | _ => [ct]); |
24 |
|
25 fun strip_objimp ct = |
|
26 case term_of ct of |
|
27 Const ("op -->", _) $ _ $ _ => Thm.dest_arg1 ct :: strip_objimp (Thm.dest_arg ct) |
|
28 | _ => [ct]; |
|
29 |
23 |
30 fun strip_objall ct = |
24 fun strip_objall ct = |
31 case term_of ct of |
25 case term_of ct of |
32 Const ("All", _) $ Abs (xn,xT,p) => |
26 Const ("All", _) $ Abs (xn,xT,p) => |
33 let val (a,(v,t')) = (apsnd (Thm.dest_abs (SOME xn)) o Thm.dest_comb) ct |
27 let val (a,(v,t')) = (apsnd (Thm.dest_abs (SOME xn)) o Thm.dest_comb) ct |
52 (fold_rev (fn p => fn q => Thm.capply (Thm.capply @{cterm "op -->"} p) q) qs q) |
44 (fold_rev (fn p => fn q => Thm.capply (Thm.capply @{cterm "op -->"} p) q) qs q) |
53 val g = Thm.capply (Thm.capply @{cterm "op ==>"} (Thm.capply @{cterm "Trueprop"} ng)) p' |
45 val g = Thm.capply (Thm.capply @{cterm "op ==>"} (Thm.capply @{cterm "Trueprop"} ng)) p' |
54 val ntac = (case qs of [] => q aconvc @{cterm "False"} |
46 val ntac = (case qs of [] => q aconvc @{cterm "False"} |
55 | _ => false) |
47 | _ => false) |
56 in |
48 in |
57 if ntac then no_tac st |
49 if ntac then no_tac |
58 else rtac (Goal.prove_internal [] g (K (blast_tac HOL_cs 1))) i st |
50 else rtac (Goal.prove_internal [] g (K (blast_tac HOL_cs 1))) i |
59 end) |
51 end) |
60 end; |
52 end; |
61 |
53 |
62 local |
54 local |
63 fun ty cts t = |
55 fun ty cts t = |
64 if not (typ_of (ctyp_of_term t) mem [HOLogic.intT, HOLogic.natT]) then false |
56 if not (typ_of (ctyp_of_term t) mem [HOLogic.intT, HOLogic.natT]) then false |
65 else case term_of t of |
57 else case term_of t of |
66 c$_$_ => not (member (op aconv) cts c) |
58 c$_$_ => not (member (op aconv) cts c) |
67 | c$_ => not (member (op aconv) cts c) |
59 | c$_ => not (member (op aconv) cts c) |
68 | c => not (member (op aconv) cts c) |
60 | c => not (member (op aconv) cts c) |
69 | _ => true |
|
70 |
61 |
71 val term_constants = |
62 val term_constants = |
72 let fun h acc t = case t of |
63 let fun h acc t = case t of |
73 Const _ => insert (op aconv) t acc |
64 Const _ => insert (op aconv) t acc |
74 | a$b => h (h acc a) b |
65 | a$b => h (h acc a) b |
90 | Abs(_,_,_) => Thm.dest_abs NONE t ||> h acc |> uncurry (remove (op aconvc)) |
81 | Abs(_,_,_) => Thm.dest_abs NONE t ||> h acc |> uncurry (remove (op aconvc)) |
91 | _ => acc |
82 | _ => acc |
92 in h [] ct end |
83 in h [] ct end |
93 end; |
84 end; |
94 |
85 |
95 fun generalize_tac ctxt f i st = |
86 fun generalize_tac f = CSUBGOAL (fn (p, i) => PRIMITIVE (fn st => |
96 case try (nth (cprems_of st)) (i - 1) of |
87 let |
97 NONE => all_tac st |
|
98 | SOME p => |
|
99 let |
|
100 fun all T = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "all"} |
88 fun all T = Drule.cterm_rule (instantiate' [SOME T] []) @{cpat "all"} |
101 fun gen x t = Thm.capply (all (ctyp_of_term x)) (Thm.cabs x t) |
89 fun gen x t = Thm.capply (all (ctyp_of_term x)) (Thm.cabs x t) |
102 val ts = sort (fn (a,b) => Term.fast_term_ord (term_of a, term_of b)) (f p) |
90 val ts = sort (fn (a,b) => Term.fast_term_ord (term_of a, term_of b)) (f p) |
103 val p' = fold_rev gen ts p |
91 val p' = fold_rev gen ts p |
104 in Seq.of_list [implies_intr p' (implies_elim st (fold forall_elim ts (assume p')))] |
92 in implies_intr p' (implies_elim st (fold forall_elim ts (assume p'))) end)); |
105 end; |
|
106 |
93 |
107 local |
94 local |
108 val ss1 = comp_ss |
95 val ss1 = comp_ss |
109 addsimps simp_thms @ [@{thm "nat_number_of_def"}, @{thm "zdvd_int"}] |
96 addsimps simp_thms @ [@{thm "nat_number_of_def"}, @{thm "zdvd_int"}] |
110 @ map (fn r => r RS sym) |
97 @ map (fn r => r RS sym) |
132 addsimprocs [cancel_div_mod_proc] |
119 addsimprocs [cancel_div_mod_proc] |
133 val splits_ss = comp_ss addsimps [@{thm "mod_div_equality'"}] addsplits |
120 val splits_ss = comp_ss addsimps [@{thm "mod_div_equality'"}] addsplits |
134 [@{thm "split_zdiv"}, @{thm "split_zmod"}, @{thm "split_div'"}, |
121 [@{thm "split_zdiv"}, @{thm "split_zmod"}, @{thm "split_div'"}, |
135 @{thm "split_min"}, @{thm "split_max"}, @{thm "abs_split"}] |
122 @{thm "split_min"}, @{thm "split_max"}, @{thm "abs_split"}] |
136 in |
123 in |
137 fun nat_to_int_tac ctxt i = |
124 fun nat_to_int_tac ctxt = |
138 simp_tac (Simplifier.context ctxt ss1) i THEN |
125 simp_tac (Simplifier.context ctxt ss1) THEN_ALL_NEW |
139 simp_tac (Simplifier.context ctxt ss2) i THEN |
126 simp_tac (Simplifier.context ctxt ss2) THEN_ALL_NEW |
140 TRY (simp_tac (Simplifier.context ctxt comp_ss) i); |
127 simp_tac (Simplifier.context ctxt comp_ss); |
141 |
128 |
142 fun div_mod_tac ctxt i = simp_tac (Simplifier.context ctxt div_mod_ss) i; |
129 fun div_mod_tac ctxt i = simp_tac (Simplifier.context ctxt div_mod_ss) i; |
143 fun splits_tac ctxt i = simp_tac (Simplifier.context ctxt splits_ss) i; |
130 fun splits_tac ctxt i = simp_tac (Simplifier.context ctxt splits_ss) i; |
144 end; |
131 end; |
145 |
132 |
146 |
133 |
147 fun eta_beta_tac ctxt i st = case try (nth (cprems_of st)) (i - 1) of |
134 fun core_cooper_tac ctxt = CSUBGOAL (fn (p, i) => |
148 NONE => no_tac st |
|
149 | SOME p => |
|
150 let |
|
151 val eq = (Thm.eta_long_conversion then_conv Thm.beta_conversion true) p |
|
152 val p' = Thm.rhs_of eq |
|
153 val th = implies_intr p' (equal_elim (symmetric eq) (assume p')) |
|
154 in rtac th i st |
|
155 end; |
|
156 |
|
157 |
|
158 |
|
159 fun core_cooper_tac ctxt i st = |
|
160 case try (nth (cprems_of st)) (i - 1) of |
|
161 NONE => all_tac st |
|
162 | SOME p => |
|
163 let |
135 let |
164 val cpth = |
136 val cpth = |
165 if !quick_and_dirty |
137 if !quick_and_dirty |
166 then linzqe_oracle (ProofContext.theory_of ctxt) |
138 then linzqe_oracle (ProofContext.theory_of ctxt) |
167 (Envir.beta_norm (Pattern.eta_long [] (term_of (Thm.dest_arg p)))) |
139 (Envir.beta_norm (Pattern.eta_long [] (term_of (Thm.dest_arg p)))) |
168 else arg_conv (Cooper.cooper_conv ctxt) p |
140 else arg_conv (Cooper.cooper_conv ctxt) p |
169 val p' = Thm.rhs_of cpth |
141 val p' = Thm.rhs_of cpth |
170 val th = implies_intr p' (equal_elim (symmetric cpth) (assume p')) |
142 val th = implies_intr p' (equal_elim (symmetric cpth) (assume p')) |
171 in rtac th i st end |
143 in rtac th i end |
172 handle Cooper.COOPER _ => no_tac st; |
144 handle Cooper.COOPER _ => no_tac); |
173 |
145 |
174 fun nogoal_tac i st = case try (nth (cprems_of st)) (i - 1) of |
146 fun finish_tac q = SUBGOAL (fn (_, i) => |
175 NONE => no_tac st |
147 (if q then I else TRY) (rtac TrueI i)); |
176 | SOME _ => all_tac st |
|
177 |
148 |
178 fun finish_tac q i st = case try (nth (cprems_of st)) (i - 1) of |
149 fun cooper_tac elim add_ths del_ths ctxt = |
179 NONE => all_tac st |
|
180 | SOME _ => (if q then I else TRY) (rtac TrueI i) st |
|
181 |
|
182 fun cooper_tac elim add_ths del_ths ctxt i = |
|
183 let val ss = fst (CooperData.get ctxt) delsimps del_ths addsimps add_ths |
150 let val ss = fst (CooperData.get ctxt) delsimps del_ths addsimps add_ths |
184 in |
151 in |
185 nogoal_tac i |
152 ObjectLogic.full_atomize_tac |
186 THEN (EVERY o (map TRY)) |
153 THEN_ALL_NEW eta_long_tac |
187 [ObjectLogic.full_atomize_tac i, |
154 THEN_ALL_NEW simp_tac ss |
188 eta_beta_tac ctxt i, |
155 THEN_ALL_NEW (TRY o generalize_tac (int_nat_terms ctxt)) |
189 simp_tac ss i, |
156 THEN_ALL_NEW ObjectLogic.full_atomize_tac |
190 generalize_tac ctxt (int_nat_terms ctxt) i, |
157 THEN_ALL_NEW div_mod_tac ctxt |
191 ObjectLogic.full_atomize_tac i, |
158 THEN_ALL_NEW splits_tac ctxt |
192 div_mod_tac ctxt i, |
159 THEN_ALL_NEW simp_tac ss |
193 splits_tac ctxt i, |
160 THEN_ALL_NEW eta_long_tac |
194 simp_tac ss i, |
161 THEN_ALL_NEW nat_to_int_tac ctxt |
195 eta_beta_tac ctxt i, |
162 THEN_ALL_NEW (TRY o thin_prems_tac (is_relevant ctxt)) |
196 nat_to_int_tac ctxt i, |
163 THEN_ALL_NEW core_cooper_tac ctxt |
197 thin_prems_tac (is_relevant ctxt) i] |
164 THEN_ALL_NEW finish_tac elim |
198 THEN core_cooper_tac ctxt i THEN finish_tac elim i |
|
199 end; |
165 end; |
200 |
166 |
201 end; |
167 end; |