author | haftmann |
Thu, 19 Jun 2025 17:15:40 +0200 | |
changeset 82734 | 89347c0cc6a3 |
parent 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*) |
81524
13e9678f2c00
clarified names context: proper context, without consts;
wenzelm
parents:
74736
diff
changeset
|
105 |
let |
13e9678f2c00
clarified names context: proper context, without consts;
wenzelm
parents:
74736
diff
changeset
|
106 |
val names = Variable.names_of ctxt |> Term.declare_free_names (Thm.term_of ct) |
13e9678f2c00
clarified names context: proper context, without consts;
wenzelm
parents:
74736
diff
changeset
|
107 |
val x = Free (#1 (Name.variant "x" names), metric_ty) |
13e9678f2c00
clarified names context: proper context, without consts;
wenzelm
parents:
74736
diff
changeset
|
108 |
in [Thm.cterm_of ctxt x] end |
74627 | 109 |
| points => points) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
110 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
111 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
112 |
(* find all cterms "dist x y" in ct, where x and y have type metric_ty *) |
74627 | 113 |
fun find_dist metric_ty = |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
114 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
115 |
fun find ct = |
74627 | 116 |
(case Thm.term_of ct of |
117 |
\<^Const_>\<open>dist T for _ _\<close> => if T = metric_ty then [ct] else [] |
|
118 |
| _ $ _ => app_union_ct_pair find (Thm.dest_comb ct) |
|
119 |
| Abs _ => |
|
120 |
let val (x, body) = Thm.dest_abs_global ct |
|
121 |
in filter_out (free_in x) (find body) end |
|
122 |
| _ => []) |
|
123 |
in find end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
124 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
125 |
(* find all "x=y", where x has type metric_ty *) |
74627 | 126 |
fun find_eq metric_ty = |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
127 |
let |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
128 |
fun find ct = |
74627 | 129 |
(case Thm.term_of ct of |
130 |
\<^Const_>\<open>HOL.eq T for _ _\<close> => |
|
131 |
if T = metric_ty then [ct] |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
132 |
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
|
133 |
| _ $ _ => app_union_ct_pair find (Thm.dest_comb ct) |
74627 | 134 |
| Abs _ => |
135 |
let val (x, body) = Thm.dest_abs_global ct |
|
136 |
in filter_out (free_in x) (find body) end |
|
137 |
| _ => []) |
|
138 |
in find end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
139 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
140 |
(* 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
|
141 |
fun maxdist_conv ctxt fset_ct ct = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
142 |
let |
74627 | 143 |
val (x, y) = Thm.dest_binop ct |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
144 |
val solve_prems = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
145 |
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
|
146 |
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
|
147 |
val image_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 image_empty image_insert}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
149 |
val dist_refl_sym_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 @{thms dist_commute dist_self}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
151 |
val algebra_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
152 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
153 |
@{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
|
154 |
val insert_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 insert_absorb2 insert_commute}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
156 |
val sup_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 cSup_singleton Sup_insert_insert}) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
158 |
val real_abs_dist_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
159 |
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
|
160 |
val maxdist_thm = |
74629 | 161 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm x\<close> and x and y and s = fset_ct in |
162 |
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> |
|
163 |
for x y :: \<open>'a::metric_space\<close> |
|
164 |
by (fact maxdist_thm)\<close> |
|
165 |
|> solve_prems |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
166 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
167 |
((Conv.rewr_conv maxdist_thm) then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
168 |
(* SUP to Sup *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
169 |
image_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
170 |
dist_refl_sym_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
171 |
algebra_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
172 |
(* eliminate duplicate terms in set *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
173 |
insert_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
174 |
(* Sup to max *) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
175 |
sup_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
176 |
real_abs_dist_simp) ct |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
177 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
178 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
179 |
(* 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
|
180 |
fun metric_eq_conv ctxt fset_ct ct = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
181 |
let |
74627 | 182 |
val (x, y) = Thm.dest_binop ct |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
183 |
val solve_prems = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
184 |
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
|
185 |
addsimps @{thms empty_iff insert_iff}))) |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
186 |
val ball_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
187 |
Simplifier.rewrite (put_simpset HOL_ss ctxt addsimps |
70954 | 188 |
@{thms Set.ball_empty ball_insert}) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
189 |
val dist_refl_sym_simp = |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
190 |
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
|
191 |
val metric_eq_thm = |
74629 | 192 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm x\<close> and x and y and s = fset_ct in |
193 |
lemma \<open>x \<in> s \<Longrightarrow> y \<in> s \<Longrightarrow> x = y \<equiv> \<forall>a\<in>s. dist x a = dist y a\<close> |
|
194 |
for x y :: \<open>'a::metric_space\<close> |
|
195 |
by (fact metric_eq_thm)\<close> |
|
196 |
|> solve_prems |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
197 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
198 |
((Conv.rewr_conv metric_eq_thm) then_conv |
74627 | 199 |
(*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
|
200 |
ball_simp then_conv |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
201 |
dist_refl_sym_simp) ct |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
202 |
end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
203 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
204 |
(* build list of theorems "0 \<le> dist x y" for all dist terms in ct *) |
74629 | 205 |
fun augment_dist_pos metric_ty ct = |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
206 |
let fun inst dist_ct = |
74629 | 207 |
let val (x, y) = Thm.dest_binop dist_ct in |
208 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm x\<close> and x and y |
|
209 |
in lemma \<open>dist x y \<ge> 0\<close> for x y :: \<open>'a::metric_space\<close> by simp\<close> |
|
210 |
end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
211 |
in map inst (find_dist metric_ty ct) end |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
212 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
213 |
(* apply maxdist_conv and metric_eq_conv to the goal, thereby embedding the goal in (\<real>\<^sup>n,dist\<^sub>\<infinity>) *) |
74547 | 214 |
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
|
215 |
let |
74547 | 216 |
val points = find_points ctxt metric_ty goal |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
217 |
val fset_ct = mk_ct_set ctxt metric_ty points |
74627 | 218 |
(*embed all subterms of the form "dist x y" in (\<real>\<^sup>n,dist\<^sub>\<infinity>)*) |
74547 | 219 |
val eq1 = map (maxdist_conv ctxt fset_ct) (find_dist metric_ty goal) |
74627 | 220 |
(*replace point equality by equality of components in \<real>\<^sup>n*) |
74547 | 221 |
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
|
222 |
in |
74545 | 223 |
(K (trace_tac ctxt "Embedding into \<real>\<^sup>n") THEN' |
74547 | 224 |
CONVERSION (Conv.top_sweep_rewrs_conv (eq1 @ eq2) ctxt)) i |
225 |
end) |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
226 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
227 |
(* decision procedure for linear real arithmetic *) |
74630 | 228 |
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
|
229 |
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
|
230 |
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
|
231 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
232 |
fun basic_metric_arith_tac ctxt metric_ty = |
74631 | 233 |
SELECT_GOAL ( |
234 |
dist_refl_sym_tac ctxt 1 THEN |
|
235 |
IF_UNSOLVED (embedding_tac ctxt metric_ty 1) THEN |
|
236 |
IF_UNSOLVED (pre_arith_tac ctxt 1) THEN |
|
237 |
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
|
238 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
239 |
(* 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
|
240 |
if no dist terms are present, equality terms will be used *) |
74627 | 241 |
fun guess_metric ctxt tm = |
242 |
let |
|
243 |
val thy = Proof_Context.theory_of ctxt |
|
244 |
fun find_dist t = |
|
245 |
(case t of |
|
246 |
\<^Const_>\<open>dist T for _ _\<close> => SOME T |
|
247 |
| t1 $ t2 => (case find_dist t1 of NONE => find_dist t2 | some => some) |
|
248 |
| Abs _ => find_dist (#2 (Term.dest_abs_global t)) |
|
249 |
| _ => NONE) |
|
250 |
fun find_eq t = |
|
251 |
(case t of |
|
252 |
\<^Const_>\<open>HOL.eq T for l r\<close> => |
|
253 |
if Sign.of_sort thy (T, \<^sort>\<open>metric_space\<close>) then SOME T |
|
74628 | 254 |
else (case find_eq l of NONE => find_eq r | some => some) |
74627 | 255 |
| t1 $ t2 => (case find_eq t1 of NONE => find_eq t2 | some => some) |
256 |
| Abs _ => find_eq (#2 (Term.dest_abs_global t)) |
|
257 |
| _ => NONE) |
|
258 |
in |
|
259 |
(case find_dist tm of |
|
260 |
SOME ty => ty |
|
261 |
| NONE => |
|
262 |
case find_eq tm of |
|
263 |
SOME ty => ty |
|
264 |
| NONE => error "No Metric Space was found") |
|
265 |
end |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
266 |
|
74627 | 267 |
(* solve \<exists> by proving the goal for a single witness from the metric space *) |
74631 | 268 |
fun exists_tac ctxt = CSUBGOAL (fn (goal, i) => |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
269 |
let |
74631 | 270 |
val _ = \<^assert> (i = 1) |
74627 | 271 |
val metric_ty = guess_metric ctxt (Thm.term_of goal) |
272 |
val points = find_points ctxt metric_ty goal |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
273 |
|
74627 | 274 |
fun try_point_tac ctxt pt = |
275 |
let |
|
276 |
val ex_rule = |
|
277 |
\<^instantiate>\<open>'a = \<open>Thm.ctyp_of_cterm pt\<close> and x = pt in |
|
278 |
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
|
279 |
in |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
280 |
HEADGOAL (resolve_tac ctxt [ex_rule] ORELSE' |
74627 | 281 |
(*variable doesn't occur in body*) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
282 |
resolve_tac ctxt @{thms exI}) THEN |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
283 |
trace_tac ctxt ("Removed existential quantifier, try " ^ @{make_string} pt) THEN |
74631 | 284 |
HEADGOAL (try_points_tac ctxt) |
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
285 |
end |
74631 | 286 |
and try_points_tac ctxt = SUBGOAL (fn (g, _) => |
287 |
if is_exists g then |
|
74627 | 288 |
FIRST (map (try_point_tac ctxt) points) |
74631 | 289 |
else if is_forall g then |
290 |
resolve_tac ctxt @{thms HOL.allI} 1 THEN |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
291 |
Subgoal.FOCUS (fn {context = ctxt', ...} => |
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
292 |
trace_tac ctxt "Removed universal quantifier" THEN |
74631 | 293 |
try_points_tac ctxt' 1) ctxt 1 |
294 |
else basic_metric_arith_tac ctxt metric_ty 1) |
|
295 |
in try_points_tac ctxt 1 end) |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
296 |
|
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
297 |
fun metric_arith_tac ctxt = |
74631 | 298 |
SELECT_GOAL ( |
299 |
(*unfold common definitions to get rid of sets*) |
|
300 |
unfold_tac ctxt 1 THEN |
|
301 |
(*remove all meta-level connectives*) |
|
302 |
IF_UNSOLVED (Object_Logic.full_atomize_tac ctxt 1) THEN |
|
303 |
(*convert goal to prenex form*) |
|
304 |
IF_UNSOLVED (prenex_tac ctxt 1) THEN |
|
305 |
(*and NNF to ?*) |
|
306 |
IF_UNSOLVED (nnf_tac ctxt 1) THEN |
|
307 |
(*turn all universally quantified variables into free variables, by focusing the subgoal*) |
|
308 |
REPEAT (HEADGOAL (resolve_tac ctxt @{thms HOL.allI})) THEN |
|
309 |
IF_UNSOLVED (SUBPROOF (fn {context = ctxt', ...} => |
|
310 |
trace_tac ctxt' "Focused on subgoal" THEN |
|
311 |
exists_tac ctxt' 1) ctxt 1)) |
|
74546 | 312 |
|
70951
678b2abe9f7d
decision procedure for metric spaces, implemented by Maximilian Schäffeler
immler
parents:
diff
changeset
|
313 |
end |