author haftmann Thu, 01 May 2014 10:20:20 +0200 changeset 56813 80a5905c1610 parent 56812 baef1c110f12 child 56814 eb8f2a5a57ad
separate ML module
```--- a/src/HOL/Decision_Procs/Approximation.thy	Thu May 01 09:30:36 2014 +0200
+++ b/src/HOL/Decision_Procs/Approximation.thy	Thu May 01 10:20:20 2014 +0200
@@ -3446,138 +3446,8 @@
THEN gen_eval_tac (approximation_conv ctxt) ctxt i))
*} "real number approximation"

-ML {*
-  fun calculated_subterms (@{const Trueprop} \$ t) = calculated_subterms t
-    | calculated_subterms (@{const HOL.implies} \$ _ \$ t) = calculated_subterms t
-    | calculated_subterms (@{term "op <= :: real \<Rightarrow> real \<Rightarrow> bool"} \$ t1 \$ t2) = [t1, t2]
-    | calculated_subterms (@{term "op < :: real \<Rightarrow> real \<Rightarrow> bool"} \$ t1 \$ t2) = [t1, t2]
-    | calculated_subterms (@{term "op : :: real \<Rightarrow> real set \<Rightarrow> bool"} \$ t1 \$
-                           (@{term "atLeastAtMost :: real \<Rightarrow> real \<Rightarrow> real set"} \$ t2 \$ t3)) = [t1, t2, t3]
-    | calculated_subterms t = raise TERM ("calculated_subterms", [t])
-
-  fun dest_interpret_form (@{const "interpret_form"} \$ b \$ xs) = (b, xs)
-    | dest_interpret_form t = raise TERM ("dest_interpret_form", [t])
-
-  fun dest_interpret (@{const "interpret_floatarith"} \$ b \$ xs) = (b, xs)
-    | dest_interpret t = raise TERM ("dest_interpret", [t])
-
-
-  fun dest_float (@{const "Float"} \$ m \$ e) =
-    (snd (HOLogic.dest_number m), snd (HOLogic.dest_number e))
-
-  fun dest_ivl (Const (@{const_name "Some"}, _) \$
-                (Const (@{const_name Pair}, _) \$ u \$ l)) = SOME (dest_float u, dest_float l)
-    | dest_ivl (Const (@{const_name "None"}, _)) = NONE
-    | dest_ivl t = raise TERM ("dest_result", [t])
-
-  fun mk_approx' prec t = (@{const "approx'"}
-                         \$ HOLogic.mk_number @{typ nat} prec
-                         \$ t \$ @{term "[] :: (float * float) option list"})
-
-  fun mk_approx_form_eval prec t xs = (@{const "approx_form_eval"}
-                         \$ HOLogic.mk_number @{typ nat} prec
-                         \$ t \$ xs)
-
-  fun float2_float10 prec round_down (m, e) = (
-    let
-      val (m, e) = (if e < 0 then (m,e) else (m * Integer.pow e 2, 0))
-
-      fun frac c p 0 digits cnt = (digits, cnt, 0)
-        | frac c 0 r digits cnt = (digits, cnt, r)
-        | frac c p r digits cnt = (let
-          val (d, r) = Integer.div_mod (r * 10) (Integer.pow (~e) 2)
-        in frac (c orelse d <> 0) (if d <> 0 orelse c then p - 1 else p) r
-                (digits * 10 + d) (cnt + 1)
-        end)
-
-      val sgn = Int.sign m
-      val m = abs m
-
-      val round_down = (sgn = 1 andalso round_down) orelse
-                       (sgn = ~1 andalso not round_down)
-
-      val (x, r) = Integer.div_mod m (Integer.pow (~e) 2)
-
-      val p = ((if x = 0 then prec else prec - (IntInf.log2 x + 1)) * 3) div 10 + 1
-
-      val (digits, e10, r) = if p > 0 then frac (x <> 0) p r 0 0 else (0,0,0)
-
-      val digits = if round_down orelse r = 0 then digits else digits + 1
-
-    in (sgn * (digits + x * (Integer.pow e10 10)), ~e10)
-    end)
-
-  fun mk_result prec (SOME (l, u)) =
-    (let
-      fun mk_float10 rnd x = (let val (m, e) = float2_float10 prec rnd x
-                         in if e = 0 then HOLogic.mk_number @{typ real} m
-                       else if e = 1 then @{term "divide :: real \<Rightarrow> real \<Rightarrow> real"} \$
-                                          HOLogic.mk_number @{typ real} m \$
-                                          @{term "10"}
-                                     else @{term "divide :: real \<Rightarrow> real \<Rightarrow> real"} \$
-                                          HOLogic.mk_number @{typ real} m \$
-                                          (@{term "power 10 :: nat \<Rightarrow> real"} \$
-                                           HOLogic.mk_number @{typ nat} (~e)) end)
-      in @{term "atLeastAtMost :: real \<Rightarrow> real \<Rightarrow> real set"} \$ mk_float10 true l \$ mk_float10 false u end)
-    | mk_result _ NONE = @{term "UNIV :: real set"}
-
-  fun realify t =
-    let
-      val t = Logic.varify_global t
-      val m = map (fn (name, _) => (name, @{typ real})) (Term.add_tvars t [])
-      val t = Term.subst_TVars m t
-    in t end
-
-  fun converted_result t =
-          prop_of t
-       |> HOLogic.dest_Trueprop
-       |> HOLogic.dest_eq |> snd
-
-  fun apply_tactic ctxt term tactic =
-    cterm_of (Proof_Context.theory_of ctxt) term
-    |> Goal.init
-    |> SINGLE tactic
-    |> the |> prems_of |> hd
-
-  fun prepare_form ctxt term = apply_tactic ctxt term (
-      REPEAT (FIRST' [etac @{thm intervalE}, etac @{thm meta_eqE}, rtac @{thm impI}] 1)
-      THEN Subgoal.FOCUS (fn {prems, ...} => reorder_bounds_tac prems 1) ctxt 1
-      THEN DETERM (TRY (filter_prems_tac (K false) 1)))
-
-  fun reify_form ctxt term = apply_tactic ctxt term
-     (Reification.tac ctxt form_equations NONE 1)
-
-  fun approx_form prec ctxt t =
-          realify t
-       |> prepare_form ctxt
-       |> (fn arith_term => reify_form ctxt arith_term
-           |> HOLogic.dest_Trueprop |> dest_interpret_form
-           |> (fn (data, xs) =>
-              mk_approx_form_eval prec data (HOLogic.mk_list @{typ "(float * float) option"}
-                (map (fn _ => @{term "None :: (float * float) option"}) (HOLogic.dest_list xs)))
-           |> approximate ctxt
-           |> HOLogic.dest_list
-           |> curry ListPair.zip (HOLogic.dest_list xs @ calculated_subterms arith_term)
-           |> map (fn (elem, s) => @{term "op : :: real \<Rightarrow> real set \<Rightarrow> bool"} \$ elem \$ mk_result prec (dest_ivl s))
-           |> foldr1 HOLogic.mk_conj))
-
-  fun approx_arith prec ctxt t = realify t
-       |> Thm.cterm_of (Proof_Context.theory_of ctxt)
-       |> Reification.conv ctxt form_equations
-       |> prop_of
-       |> Logic.dest_equals |> snd
-       |> dest_interpret |> fst
-       |> mk_approx' prec
-       |> approximate ctxt
-       |> dest_ivl
-       |> mk_result prec
-
-  fun approx prec ctxt t =
-    if type_of t = @{typ prop} then approx_form prec ctxt t
-    else if type_of t = @{typ bool} then approx_form prec ctxt (@{const Trueprop} \$ t)
-    else approx_arith prec ctxt t
-*}
-
-setup {* Value.add_evaluator ("approximate", approx 30) *}
+ML_file "approximation.ML"
+
+setup {* Value.add_evaluator ("approximate", Approximation.approx 30) *}

end```
```--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Decision_Procs/approximation.ML	Thu May 01 10:20:20 2014 +0200
@@ -0,0 +1,143 @@
+(*  Title:      HOL/Decision_Procs/approximation.ML
+    Author:     Johannes Hoelzl, TU Muenchen
+*)
+
+signature APPROXIMATION =
+sig
+  val approx: int -> Proof.context -> term -> term
+end
+
+structure Approximation: APPROXIMATION =
+struct
+
+fun calculated_subterms (@{const Trueprop} \$ t) = calculated_subterms t
+  | calculated_subterms (@{const HOL.implies} \$ _ \$ t) = calculated_subterms t
+  | calculated_subterms (@{term "op <= :: real \<Rightarrow> real \<Rightarrow> bool"} \$ t1 \$ t2) = [t1, t2]
+  | calculated_subterms (@{term "op < :: real \<Rightarrow> real \<Rightarrow> bool"} \$ t1 \$ t2) = [t1, t2]
+  | calculated_subterms (@{term "op : :: real \<Rightarrow> real set \<Rightarrow> bool"} \$ t1 \$
+                         (@{term "atLeastAtMost :: real \<Rightarrow> real \<Rightarrow> real set"} \$ t2 \$ t3)) = [t1, t2, t3]
+  | calculated_subterms t = raise TERM ("calculated_subterms", [t])
+
+fun dest_interpret_form (@{const "interpret_form"} \$ b \$ xs) = (b, xs)
+  | dest_interpret_form t = raise TERM ("dest_interpret_form", [t])
+
+fun dest_interpret (@{const "interpret_floatarith"} \$ b \$ xs) = (b, xs)
+  | dest_interpret t = raise TERM ("dest_interpret", [t])
+
+
+fun dest_float (@{const "Float"} \$ m \$ e) =
+  (snd (HOLogic.dest_number m), snd (HOLogic.dest_number e))
+
+fun dest_ivl (Const (@{const_name "Some"}, _) \$
+              (Const (@{const_name Pair}, _) \$ u \$ l)) = SOME (dest_float u, dest_float l)
+  | dest_ivl (Const (@{const_name "None"}, _)) = NONE
+  | dest_ivl t = raise TERM ("dest_result", [t])
+
+fun mk_approx' prec t = (@{const "approx'"}
+                       \$ HOLogic.mk_number @{typ nat} prec
+                       \$ t \$ @{term "[] :: (float * float) option list"})
+
+fun mk_approx_form_eval prec t xs = (@{const "approx_form_eval"}
+                       \$ HOLogic.mk_number @{typ nat} prec
+                       \$ t \$ xs)
+
+fun float2_float10 prec round_down (m, e) = (
+  let
+    val (m, e) = (if e < 0 then (m,e) else (m * Integer.pow e 2, 0))
+
+    fun frac c p 0 digits cnt = (digits, cnt, 0)
+      | frac c 0 r digits cnt = (digits, cnt, r)
+      | frac c p r digits cnt = (let
+        val (d, r) = Integer.div_mod (r * 10) (Integer.pow (~e) 2)
+      in frac (c orelse d <> 0) (if d <> 0 orelse c then p - 1 else p) r
+              (digits * 10 + d) (cnt + 1)
+      end)
+
+    val sgn = Int.sign m
+    val m = abs m
+
+    val round_down = (sgn = 1 andalso round_down) orelse
+                     (sgn = ~1 andalso not round_down)
+
+    val (x, r) = Integer.div_mod m (Integer.pow (~e) 2)
+
+    val p = ((if x = 0 then prec else prec - (IntInf.log2 x + 1)) * 3) div 10 + 1
+
+    val (digits, e10, r) = if p > 0 then frac (x <> 0) p r 0 0 else (0,0,0)
+
+    val digits = if round_down orelse r = 0 then digits else digits + 1
+
+  in (sgn * (digits + x * (Integer.pow e10 10)), ~e10)
+  end)
+
+fun mk_result prec (SOME (l, u)) =
+  (let
+    fun mk_float10 rnd x = (let val (m, e) = float2_float10 prec rnd x
+                       in if e = 0 then HOLogic.mk_number @{typ real} m
+                     else if e = 1 then @{term "divide :: real \<Rightarrow> real \<Rightarrow> real"} \$
+                                        HOLogic.mk_number @{typ real} m \$
+                                        @{term "10"}
+                                   else @{term "divide :: real \<Rightarrow> real \<Rightarrow> real"} \$
+                                        HOLogic.mk_number @{typ real} m \$
+                                        (@{term "power 10 :: nat \<Rightarrow> real"} \$
+                                         HOLogic.mk_number @{typ nat} (~e)) end)
+    in @{term "atLeastAtMost :: real \<Rightarrow> real \<Rightarrow> real set"} \$ mk_float10 true l \$ mk_float10 false u end)
+  | mk_result _ NONE = @{term "UNIV :: real set"}
+
+fun realify t =
+  let
+    val t = Logic.varify_global t
+    val m = map (fn (name, _) => (name, @{typ real})) (Term.add_tvars t [])
+    val t = Term.subst_TVars m t
+  in t end
+
+fun converted_result t =
+        prop_of t
+     |> HOLogic.dest_Trueprop
+     |> HOLogic.dest_eq |> snd
+
+fun apply_tactic ctxt term tactic =
+  cterm_of (Proof_Context.theory_of ctxt) term
+  |> Goal.init
+  |> SINGLE tactic
+  |> the |> prems_of |> hd
+
+fun prepare_form ctxt term = apply_tactic ctxt term (
+    REPEAT (FIRST' [etac @{thm intervalE}, etac @{thm meta_eqE}, rtac @{thm impI}] 1)
+    THEN Subgoal.FOCUS (fn {prems, ...} => reorder_bounds_tac prems 1) ctxt 1
+    THEN DETERM (TRY (filter_prems_tac (K false) 1)))
+
+fun reify_form ctxt term = apply_tactic ctxt term
+   (Reification.tac ctxt form_equations NONE 1)
+
+fun approx_form prec ctxt t =
+        realify t
+     |> prepare_form ctxt
+     |> (fn arith_term => reify_form ctxt arith_term
+         |> HOLogic.dest_Trueprop |> dest_interpret_form
+         |> (fn (data, xs) =>
+            mk_approx_form_eval prec data (HOLogic.mk_list @{typ "(float * float) option"}
+              (map (fn _ => @{term "None :: (float * float) option"}) (HOLogic.dest_list xs)))
+         |> approximate ctxt
+         |> HOLogic.dest_list
+         |> curry ListPair.zip (HOLogic.dest_list xs @ calculated_subterms arith_term)
+         |> map (fn (elem, s) => @{term "op : :: real \<Rightarrow> real set \<Rightarrow> bool"} \$ elem \$ mk_result prec (dest_ivl s))
+         |> foldr1 HOLogic.mk_conj))
+
+fun approx_arith prec ctxt t = realify t
+     |> Thm.cterm_of (Proof_Context.theory_of ctxt)
+     |> Reification.conv ctxt form_equations
+     |> prop_of
+     |> Logic.dest_equals |> snd
+     |> dest_interpret |> fst
+     |> mk_approx' prec
+     |> approximate ctxt
+     |> dest_ivl
+     |> mk_result prec
+
+fun approx prec ctxt t =
+  if type_of t = @{typ prop} then approx_form prec ctxt t
+  else if type_of t = @{typ bool} then approx_form prec ctxt (@{const Trueprop} \$ t)
+  else approx_arith prec ctxt t
+
+end;```