src/HOL/Real_Asymp/lazy_eval.ML
author wenzelm
Wed, 15 Aug 2018 16:15:23 +0200
changeset 68753 b0ed78ffa4d9
parent 68630 c55f6f0b3854
permissions -rw-r--r--
removed obsolete RC tags;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
68630
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     1
signature LAZY_EVAL = sig
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     3
datatype pat = AnyPat of indexname | ConsPat of (string * pat list)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     4
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     5
type constructor = string * int
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     6
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     7
type equation = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     8
    function : term, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     9
    thm : thm, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    10
    rhs : term, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    11
    pats : pat list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    12
  }
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    13
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    14
type eval_ctxt' = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    15
    equations : equation list, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    16
    constructors : constructor list,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    17
    pctxt : Proof.context, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    18
    facts : thm Net.net,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    19
    verbose : bool
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    20
  }
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    21
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    22
type eval_hook = eval_ctxt' -> term -> (term * conv) option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    23
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    24
type eval_ctxt = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    25
    ctxt : eval_ctxt', 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    26
    hooks : eval_hook list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    27
  }
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    28
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    29
val is_constructor_name : constructor list -> string -> bool
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    30
val constructor_arity : constructor list -> string -> int option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    31
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    32
val mk_eval_ctxt : Proof.context -> constructor list -> thm list -> eval_ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    33
val add_facts : thm list -> eval_ctxt -> eval_ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    34
val get_facts : eval_ctxt -> thm list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    35
val get_ctxt : eval_ctxt -> Proof.context
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    36
val add_hook : eval_hook -> eval_ctxt -> eval_ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    37
val get_verbose : eval_ctxt -> bool
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    38
val set_verbose : bool -> eval_ctxt -> eval_ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    39
val get_constructors : eval_ctxt -> constructor list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    40
val set_constructors : constructor list -> eval_ctxt -> eval_ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    41
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    42
val whnf : eval_ctxt -> term -> term * conv
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    43
val match : eval_ctxt -> pat -> term -> 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    44
  (indexname * term) list option -> (indexname * term) list option * term * conv
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    45
val match_all : eval_ctxt -> pat list -> term list -> 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    46
  (indexname * term) list option -> (indexname * term) list option * term list * conv
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    47
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    48
end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    49
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    50
structure Lazy_Eval : LAZY_EVAL = struct
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    51
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    52
datatype pat = AnyPat of indexname | ConsPat of (string * pat list)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    53
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    54
type constructor = string * int
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    55
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    56
type equation = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    57
    function : term, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    58
    thm : thm, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    59
    rhs : term, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    60
    pats : pat list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    61
  }
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    62
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    63
type eval_ctxt' = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    64
    equations : equation list, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    65
    constructors : constructor list,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    66
    pctxt : Proof.context, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    67
    facts : thm Net.net,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    68
    verbose : bool
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    69
  }
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    70
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    71
type eval_hook = eval_ctxt' -> term -> (term * conv) option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    72
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    73
type eval_ctxt = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    74
    ctxt : eval_ctxt', 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    75
    hooks : eval_hook list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    76
  }
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    77
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    78
fun add_hook h ({hooks, ctxt} : eval_ctxt) = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    79
  {hooks = h :: hooks, ctxt = ctxt} : eval_ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    80
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    81
fun get_verbose {ctxt = {verbose, ...}, ...} = verbose
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    82
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    83
fun set_verbose b ({ctxt = {equations, pctxt, facts, constructors, ...}, hooks} : eval_ctxt) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    84
  {ctxt = {equations = equations, pctxt = pctxt, facts = facts, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    85
   constructors = constructors, verbose = b}, hooks = hooks}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    86
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    87
fun get_constructors ({ctxt = {constructors, ...}, ...} : eval_ctxt) = constructors
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    88
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    89
fun set_constructors cs ({ctxt = {equations, pctxt, facts, verbose, ...}, hooks} : eval_ctxt) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    90
  {ctxt = {equations = equations, pctxt = pctxt, facts = facts, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    91
   verbose = verbose, constructors = cs}, hooks = hooks}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    92
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    93
type constructor = string * int
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    94
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    95
val is_constructor_name = member (op = o apsnd fst)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    96
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    97
val constructor_arity = AList.lookup op =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    98
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    99
fun stream_pat_of_term _ (Var v) = AnyPat (fst v)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   100
  | stream_pat_of_term constructors t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   101
      case strip_comb t of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   102
        (Const (c, _), args) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   103
          (case constructor_arity constructors c of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   104
             NONE => raise TERM ("Not a valid pattern.", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   105
           | SOME n => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   106
               if length args = n then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   107
                 ConsPat (c, map (stream_pat_of_term constructors) args)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   108
               else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   109
                 raise TERM ("Not a valid pattern.", [t]))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   110
      | _ => raise TERM ("Not a valid pattern.", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   111
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   112
fun analyze_eq constructors thm = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   113
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   114
    val ((f, pats), rhs) = thm |> Thm.concl_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   115
      apfst (strip_comb #> apsnd (map (stream_pat_of_term constructors)))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   116
    handle TERM _ => raise THM ("Not a valid function equation.", 0, [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   117
  in 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   118
    {function = f, thm = thm RS @{thm eq_reflection}, rhs = rhs, pats = pats} : equation
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   119
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   120
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   121
fun mk_eval_ctxt ctxt (constructors : constructor list) thms : eval_ctxt = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   122
    ctxt = {
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   123
        equations = map (analyze_eq constructors) thms, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   124
        facts = Net.empty, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   125
        verbose = false,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   126
        pctxt = ctxt,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   127
        constructors = constructors
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   128
      }, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   129
      hooks = []
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   130
    }
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   131
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   132
fun add_facts facts' {ctxt = {equations, pctxt, facts, verbose, constructors}, hooks} =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   133
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   134
    val eq = op = o apply2 Thm.prop_of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   135
    val facts' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   136
      fold (fn thm => fn net => Net.insert_term eq (Thm.prop_of thm, thm) net
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   137
        handle Net.INSERT => net) facts' facts
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   138
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   139
    {ctxt = {equations = equations, pctxt = pctxt, facts = facts', 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   140
       verbose = verbose, constructors = constructors}, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   141
     hooks = hooks}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   142
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   143
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   144
val get_facts = Net.content o #facts o #ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   145
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   146
val get_ctxt = (#pctxt o #ctxt : eval_ctxt -> Proof.context)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   147
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   148
fun find_eqs (eval_ctxt : eval_ctxt) f = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   149
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   150
    fun eq_const (Const (c, _)) (Const (c', _)) = c = c'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   151
      | eq_const _ _ = false
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   152
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   153
    map_filter (fn eq => if eq_const f (#function eq) then SOME eq else NONE) 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   154
      (#equations (#ctxt eval_ctxt))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   155
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   156
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   157
datatype ('a, 'b) either = Inl of 'a | Inr of 'b
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   158
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   159
fun whnf (ctxt : eval_ctxt) t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   160
      case whnf_aux1 ctxt (Envir.beta_norm t) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   161
        (t', conv) => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   162
          if t aconv t' then 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   163
            (t', conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   164
          else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   165
            case whnf ctxt t' of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   166
              (t'', conv') => (t'', conv then_conv conv')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   167
  
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   168
and whnf_aux1 (ctxt as {hooks, ctxt = ctxt'}) t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   169
      case get_first (fn h => h ctxt' t) hooks of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   170
        NONE => whnf_aux2 ctxt t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   171
      | SOME (t', conv) => case whnf ctxt t' of (t'', conv') => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   172
          (t'', conv then_conv conv')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   173
and whnf_aux2 ctxt t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   174
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   175
    val (f, args) = strip_comb t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   176
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   177
    fun instantiate table (Var (x, _)) = the (AList.lookup op = table x)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   178
      | instantiate table (s $ t) = instantiate table s $ instantiate table t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   179
      | instantiate _ t = t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   180
    fun apply_eq {thm, rhs, pats, ...} conv args = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   181
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   182
        val (table, args', conv') = match_all ctxt pats args (SOME [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   183
      in (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   184
        case table of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   185
          SOME _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   186
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   187
              val thy = Proof_Context.theory_of (get_ctxt ctxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   188
              val t' = list_comb (f, args')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   189
              val lhs = Thm.term_of (Thm.lhs_of thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   190
              val env = Pattern.match thy (lhs, t') (Vartab.empty, Vartab.empty)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   191
              val rhs = Thm.term_of (Thm.rhs_of thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   192
              val rhs = Envir.subst_term env rhs |> Envir.beta_norm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   193
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   194
              Inr (rhs, conv then_conv conv' then_conv Conv.rewr_conv thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   195
            end 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   196
              handle Pattern.MATCH => Inl (args', conv then_conv conv'))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   197
        | NONE => Inl (args', conv then_conv conv'))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   198
       end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   199
    
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   200
    fun apply_eqs [] args conv = (list_comb (f, args), conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   201
      | apply_eqs (eq :: ctxt) args conv =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   202
          (case apply_eq eq conv args of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   203
             Inr res => res
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   204
           | Inl (args', conv) => apply_eqs ctxt args' conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   205
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   206
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   207
    case f of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   208
      Const (f', _) => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   209
        if is_constructor_name (get_constructors ctxt) f' then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   210
          (t, Conv.all_conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   211
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   212
          apply_eqs (find_eqs ctxt f) args Conv.all_conv
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   213
    | _ => (t, Conv.all_conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   214
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   215
and match_all ctxt pats args table =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   216
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   217
    fun match_all' [] [] acc conv table = (table, rev acc, conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   218
      | match_all' (_ :: pats) (arg :: args) acc conv NONE =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   219
        match_all' pats args (arg :: acc) (Conv.fun_conv conv) NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   220
      | match_all' (pat :: pats) (arg :: args) acc conv (SOME table) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   221
          let 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   222
            val (table', arg', conv') = match ctxt pat arg (SOME table)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   223
            val conv = Conv.combination_conv conv conv'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   224
            val acc = arg' :: acc
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   225
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   226
            match_all' pats args acc conv table'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   227
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   228
      | match_all' _ _ _ _ _ = raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   229
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   230
    if length pats = length args then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   231
      match_all' pats args [] Conv.all_conv table
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   232
    else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   233
      (NONE, args, Conv.all_conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   234
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   235
and match _ _ t NONE = (NONE, t, Conv.all_conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   236
  | match _ (AnyPat v) t (SOME table) = (SOME ((v, t) :: table), t, Conv.all_conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   237
  | match ctxt (ConsPat (c, pats)) t (SOME table) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   238
      let 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   239
        val (t', conv) = whnf ctxt t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   240
        val (f, args) = strip_comb t'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   241
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   242
        case f of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   243
          Const (c', _) => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   244
            if c = c' then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   245
              case match_all ctxt pats args (SOME table) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   246
                (table, args', conv') => (table, list_comb (f, args'), conv then_conv conv')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   247
            else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   248
              (NONE, t', conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   249
          | _ => (NONE, t', conv)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   250
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   251
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   252
end