src/HOL/Decision_Procs/approximation.ML
author wenzelm
Sat, 02 Oct 2021 12:59:16 +0200
changeset 74411 20b0b27bc6c7
parent 74397 e80c4cde6064
child 74609 3ef6e38c9847
permissions -rw-r--r--
clarified signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
     1
(*  Title:      HOL/Decision_Procs/approximation.ML
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
     2
    Author:     Johannes Hoelzl, TU Muenchen
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
     3
*)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
     4
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
     5
signature APPROXIMATION =
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
     6
sig
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
     7
  val reify_form: Proof.context -> term -> term
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
     8
  val approx: int -> Proof.context -> term -> term
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
     9
  val approximate: Proof.context -> term -> term
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    10
  val approximation_tac : int -> (string * int) list -> int option -> Proof.context -> int -> tactic
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
    11
end
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
    12
71037
f630f2e707a6 refactor Approximation.thy to use more abstract type of intervals
immler
parents: 71034
diff changeset
    13
structure Approximation =
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
    14
struct
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
    15
60754
02924903a6fd prefer tactics with explicit context;
wenzelm
parents: 60642
diff changeset
    16
fun reorder_bounds_tac ctxt prems i =
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    17
  let
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    18
    fun variable_of_bound \<^Const_>\<open>Trueprop for \<^Const_>\<open>Set.member _ for \<open>Free (name, _)\<close> _\<close>\<close> = name
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    19
      | variable_of_bound \<^Const_>\<open>Trueprop for \<^Const_>\<open>HOL.eq _ for \<open>Free (name, _)\<close> _\<close>\<close> = name
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    20
      | variable_of_bound t = raise TERM ("variable_of_bound", [t])
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    21
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    22
    val variable_bounds
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    23
      = map (`(variable_of_bound o Thm.prop_of)) prems
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    24
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    25
    fun add_deps (name, bnds)
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    26
      = Graph.add_deps_acyclic (name,
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    27
          remove (op =) name (Term.add_free_names (Thm.prop_of bnds) []))
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    28
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    29
    val order = Graph.empty
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    30
                |> fold Graph.new_node variable_bounds
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    31
                |> fold add_deps variable_bounds
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    32
                |> Graph.strong_conn |> map the_single |> rev
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    33
                |> map_filter (AList.lookup (op =) variable_bounds)
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    34
60754
02924903a6fd prefer tactics with explicit context;
wenzelm
parents: 60642
diff changeset
    35
    fun prepend_prem th tac =
02924903a6fd prefer tactics with explicit context;
wenzelm
parents: 60642
diff changeset
    36
      tac THEN resolve_tac ctxt [th RSN (2, @{thm mp})] i
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    37
  in
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    38
    fold prepend_prem order all_tac
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    39
  end
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    40
71034
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
    41
fun approximate ctxt t = case fastype_of t
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    42
   of \<^Type>\<open>bool\<close> =>
71034
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
    43
        Approximation_Computation.approx_bool ctxt t
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    44
    | \<^typ>\<open>float interval option\<close> =>
71034
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
    45
        Approximation_Computation.approx_arith ctxt t
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    46
    | \<^typ>\<open>float interval option list\<close> =>
71034
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
    47
        Approximation_Computation.approx_form_eval ctxt t
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
    48
    | _ => error ("Bad term: " ^ Syntax.string_of_term ctxt t);
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    49
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    50
fun rewrite_interpret_form_tac ctxt prec splitting taylor i st = let
63930
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
    51
    fun lookup_splitting (Free (name, _)) =
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
    52
        (case AList.lookup (op =) splitting name
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    53
          of SOME s => HOLogic.mk_number \<^Type>\<open>nat\<close> s
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
    54
           | NONE => \<^term>\<open>0 :: nat\<close>)
63930
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
    55
      | lookup_splitting t = raise TERM ("lookup_splitting", [t])
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    56
    val vs = nth (Thm.prems_of st) (i - 1)
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    57
             |> Logic.strip_imp_concl
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    58
             |> HOLogic.dest_Trueprop
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    59
             |> Term.strip_comb |> snd |> List.last
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    60
             |> HOLogic.dest_list
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    61
    val p = prec
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    62
            |> HOLogic.mk_number \<^Type>\<open>nat\<close>
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    63
            |> Thm.cterm_of ctxt
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    64
  in case taylor
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    65
  of NONE => let
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    66
       val n = vs |> length
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    67
               |> HOLogic.mk_number \<^Type>\<open>nat\<close>
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    68
               |> Thm.cterm_of ctxt
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    69
       val s = vs
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    70
               |> map lookup_splitting
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    71
               |> HOLogic.mk_list \<^Type>\<open>nat\<close>
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    72
               |> Thm.cterm_of ctxt
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    73
     in
74282
c2ee8d993d6a clarified signature: more scalable operations;
wenzelm
parents: 73019
diff changeset
    74
       (resolve_tac ctxt [Thm.instantiate (TVars.empty,
74290
b2ad24b5a42c more antiquotations;
wenzelm
parents: 74282
diff changeset
    75
           Vars.make [(\<^var>\<open>?n::nat\<close>, n), (\<^var>\<open>?prec::nat\<close>, p), (\<^var>\<open>?ss::nat list\<close>, s)])
60754
02924903a6fd prefer tactics with explicit context;
wenzelm
parents: 60642
diff changeset
    76
            @{thm approx_form}] i
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
    77
        THEN simp_tac (put_simpset (simpset_of \<^context>) ctxt) i) st
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    78
     end
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    79
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    80
   | SOME t =>
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    81
     if length vs <> 1
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    82
     then raise (TERM ("More than one variable used for taylor series expansion", [Thm.prop_of st]))
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    83
     else let
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    84
       val t = t
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    85
            |> HOLogic.mk_number \<^Type>\<open>nat\<close>
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    86
            |> Thm.cterm_of ctxt
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    87
       val s = vs |> map lookup_splitting |> hd
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    88
            |> Thm.cterm_of ctxt
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    89
     in
74282
c2ee8d993d6a clarified signature: more scalable operations;
wenzelm
parents: 73019
diff changeset
    90
       resolve_tac ctxt [Thm.instantiate (TVars.empty,
74290
b2ad24b5a42c more antiquotations;
wenzelm
parents: 74282
diff changeset
    91
            Vars.make [(\<^var>\<open>?s::nat\<close>, s), (\<^var>\<open>?t::nat\<close>, t), (\<^var>\<open>?prec::nat\<close>, p)])
60754
02924903a6fd prefer tactics with explicit context;
wenzelm
parents: 60642
diff changeset
    92
            @{thm approx_tse_form}] i st
59850
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    93
     end
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    94
  end
f339ff48a6ee exposed approximation in ML
eberlm
parents: 59621
diff changeset
    95
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    96
fun calculated_subterms \<^Const_>\<open>Trueprop for t\<close> = calculated_subterms t
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    97
  | calculated_subterms \<^Const_>\<open>implies for _ t\<close> = calculated_subterms t
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    98
  | calculated_subterms \<^Const_>\<open>less_eq \<^Type>\<open>real\<close> for t1 t2\<close> = [t1, t2]
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
    99
  | calculated_subterms \<^Const_>\<open>less \<^Type>\<open>real\<close> for t1 t2\<close> = [t1, t2]
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   100
  | calculated_subterms \<^Const_>\<open>Set.member \<^Type>\<open>real\<close> for
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   101
      t1 \<^Const_>\<open>atLeastAtMost \<^Type>\<open>real\<close> for t2 t3\<close>\<close> = [t1, t2, t3]
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   102
  | calculated_subterms t = raise TERM ("calculated_subterms", [t])
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   103
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   104
fun dest_interpret_form \<^Const_>\<open>interpret_form for b xs\<close> = (b, xs)
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   105
  | dest_interpret_form t = raise TERM ("dest_interpret_form", [t])
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   106
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   107
fun dest_interpret \<^Const_>\<open>interpret_floatarith for b xs\<close> = (b, xs)
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   108
  | dest_interpret t = raise TERM ("dest_interpret", [t])
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   109
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   110
fun dest_interpret_env \<^Const_>\<open>interpret_form for _ xs\<close> = xs
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   111
  | dest_interpret_env \<^Const_>\<open>interpret_floatarith for _ xs\<close> = xs
63930
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   112
  | dest_interpret_env t = raise TERM ("dest_interpret_env", [t])
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   113
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   114
fun dest_float \<^Const_>\<open>Float for m e\<close> = (snd (HOLogic.dest_number m), snd (HOLogic.dest_number e))
63930
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   115
  | dest_float t = raise TERM ("dest_float", [t])
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   116
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   117
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   118
fun dest_ivl \<^Const_>\<open>Some _ for \<^Const_>\<open>Interval _ for \<^Const_>\<open>Pair _ _ for u l\<close>\<close>\<close> =
71037
f630f2e707a6 refactor Approximation.thy to use more abstract type of intervals
immler
parents: 71034
diff changeset
   119
      SOME (dest_float u, dest_float l)
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   120
  | dest_ivl \<^Const_>\<open>None _\<close> = NONE
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   121
  | dest_ivl t = raise TERM ("dest_result", [t])
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   122
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   123
fun mk_approx' prec t =
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   124
  \<^Const>\<open>approx' for \<open>HOLogic.mk_number \<^Type>\<open>nat\<close> prec\<close> t \<^Const>\<open>Nil \<^typ>\<open>float interval option\<close>\<close>\<close>
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   125
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   126
fun mk_approx_form_eval prec t xs =
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   127
  \<^Const>\<open>approx_form_eval for \<open>HOLogic.mk_number \<^Type>\<open>nat\<close> prec\<close> t xs\<close>
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   128
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   129
fun float2_float10 prec round_down (m, e) = (
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   130
  let
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   131
    val (m, e) = (if e < 0 then (m,e) else (m * Integer.pow e 2, 0))
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   132
63930
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   133
    fun frac _ _ 0 digits cnt = (digits, cnt, 0)
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   134
      | frac _ 0 r digits cnt = (digits, cnt, r)
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   135
      | frac c p r digits cnt = (let
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   136
        val (d, r) = Integer.div_mod (r * 10) (Integer.pow (~e) 2)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   137
      in frac (c orelse d <> 0) (if d <> 0 orelse c then p - 1 else p) r
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   138
              (digits * 10 + d) (cnt + 1)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   139
      end)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   140
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   141
    val sgn = Int.sign m
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   142
    val m = abs m
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   143
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   144
    val round_down = (sgn = 1 andalso round_down) orelse
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   145
                     (sgn = ~1 andalso not round_down)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   146
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   147
    val (x, r) = Integer.div_mod m (Integer.pow (~e) 2)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   148
73019
05e2cab9af8b tuned signature -- prefer Isabelle/ML structure Integer;
wenzelm
parents: 71037
diff changeset
   149
    val p = ((if x = 0 then prec else prec - (Integer.log2 x + 1)) * 3) div 10 + 1
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   150
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   151
    val (digits, e10, r) = if p > 0 then frac (x <> 0) p r 0 0 else (0,0,0)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   152
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   153
    val digits = if round_down orelse r = 0 then digits else digits + 1
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   154
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   155
  in (sgn * (digits + x * (Integer.pow e10 10)), ~e10)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   156
  end)
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   157
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   158
fun mk_result prec (SOME (l, u)) =
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   159
  (let
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   160
    fun mk_float10 rnd x = (let val (m, e) = float2_float10 prec rnd x
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   161
                       in if e = 0 then HOLogic.mk_number \<^Type>\<open>real\<close> m
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   162
                     else if e = 1 then \<^Const>\<open>divide \<^Type>\<open>real\<close>\<close> $
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   163
                                        HOLogic.mk_number \<^Type>\<open>real\<close> m $
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
   164
                                        \<^term>\<open>10\<close>
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   165
                                   else \<^Const>\<open>divide \<^Type>\<open>real\<close>\<close> $
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   166
                                        HOLogic.mk_number \<^Type>\<open>real\<close> m $
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
   167
                                        (\<^term>\<open>power 10 :: nat \<Rightarrow> real\<close> $
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   168
                                         HOLogic.mk_number \<^Type>\<open>nat\<close> (~e)) end)
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   169
    in \<^Const>\<open>atLeastAtMost \<^Type>\<open>real\<close> for \<open>mk_float10 true l\<close> \<open>mk_float10 false u\<close>\<close> end)
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
   170
  | mk_result _ NONE = \<^term>\<open>UNIV :: real set\<close>
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   171
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   172
fun realify t =
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   173
  let
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   174
    val t = Logic.varify_global t
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   175
    val m = map (fn (name, _) => (name, \<^Type>\<open>real\<close>)) (Term.add_tvars t [])
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   176
    val t = Term.subst_TVars m t
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   177
  in t end
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   178
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   179
fun apply_tactic ctxt term tactic =
59621
291934bac95e Thm.cterm_of and Thm.ctyp_of operate on local context;
wenzelm
parents: 59582
diff changeset
   180
  Thm.cterm_of ctxt term
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   181
  |> Goal.init
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   182
  |> SINGLE tactic
59582
0fbed69ff081 tuned signature -- prefer qualified names;
wenzelm
parents: 59580
diff changeset
   183
  |> the |> Thm.prems_of |> hd
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   184
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   185
fun preproc_form_conv ctxt =
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   186
  Simplifier.rewrite
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   187
   (put_simpset HOL_basic_ss ctxt addsimps
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
   188
     (Named_Theorems.get ctxt \<^named_theorems>\<open>approximation_preproc\<close>))
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   189
63930
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   190
fun reify_form_conv ctxt ct =
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   191
  let
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   192
    val thm =
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   193
       Reification.conv ctxt @{thms interpret_form.simps interpret_floatarith.simps} ct
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   194
       handle ERROR msg =>
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   195
        cat_error ("Reification failed: " ^ msg)
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   196
          ("Approximation does not support " ^
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   197
            quote (Syntax.string_of_term ctxt (Thm.term_of ct)))
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   198
    fun check_env (Free _) = ()
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   199
      | check_env (Var _) = ()
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   200
      | check_env t =
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   201
          cat_error "Term not supported by approximation:" (Syntax.string_of_term ctxt t)
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   202
    val _ = Thm.rhs_of thm |> Thm.term_of |> dest_interpret_env |> HOLogic.dest_list |> map check_env
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   203
  in thm end
867ca0d92ea2 provide more information on error
immler
parents: 63929
diff changeset
   204
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   205
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   206
fun reify_form_tac ctxt i = CONVERSION (Conv.arg_conv (reify_form_conv ctxt)) i
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   207
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   208
fun prepare_form_tac ctxt i =
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   209
  REPEAT (FIRST' [eresolve_tac ctxt @{thms intervalE},
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   210
    eresolve_tac ctxt @{thms meta_eqE},
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   211
    resolve_tac ctxt @{thms impI}] i)
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   212
  THEN Subgoal.FOCUS (fn {prems, context = ctxt', ...} => reorder_bounds_tac ctxt' prems i) ctxt i
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   213
  THEN DETERM (TRY (filter_prems_tac ctxt (K false) i))
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   214
  THEN CONVERSION (Conv.arg_conv (preproc_form_conv ctxt)) i
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   215
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   216
fun prepare_form ctxt term = apply_tactic ctxt term (prepare_form_tac ctxt 1)
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   217
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   218
fun apply_reify_form ctxt t = apply_tactic ctxt t (reify_form_tac ctxt 1)
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   219
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   220
fun reify_form ctxt t = HOLogic.mk_Trueprop t
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   221
  |> prepare_form ctxt
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   222
  |> apply_reify_form ctxt
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   223
  |> HOLogic.dest_Trueprop
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   224
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   225
fun approx_form prec ctxt t =
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   226
        realify t
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   227
     |> prepare_form ctxt
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   228
     |> (fn arith_term => apply_reify_form ctxt arith_term
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   229
         |> HOLogic.dest_Trueprop
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   230
         |> dest_interpret_form
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   231
         |> (fn (data, xs) =>
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   232
            mk_approx_form_eval prec data (HOLogic.mk_list \<^typ>\<open>float interval option\<close>
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   233
              (map (fn _ => \<^Const>\<open>None \<^typ>\<open>float interval option\<close>\<close>) (HOLogic.dest_list xs)))
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   234
         |> approximate ctxt
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   235
         |> HOLogic.dest_list
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   236
         |> curry ListPair.zip (HOLogic.dest_list xs @ calculated_subterms arith_term)
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   237
         |> map (fn (elem, s) => \<^Const>\<open>Set.member \<^Type>\<open>real\<close> for elem \<open>mk_result prec (dest_ivl s)\<close>\<close>)
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   238
         |> foldr1 HOLogic.mk_conj))
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   239
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   240
fun approx_arith prec ctxt t = realify t
59621
291934bac95e Thm.cterm_of and Thm.ctyp_of operate on local context;
wenzelm
parents: 59582
diff changeset
   241
     |> Thm.cterm_of ctxt
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   242
     |> (preproc_form_conv ctxt then_conv reify_form_conv ctxt)
59582
0fbed69ff081 tuned signature -- prefer qualified names;
wenzelm
parents: 59580
diff changeset
   243
     |> Thm.prop_of
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   244
     |> Logic.dest_equals |> snd
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   245
     |> dest_interpret |> fst
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   246
     |> mk_approx' prec
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   247
     |> approximate ctxt
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   248
     |> dest_ivl
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   249
     |> mk_result prec
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   250
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   251
fun approx prec ctxt t =
74397
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   252
  if type_of t = \<^Type>\<open>prop\<close> then approx_form prec ctxt t
e80c4cde6064 clarified antiquotations;
wenzelm
parents: 74290
diff changeset
   253
  else if type_of t = \<^Type>\<open>bool\<close> then approx_form prec ctxt \<^Const>\<open>Trueprop for t\<close>
56813
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   254
  else approx_arith prec ctxt t
80a5905c1610 separate ML module
haftmann
parents:
diff changeset
   255
56923
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   256
fun approximate_cmd modes raw_t state =
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   257
  let
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   258
    val ctxt = Toplevel.context_of state;
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   259
    val t = Syntax.read_term ctxt raw_t;
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   260
    val t' = approx 30 ctxt t;
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   261
    val ty' = Term.type_of t';
70308
7f568724d67e clarified signature;
wenzelm
parents: 69597
diff changeset
   262
    val ctxt' = Proof_Context.augment t' ctxt;
59174
wenzelm
parents: 58893
diff changeset
   263
  in
wenzelm
parents: 58893
diff changeset
   264
    Print_Mode.with_modes modes (fn () =>
56923
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   265
      Pretty.block [Pretty.quote (Syntax.pretty_term ctxt' t'), Pretty.fbrk,
59174
wenzelm
parents: 58893
diff changeset
   266
        Pretty.str "::", Pretty.brk 1, Pretty.quote (Syntax.pretty_typ ctxt' ty')]) ()
wenzelm
parents: 58893
diff changeset
   267
  end |> Pretty.writeln;
56923
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   268
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   269
val opt_modes =
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
   270
  Scan.optional (\<^keyword>\<open>(\<close> |-- Parse.!!! (Scan.repeat1 Parse.name --| \<^keyword>\<open>)\<close>)) [];
56923
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   271
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   272
val _ =
69597
ff784d5a5bfb isabelle update -u control_cartouches;
wenzelm
parents: 67613
diff changeset
   273
  Outer_Syntax.command \<^command_keyword>\<open>approximate\<close> "print approximation of term"
56923
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   274
    (opt_modes -- Parse.term
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   275
      >> (fn (modes, t) => Toplevel.keep (approximate_cmd modes t)));
c062543d380e prefer separate command for approximation
haftmann
parents: 56813
diff changeset
   276
71034
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
   277
fun approximation_tac prec splitting taylor ctxt =
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
   278
  prepare_form_tac ctxt
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
   279
  THEN' reify_form_tac ctxt
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
   280
  THEN' rewrite_interpret_form_tac ctxt prec splitting taylor
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
   281
  THEN' CONVERSION (Approximation_Computation.approx_conv ctxt)
e0755162093f replace approximation oracle by less ad-hoc @{computation}s
immler
parents: 70308
diff changeset
   282
  THEN' resolve_tac ctxt [TrueI]
63929
b673e7221b16 approximation: rewrite for reduction to base expressions
immler
parents: 62969
diff changeset
   283
62391
1658fc9b2618 more canonical names
nipkow
parents: 60754
diff changeset
   284
end;