| author | wenzelm | 
| Wed, 16 Oct 2024 21:41:05 +0200 | |
| changeset 81177 | 137ea3d464be | 
| 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: 
74631diff
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: 
74631diff
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: 
74631diff
changeset | 26 | |
| 
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
 wenzelm parents: 
74631diff
changeset | 27 | fun argo_ctxt ctxt = | 
| 
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
 wenzelm parents: 
74631diff
changeset | 28 | let | 
| 
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
 wenzelm parents: 
74631diff
changeset | 29 | val ctxt1 = | 
| 
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
 wenzelm parents: 
74631diff
changeset | 30 | if Config.get ctxt trace | 
| 
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
 wenzelm parents: 
74631diff
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: 
74631diff
changeset | 32 | else ctxt | 
| 
df4449c6eff1
explicit option metric_argo_timeout, with reasonable default for Raspberry Pi;
 wenzelm parents: 
74631diff
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: 
74631diff
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: 
74631diff
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 |