author | wenzelm |
Mon, 11 Sep 2023 19:30:48 +0200 | |
changeset 78659 | b5f3d1051b13 |
parent 74736 | df4449c6eff1 |
child 81524 | 13e9678f2c00 |
permissions | -rw-r--r-- |
74546 | 1 |
(* Title: HOL/Analysis/metric_arith.ML |
2 |
Author: Maximilian Schäffeler (port from HOL Light) |
|
3 |
||
4 |
A decision procedure for metric spaces. |
|
5 |
*) |
|
6 |
||
7 |
signature METRIC_ARITH = |
|
8 |
sig |
|
9 |
val trace: bool Config.T |
|
74736
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
10 |
val argo_timeout: real Config.T |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
11 |
val metric_arith_tac : Proof.context -> int -> tactic |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
12 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
13 |
|
74546 | 14 |
structure Metric_Arith : METRIC_ARITH = |
15 |
struct |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
16 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
17 |
(* apply f to both cterms in ct_pair, merge results *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
18 |
fun app_union_ct_pair f ct_pair = uncurry (union (op aconvc)) (apply2 f ct_pair) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
19 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
20 |
val trace = Attrib.setup_config_bool \<^binding>\<open>metric_trace\<close> (K false) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
21 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
22 |
fun trace_tac ctxt msg = |
74627 | 23 |
if Config.get ctxt trace then print_tac ctxt msg else all_tac |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
24 |
|
74736
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
25 |
val argo_timeout = Attrib.setup_config_real \<^binding>\<open>metric_argo_timeout\<close> (K 20.0) |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
26 |
|
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
27 |
fun argo_ctxt ctxt = |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
28 |
let |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
29 |
val ctxt1 = |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
30 |
if Config.get ctxt trace |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
31 |
then Config.map (Argo_Tactic.trace) (K "basic") ctxt |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
32 |
else ctxt |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
33 |
in Config.put Argo_Tactic.timeout (Config.get ctxt1 argo_timeout) ctxt1 end |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
34 |
|
74627 | 35 |
fun free_in v t = |
36 |
Term.exists_subterm (fn u => u aconv Thm.term_of v) (Thm.term_of t); |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
37 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
38 |
(* build a cterm set with elements cts of type ty *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
39 |
fun mk_ct_set ctxt ty = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
40 |
map Thm.term_of #> |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
41 |
HOLogic.mk_set ty #> |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
42 |
Thm.cterm_of ctxt |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
43 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
44 |
fun prenex_tac ctxt = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
45 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
46 |
val prenex_simps = Proof_Context.get_thms ctxt @{named_theorems metric_prenex} |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
47 |
val prenex_ctxt = put_simpset HOL_basic_ss ctxt addsimps prenex_simps |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
48 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
49 |
simp_tac prenex_ctxt THEN' |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
50 |
K (trace_tac ctxt "Prenex form") |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
51 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
52 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
53 |
fun nnf_tac ctxt = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
54 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
55 |
val nnf_simps = Proof_Context.get_thms ctxt @{named_theorems metric_nnf} |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
56 |
val nnf_ctxt = put_simpset HOL_basic_ss ctxt addsimps nnf_simps |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
57 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
58 |
simp_tac nnf_ctxt THEN' |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
59 |
K (trace_tac ctxt "NNF form") |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
60 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
61 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
62 |
fun unfold_tac ctxt = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
63 |
asm_full_simp_tac (put_simpset HOL_basic_ss ctxt addsimps ( |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
64 |
Proof_Context.get_thms ctxt @{named_theorems metric_unfold})) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
65 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
66 |
fun pre_arith_tac ctxt = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
67 |
simp_tac (put_simpset HOL_basic_ss ctxt addsimps ( |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
68 |
Proof_Context.get_thms ctxt @{named_theorems metric_pre_arith})) THEN' |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
69 |
K (trace_tac ctxt "Prepared for decision procedure") |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
70 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
71 |
fun dist_refl_sym_tac ctxt = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
72 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
73 |
val refl_sym_simps = @{thms dist_self dist_commute add_0_right add_0_left simp_thms} |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
74 |
val refl_sym_ctxt = put_simpset HOL_basic_ss ctxt addsimps refl_sym_simps |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
75 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
76 |
simp_tac refl_sym_ctxt THEN' |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
77 |
K (trace_tac ctxt ("Simplified using " ^ @{make_string} refl_sym_simps)) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
78 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
79 |
|
74627 | 80 |
fun is_exists \<^Const_>\<open>Ex _ for _\<close> = true |
81 |
| is_exists \<^Const_>\<open>Trueprop for t\<close> = is_exists t |
|
82 |
| is_exists _ = false |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
83 |
|
74627 | 84 |
fun is_forall \<^Const_>\<open>All _ for _\<close> = true |
85 |
| is_forall \<^Const_>\<open>Trueprop for t\<close> = is_forall t |
|
86 |
| is_forall _ = false |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
87 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
88 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
89 |
(* find all free points in ct of type metric_ty *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
90 |
fun find_points ctxt metric_ty ct = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
91 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
92 |
fun find ct = |
74627 | 93 |
(if Thm.typ_of_cterm ct = metric_ty then [ct] else []) @ |
94 |
(case Thm.term_of ct of |
|
95 |
_ $ _ => app_union_ct_pair find (Thm.dest_comb ct) |
|
96 |
| Abs _ => |
|
97 |
(*ensure the point doesn't contain the bound variable*) |
|
98 |
let val (x, body) = Thm.dest_abs_global ct |
|
99 |
in filter_out (free_in x) (find body) end |
|
100 |
| _ => []) |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
101 |
in |
74627 | 102 |
(case find ct of |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
103 |
[] => |
74627 | 104 |
(*if no point can be found, invent one*) |
105 |
let val x = singleton (Term.variant_frees (Thm.term_of ct)) ("x", metric_ty) |
|
106 |
in [Thm.cterm_of ctxt (Free x)] end |
|
107 |
| points => points) |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
108 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
109 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
110 |
(* find all cterms "dist x y" in ct, where x and y have type metric_ty *) |
74627 | 111 |
fun find_dist metric_ty = |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
112 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
113 |
fun find ct = |
74627 | 114 |
(case Thm.term_of ct of |
115 |
\<^Const_>\<open>dist T for _ _\<close> => if T = metric_ty then [ct] else [] |
|
116 |
| _ $ _ => app_union_ct_pair find (Thm.dest_comb ct) |
|
117 |
| Abs _ => |
|
118 |
let val (x, body) = Thm.dest_abs_global ct |
|
119 |
in filter_out (free_in x) (find body) end |
|
120 |
| _ => []) |
|
121 |
in find end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
122 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
123 |
(* find all "x=y", where x has type metric_ty *) |
74627 | 124 |
fun find_eq metric_ty = |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
125 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
126 |
fun find ct = |
74627 | 127 |
(case Thm.term_of ct of |
128 |
\<^Const_>\<open>HOL.eq T for _ _\<close> => |
|
129 |
if T = metric_ty then [ct] |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
130 |
else app_union_ct_pair find (Thm.dest_binop ct) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
131 |
| _ $ _ => app_union_ct_pair find (Thm.dest_comb ct) |
74627 | 132 |
| Abs _ => |
133 |
let val (x, body) = Thm.dest_abs_global ct |
|
134 |
in filter_out (free_in x) (find body) end |
|
135 |
| _ => []) |
|
136 |
in find end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
137 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
138 |
(* rewrite ct of the form "dist x y" using maxdist_thm *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
139 |
fun maxdist_conv ctxt fset_ct ct = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
140 |
let |
74627 | 141 |
val (x, y) = Thm.dest_binop ct |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
142 |
val solve_prems = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
143 |
rule_by_tactic ctxt (ALLGOALS (simp_tac (put_simpset HOL_ss ctxt |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
144 |
addsimps @{thms finite.emptyI finite_insert empty_iff insert_iff}))) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
145 |
val image_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
146 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps @{thms image_empty image_insert}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
147 |
val dist_refl_sym_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
148 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps @{thms dist_commute dist_self}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
149 |
val algebra_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
150 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
151 |
@{thms diff_self diff_0_right diff_0 abs_zero abs_minus_cancel abs_minus_commute}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
152 |
val insert_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
153 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps @{thms insert_absorb2 insert_commute}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
154 |
val sup_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
155 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps @{thms cSup_singleton Sup_insert_insert}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
156 |
val real_abs_dist_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
157 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps @{thms real_abs_dist}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
158 |
val maxdist_thm = |
74629 | 159 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm x\<close> and x and y and s = fset_ct in |
160 |
lemma \<open>finite s \<Longrightarrow> x \<in> s \<Longrightarrow> y \<in> s \<Longrightarrow> dist x y \<equiv> SUP a\<in>s. \<bar>dist x a - dist a y\<bar>\<close> |
|
161 |
for x y :: \<open>'a::metric_space\<close> |
|
162 |
by (fact maxdist_thm)\<close> |
|
163 |
|> solve_prems |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
164 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
165 |
((Conv.rewr_conv maxdist_thm) then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
166 |
(* SUP to Sup *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
167 |
image_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
168 |
dist_refl_sym_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
169 |
algebra_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
170 |
(* eliminate duplicate terms in set *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
171 |
insert_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
172 |
(* Sup to max *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
173 |
sup_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
174 |
real_abs_dist_simp) ct |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
175 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
176 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
177 |
(* rewrite ct of the form "x=y" using metric_eq_thm *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
178 |
fun metric_eq_conv ctxt fset_ct ct = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
179 |
let |
74627 | 180 |
val (x, y) = Thm.dest_binop ct |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
181 |
val solve_prems = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
182 |
rule_by_tactic ctxt (ALLGOALS (simp_tac (put_simpset HOL_ss ctxt |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
183 |
addsimps @{thms empty_iff insert_iff}))) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
184 |
val ball_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
185 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps |
70954 | 186 |
@{thms Set.ball_empty ball_insert}) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
187 |
val dist_refl_sym_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
188 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps @{thms dist_commute dist_self}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
189 |
val metric_eq_thm = |
74629 | 190 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm x\<close> and x and y and s = fset_ct in |
191 |
lemma \<open>x \<in> s \<Longrightarrow> y \<in> s \<Longrightarrow> x = y \<equiv> \<forall>a\<in>s. dist x a = dist y a\<close> |
|
192 |
for x y :: \<open>'a::metric_space\<close> |
|
193 |
by (fact metric_eq_thm)\<close> |
|
194 |
|> solve_prems |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
195 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
196 |
((Conv.rewr_conv metric_eq_thm) then_conv |
74627 | 197 |
(*convert \<forall>x\<in>{x\<^sub>1,...,x\<^sub>n}. P x to P x\<^sub>1 \<and> ... \<and> P x\<^sub>n*) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
198 |
ball_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
199 |
dist_refl_sym_simp) ct |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
200 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
201 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
202 |
(* build list of theorems "0 \<le> dist x y" for all dist terms in ct *) |
74629 | 203 |
fun augment_dist_pos metric_ty ct = |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
204 |
let fun inst dist_ct = |
74629 | 205 |
let val (x, y) = Thm.dest_binop dist_ct in |
206 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm x\<close> and x and y |
|
207 |
in lemma \<open>dist x y \<ge> 0\<close> for x y :: \<open>'a::metric_space\<close> by simp\<close> |
|
208 |
end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
209 |
in map inst (find_dist metric_ty ct) end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
210 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
211 |
(* apply maxdist_conv and metric_eq_conv to the goal, thereby embedding the goal in (\<real>\<^sup>n,dist\<^sub>\<infinity>) *) |
74547 | 212 |
fun embedding_tac ctxt metric_ty = CSUBGOAL (fn (goal, i) => |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
213 |
let |
74547 | 214 |
val points = find_points ctxt metric_ty goal |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
215 |
val fset_ct = mk_ct_set ctxt metric_ty points |
74627 | 216 |
(*embed all subterms of the form "dist x y" in (\<real>\<^sup>n,dist\<^sub>\<infinity>)*) |
74547 | 217 |
val eq1 = map (maxdist_conv ctxt fset_ct) (find_dist metric_ty goal) |
74627 | 218 |
(*replace point equality by equality of components in \<real>\<^sup>n*) |
74547 | 219 |
val eq2 = map (metric_eq_conv ctxt fset_ct) (find_eq metric_ty goal) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
220 |
in |
74545 | 221 |
(K (trace_tac ctxt "Embedding into \<real>\<^sup>n") THEN' |
74547 | 222 |
CONVERSION (Conv.top_sweep_rewrs_conv (eq1 @ eq2) ctxt)) i |
223 |
end) |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
224 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
225 |
(* decision procedure for linear real arithmetic *) |
74630 | 226 |
fun lin_real_arith_tac ctxt metric_ty = CSUBGOAL (fn (goal, i) => |
74736
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
227 |
let val dist_thms = augment_dist_pos metric_ty goal |
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
wenzelm
parents:
74631
diff
changeset
|
228 |
in Argo_Tactic.argo_tac (argo_ctxt ctxt) dist_thms i end) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
229 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
230 |
fun basic_metric_arith_tac ctxt metric_ty = |
74631 | 231 |
SELECT_GOAL ( |
232 |
dist_refl_sym_tac ctxt 1 THEN |
|
233 |
IF_UNSOLVED (embedding_tac ctxt metric_ty 1) THEN |
|
234 |
IF_UNSOLVED (pre_arith_tac ctxt 1) THEN |
|
235 |
IF_UNSOLVED (lin_real_arith_tac ctxt metric_ty 1)) |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
236 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
237 |
(* tries to infer the metric space from ct from dist terms, |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
238 |
if no dist terms are present, equality terms will be used *) |
74627 | 239 |
fun guess_metric ctxt tm = |
240 |
let |
|
241 |
val thy = Proof_Context.theory_of ctxt |
|
242 |
fun find_dist t = |
|
243 |
(case t of |
|
244 |
\<^Const_>\<open>dist T for _ _\<close> => SOME T |
|
245 |
| t1 $ t2 => (case find_dist t1 of NONE => find_dist t2 | some => some) |
|
246 |
| Abs _ => find_dist (#2 (Term.dest_abs_global t)) |
|
247 |
| _ => NONE) |
|
248 |
fun find_eq t = |
|
249 |
(case t of |
|
250 |
\<^Const_>\<open>HOL.eq T for l r\<close> => |
|
251 |
if Sign.of_sort thy (T, \<^sort>\<open>metric_space\<close>) then SOME T |
|
74628 | 252 |
else (case find_eq l of NONE => find_eq r | some => some) |
74627 | 253 |
| t1 $ t2 => (case find_eq t1 of NONE => find_eq t2 | some => some) |
254 |
| Abs _ => find_eq (#2 (Term.dest_abs_global t)) |
|
255 |
| _ => NONE) |
|
256 |
in |
|
257 |
(case find_dist tm of |
|
258 |
SOME ty => ty |
|
259 |
| NONE => |
|
260 |
case find_eq tm of |
|
261 |
SOME ty => ty |
|
262 |
| NONE => error "No Metric Space was found") |
|
263 |
end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
264 |
|
74627 | 265 |
(* solve \<exists> by proving the goal for a single witness from the metric space *) |
74631 | 266 |
fun exists_tac ctxt = CSUBGOAL (fn (goal, i) => |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
267 |
let |
74631 | 268 |
val _ = \<^assert> (i = 1) |
74627 | 269 |
val metric_ty = guess_metric ctxt (Thm.term_of goal) |
270 |
val points = find_points ctxt metric_ty goal |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
271 |
|
74627 | 272 |
fun try_point_tac ctxt pt = |
273 |
let |
|
274 |
val ex_rule = |
|
275 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm pt\<close> and x = pt in |
|
276 |
lemma (schematic) \<open>P x \<Longrightarrow> \<exists>x::'a. P x\<close> by (rule exI)\<close> |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
277 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
278 |
HEADGOAL (resolve_tac ctxt [ex_rule] ORELSE' |
74627 | 279 |
(*variable doesn't occur in body*) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
280 |
resolve_tac ctxt @{thms exI}) THEN |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
281 |
trace_tac ctxt ("Removed existential quantifier, try " ^ @{make_string} pt) THEN |
74631 | 282 |
HEADGOAL (try_points_tac ctxt) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
283 |
end |
74631 | 284 |
and try_points_tac ctxt = SUBGOAL (fn (g, _) => |
285 |
if is_exists g then |
|
74627 | 286 |
FIRST (map (try_point_tac ctxt) points) |
74631 | 287 |
else if is_forall g then |
288 |
resolve_tac ctxt @{thms HOL.allI} 1 THEN |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
289 |
Subgoal.FOCUS (fn {context = ctxt', ...} => |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
290 |
trace_tac ctxt "Removed universal quantifier" THEN |
74631 | 291 |
try_points_tac ctxt' 1) ctxt 1 |
292 |
else basic_metric_arith_tac ctxt metric_ty 1) |
|
293 |
in try_points_tac ctxt 1 end) |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
294 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
295 |
fun metric_arith_tac ctxt = |
74631 | 296 |
SELECT_GOAL ( |
297 |
(*unfold common definitions to get rid of sets*) |
|
298 |
unfold_tac ctxt 1 THEN |
|
299 |
(*remove all meta-level connectives*) |
|
300 |
IF_UNSOLVED (Object_Logic.full_atomize_tac ctxt 1) THEN |
|
301 |
(*convert goal to prenex form*) |
|
302 |
IF_UNSOLVED (prenex_tac ctxt 1) THEN |
|
303 |
(*and NNF to ?*) |
|
304 |
IF_UNSOLVED (nnf_tac ctxt 1) THEN |
|
305 |
(*turn all universally quantified variables into free variables, by focusing the subgoal*) |
|
306 |
REPEAT (HEADGOAL (resolve_tac ctxt @{thms HOL.allI})) THEN |
|
307 |
IF_UNSOLVED (SUBPROOF (fn {context = ctxt', ...} => |
|
308 |
trace_tac ctxt' "Focused on subgoal" THEN |
|
309 |
exists_tac ctxt' 1) ctxt 1)) |
|
74546 | 310 |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
311 |
end |