src/HOL/Real_Asymp/multiseries_expansion.ML
author Manuel Eberl <eberlm@in.tum.de>
Sun, 15 Jul 2018 14:46:57 +0200
changeset 68630 c55f6f0b3854
child 69064 5840724b1d71
permissions -rw-r--r--
Added Real_Asymp package
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 MULTISERIES_EXPANSION = 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
type expansion_thm = thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     4
type trimmed_thm = thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     5
type expr = Exp_Log_Expression.expr
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     6
type basis = Asymptotic_Basis.basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     7
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     8
datatype trim_mode = Simple_Trim | Pos_Trim | Neg_Trim | Sgn_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
     9
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    10
datatype zeroness = IsZero | IsNonZero | IsPos | IsNeg
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    11
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    12
datatype intyness = Nat of thm | Neg_Nat of thm | No_Nat
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    13
datatype parity = Even of thm | Odd of thm | Unknown_Parity
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    14
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    15
datatype limit =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    16
   Zero_Limit of bool option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    17
 | Finite_Limit of term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    18
 | Infinite_Limit of bool option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    19
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    20
datatype trim_result =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    21
    Trimmed of zeroness * trimmed_thm option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    22
  | Aborted of order
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
val get_intyness : Proof.context -> cterm -> intyness
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    25
val get_parity : cterm -> parity
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    26
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    27
val get_expansion : thm -> term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    28
val get_coeff : term -> term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    29
val get_exponent : term -> term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    30
val get_expanded_fun : thm -> term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    31
val get_eval : term -> term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    32
val expands_to_hd : thm -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    33
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    34
val mk_eval_ctxt : Proof.context -> Lazy_Eval.eval_ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    35
val expand : Lazy_Eval.eval_ctxt -> expr -> basis -> expansion_thm * basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    36
val expand_term : Lazy_Eval.eval_ctxt -> term -> basis -> expansion_thm * basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    37
val expand_terms : Lazy_Eval.eval_ctxt -> term list -> basis -> expansion_thm list * basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    38
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    39
val limit_of_expansion : bool * bool -> Lazy_Eval.eval_ctxt -> thm * basis -> limit * thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    40
val compute_limit : Lazy_Eval.eval_ctxt -> term -> limit * thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    41
val compare_expansions : 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    42
  Lazy_Eval.eval_ctxt -> expansion_thm * expansion_thm * basis -> 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    43
    order * thm * expansion_thm * expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    44
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    45
(* TODO DEBUG *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    46
datatype comparison_result =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    47
  Cmp_Dominated of order * thm list * zeroness * trimmed_thm * expansion_thm * expansion_thm 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    48
| Cmp_Asymp_Equiv of thm * thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    49
val compare_expansions' :
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    50
  Lazy_Eval.eval_ctxt ->
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    51
      thm * thm * Asymptotic_Basis.basis ->
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    52
        comparison_result
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
val prove_at_infinity : Lazy_Eval.eval_ctxt -> thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    55
val prove_at_top : Lazy_Eval.eval_ctxt -> thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    56
val prove_at_bot : Lazy_Eval.eval_ctxt -> thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    57
val prove_nhds : Lazy_Eval.eval_ctxt -> thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    58
val prove_at_0 : Lazy_Eval.eval_ctxt -> thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    59
val prove_at_left_0 : Lazy_Eval.eval_ctxt -> thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    60
val prove_at_right_0 : Lazy_Eval.eval_ctxt -> thm * basis -> thm
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
val prove_smallo : Lazy_Eval.eval_ctxt -> thm * thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    63
val prove_bigo : Lazy_Eval.eval_ctxt -> thm * thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    64
val prove_bigtheta : Lazy_Eval.eval_ctxt -> thm * thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    65
val prove_asymp_equiv : Lazy_Eval.eval_ctxt -> thm * thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    66
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    67
val prove_asymptotic_relation : Lazy_Eval.eval_ctxt -> thm * thm * basis -> order * thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    68
val prove_eventually_less : Lazy_Eval.eval_ctxt -> thm * thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    69
val prove_eventually_greater : Lazy_Eval.eval_ctxt -> thm * thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    70
val prove_eventually_nonzero : Lazy_Eval.eval_ctxt -> thm * basis -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    71
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    72
val extract_terms : int * bool -> Lazy_Eval.eval_ctxt -> basis -> term -> term * term option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    73
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    74
(* Internal functions *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    75
val check_expansion : Exp_Log_Expression.expr -> expansion_thm -> expansion_thm
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
val zero_expansion : basis -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    78
val const_expansion : Lazy_Eval.eval_ctxt -> basis -> term -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    79
val ln_expansion :
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    80
  Lazy_Eval.eval_ctxt -> trimmed_thm -> expansion_thm -> basis -> expansion_thm * basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    81
val exp_expansion : Lazy_Eval.eval_ctxt -> expansion_thm -> basis -> expansion_thm * basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    82
val powr_expansion :
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    83
  Lazy_Eval.eval_ctxt -> expansion_thm * expansion_thm * basis -> expansion_thm * basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    84
val powr_const_expansion :
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    85
  Lazy_Eval.eval_ctxt -> expansion_thm * term * basis -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    86
val powr_nat_expansion :
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    87
  Lazy_Eval.eval_ctxt -> expansion_thm * expansion_thm * basis -> expansion_thm * basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    88
val power_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * term * basis -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    89
val root_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * term * basis -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    90
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    91
val sgn_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * basis -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    92
val min_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * expansion_thm * basis -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    93
val max_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * expansion_thm * basis -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    94
val arctan_expansion : Lazy_Eval.eval_ctxt -> basis -> expansion_thm -> expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    95
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    96
val ev_zeroness_oracle : Lazy_Eval.eval_ctxt -> term -> thm option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
    97
val zeroness_oracle : bool -> trim_mode option -> Lazy_Eval.eval_ctxt -> term -> zeroness * thm option
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
val whnf_expansion : Lazy_Eval.eval_ctxt -> expansion_thm -> term option * expansion_thm * thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   100
val simplify_expansion : Lazy_Eval.eval_ctxt -> expansion_thm -> expansion_thm 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   101
val simplify_term : Lazy_Eval.eval_ctxt -> term -> term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   102
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   103
val trim_expansion_while_greater :
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   104
  bool -> term list option -> bool -> trim_mode option -> Lazy_Eval.eval_ctxt ->
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   105
    thm * Asymptotic_Basis.basis -> thm * trim_result * (zeroness * thm) list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   106
val trim_expansion : bool -> trim_mode option -> Lazy_Eval.eval_ctxt -> expansion_thm * basis -> 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   107
  expansion_thm * zeroness * trimmed_thm option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   108
val try_drop_leading_term_ex : bool -> Lazy_Eval.eval_ctxt -> expansion_thm -> expansion_thm option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   109
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   110
val try_prove_real_eq : bool -> Lazy_Eval.eval_ctxt -> term * term -> thm option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   111
val try_prove_ev_eq : Lazy_Eval.eval_ctxt -> term * term -> thm option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   112
val prove_compare_expansions : order -> thm list -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   113
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   114
val simplify_trimmed_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * trimmed_thm -> 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   115
  expansion_thm * trimmed_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   116
val retrim_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * basis -> expansion_thm * thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   117
val retrim_pos_expansion : Lazy_Eval.eval_ctxt -> expansion_thm * basis * trimmed_thm ->
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   118
  expansion_thm * thm * trimmed_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   119
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   120
val register_sign_oracle : 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   121
  binding * (Proof.context -> int -> tactic) -> Context.generic -> Context.generic
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   122
val get_sign_oracles :
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   123
  Context.generic -> (string * (Proof.context -> int -> tactic)) list
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   124
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   125
val solve_eval_eq : thm -> thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   126
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   127
end
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
structure Multiseries_Expansion : MULTISERIES_EXPANSION = struct
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
open Asymptotic_Basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   132
open Exp_Log_Expression
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   133
open Lazy_Eval
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   134
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   135
structure Data = Generic_Data
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   136
(
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   137
  type T = (Proof.context -> int -> tactic) Name_Space.table;
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   138
  val empty : T = Name_Space.empty_table "sign oracle tactics";
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   139
  val extend = I;
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   140
  fun merge (tactics1, tactics2) : T = Name_Space.merge_tables (tactics1, tactics2);
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   141
);
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   142
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   143
fun register_sign_oracle (s, tac) ctxt =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   144
  Data.map (Name_Space.define ctxt false (s, tac) #> snd) 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
fun get_sign_oracles ctxt = Name_Space.fold_table cons (Data.get ctxt) []
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 apply_sign_oracles ctxt tac =
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
    val oracles = get_sign_oracles (Context.Proof ctxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   151
    fun tac' {context = ctxt, concl, ...} =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   152
      if Thm.term_of concl = @{term "HOL.Trueprop HOL.False"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   153
        no_tac
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   154
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   155
        FIRST (map (fn tac => HEADGOAL (snd tac ctxt)) oracles)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   156
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   157
    tac THEN_ALL_NEW (Subgoal.FOCUS_PREMS tac' ctxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   158
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   159
    
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   160
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   161
type expansion_thm = thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   162
type trimmed_thm = thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   163
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   164
val dest_fun = dest_comb #> fst
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   165
val dest_arg = dest_comb #> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   166
val concl_of' = Thm.concl_of #> HOLogic.dest_Trueprop
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
fun get_expansion thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   169
  thm |> Thm.concl_of |> HOLogic.dest_Trueprop |> Term.dest_comb |> fst |> Term.dest_comb |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   170
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   171
fun get_expanded_fun thm = thm |> concl_of' |> dest_fun |> dest_fun |> dest_arg
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   172
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   173
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   174
  The following function is useful in order to detect whether a given real constant is
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   175
  an integer, which allows us to use the "f(x) ^ n" operation instead of "f(x) powr n".
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   176
  This usually leads to nicer results.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   177
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   178
datatype intyness = Nat of thm | Neg_Nat of thm | No_Nat
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   179
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   180
fun get_intyness ctxt ct =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   181
  if Thm.typ_of_cterm ct = @{typ Real.real} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   182
    let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   183
      val ctxt' = put_simpset HOL_basic_ss ctxt addsimps @{thms intyness_simps}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   184
      val conv = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   185
        Simplifier.rewrite ctxt then_conv Simplifier.rewrite ctxt'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   186
      fun flip (Nat thm) = Neg_Nat (thm RS @{thm intyness_uminus})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   187
        | flip _ = No_Nat
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   188
      fun get_intyness' ct =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   189
        case Thm.term_of ct of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   190
          @{term "0::real"} => Nat @{thm intyness_0}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   191
        | @{term "1::real"} => Nat @{thm intyness_1}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   192
        | Const (@{const_name numeral}, _) $ _ => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   193
            Nat (Thm.reflexive (Thm.dest_arg ct) RS @{thm intyness_numeral})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   194
        | Const (@{const_name uminus}, _) $ _ => flip (get_intyness' (Thm.dest_arg ct))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   195
        | Const (@{const_name of_nat}, _) $ _ => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   196
            Nat (Thm.reflexive (Thm.dest_arg ct) RS @{thm intyness_of_nat})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   197
        | _ => No_Nat
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   198
      val thm = conv ct
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   199
      val ct' = thm |> Thm.cprop_of |> Thm.dest_equals_rhs
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   200
    in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   201
      case get_intyness' ct' of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   202
        Nat thm' => Nat (Thm.transitive thm thm' RS @{thm HOL.meta_eq_to_obj_eq})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   203
      | Neg_Nat thm' => Neg_Nat (Thm.transitive thm thm' RS @{thm HOL.meta_eq_to_obj_eq})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   204
      | No_Nat => No_Nat
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   205
    end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   206
      handle CTERM _ => No_Nat
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   207
  else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   208
    No_Nat
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   209
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   210
datatype parity = Even of thm | Odd of thm | Unknown_Parity
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   211
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   212
(* TODO: powers *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   213
fun get_parity ct =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   214
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   215
    fun inst thm cts =
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
        val tvs = Term.add_tvars (Thm.concl_of thm) []
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   218
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   219
        case tvs of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   220
          [v] =>
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 thm' = Thm.instantiate ([(v, Thm.ctyp_of_cterm ct)], []) thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   223
              val vs = take (length cts) (rev (Term.add_vars (Thm.concl_of thm') []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   224
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   225
              Thm.instantiate ([], vs ~~ cts) thm'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   226
            end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   227
        | _ => raise THM ("get_parity", 0, [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   228
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   229
    val get_num = Thm.dest_arg o Thm.dest_arg
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   230
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   231
    case Thm.term_of ct of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   232
      Const (@{const_name Groups.zero}, _) => Even (inst @{thm even_zero} [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   233
    | Const (@{const_name Groups.one}, _) => Odd (inst @{thm odd_one} [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   234
    | Const (@{const_name Num.numeral_class.numeral}, _) $ @{term "Num.One"} =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   235
        Odd (inst @{thm odd_Numeral1} [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   236
    | Const (@{const_name Num.numeral_class.numeral}, _) $ (@{term "Num.Bit0"} $ _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   237
        Even (inst @{thm even_numeral} [get_num ct])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   238
    | Const (@{const_name Num.numeral_class.numeral}, _) $ (@{term "Num.Bit1"} $ _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   239
        Odd (inst @{thm odd_numeral} [get_num ct])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   240
    | Const (@{const_name Groups.uminus}, _) $ _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   241
        case get_parity (Thm.dest_arg ct) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   242
          Even thm => Even (@{thm even_uminusI} OF [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   243
        | Odd thm => Odd (@{thm odd_uminusI} OF [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   244
        | _ => Unknown_Parity)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   245
    | Const (@{const_name Groups.plus}, _) $ _ $ _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   246
        case apply2 get_parity (Thm.dest_binop ct) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   247
          (Even thm1, Even thm2) => Even (@{thm even_addI(1)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   248
        | (Odd thm1, Odd thm2) => Even (@{thm even_addI(2)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   249
        | (Even thm1, Odd thm2) => Odd (@{thm odd_addI(1)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   250
        | (Odd thm1, Even thm2) => Odd (@{thm odd_addI(2)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   251
        | _ => Unknown_Parity)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   252
    | Const (@{const_name Groups.minus}, _) $ _ $ _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   253
        case apply2 get_parity (Thm.dest_binop ct) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   254
          (Even thm1, Even thm2) => Even (@{thm even_diffI(1)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   255
        | (Odd thm1, Odd thm2) => Even (@{thm even_diffI(2)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   256
        | (Even thm1, Odd thm2) => Odd (@{thm odd_diffI(1)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   257
        | (Odd thm1, Even thm2) => Odd (@{thm odd_diffI(2)} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   258
        | _ => Unknown_Parity)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   259
    | Const (@{const_name Groups.times}, _) $ _ $ _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   260
        case apply2 get_parity (Thm.dest_binop ct) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   261
          (Even thm1, _) => Even (@{thm even_multI(1)} OF [thm1])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   262
        | (_, Even thm2) => Even (@{thm even_multI(2)} OF [thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   263
        | (Odd thm1, Odd thm2) => Odd (@{thm odd_multI} OF [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   264
        | _ => Unknown_Parity)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   265
    | Const (@{const_name Power.power}, _) $ _ $ _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   266
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   267
          val (a, n) = Thm.dest_binop ct
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   268
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   269
          case get_parity a of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   270
            Odd thm => Odd (inst @{thm odd_powerI} [a, n] OF [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   271
          | _ => Unknown_Parity
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   272
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   273
    | _ => Unknown_Parity
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   274
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   275
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   276
fun simplify_term' facts ctxt =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   277
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   278
    val ctxt = Simplifier.add_prems facts ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   279
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   280
    Thm.cterm_of ctxt #> Simplifier.rewrite ctxt #> 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   281
    Thm.concl_of #> Logic.dest_equals #> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   282
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   283
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   284
fun simplify_term ectxt = simplify_term' (get_facts ectxt) (get_ctxt ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   285
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   286
fun simplify_eval ctxt =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   287
  simplify_term' [] (put_simpset HOL_basic_ss ctxt addsimps @{thms eval_simps})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   288
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   289
datatype zeroness = IsZero | IsNonZero | IsPos | IsNeg
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   290
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   291
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   292
(* Caution: The following functions assume that the given expansion is in normal form already
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   293
   as far as needed. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   294
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   295
(* Returns the leading coefficient of the given expansion. This coefficient is a multiseries. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   296
fun try_get_coeff expr =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   297
  case expr of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   298
    Const (@{const_name MS}, _) $ (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   299
      Const (@{const_name MSLCons}, _) $ (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   300
        Const (@{const_name Pair}, _) $ c $ _) $ _) $ _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   301
      SOME c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   302
  | _ => NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   303
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   304
fun get_coeff expr = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   305
  expr |> dest_comb |> fst |> dest_comb |> snd |> dest_comb |> fst |> dest_comb |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   306
    |> dest_comb |> fst |> dest_comb |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   307
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   308
(* Returns the coefficient of the leading term in the expansion (i.e. a real number) *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   309
fun get_lead_coeff expr =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   310
  case try_get_coeff expr of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   311
    NONE => expr
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   312
  | SOME c => get_lead_coeff c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   313
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   314
(* Returns the exponent (w.r.t. the fastest-growing basis element) of the leading term *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   315
fun get_exponent expr = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   316
  expr |> dest_comb |> fst |> dest_comb |> snd |> dest_comb |> fst |> dest_comb |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   317
    |> dest_comb |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   318
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   319
(* Returns the list of exponents of the leading term *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   320
fun get_exponents exp =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   321
  if fastype_of exp = @{typ real} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   322
    []
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   323
  else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   324
    get_exponent exp :: get_exponents (get_coeff exp)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   325
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   326
(* Returns the function that the expansion corresponds to *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   327
fun get_eval expr =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   328
  if fastype_of expr = @{typ real} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   329
    Abs ("x", @{typ real}, expr)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   330
  else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   331
    expr |> dest_comb |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   332
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   333
val eval_simps = @{thms eval_simps [THEN eq_reflection]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   334
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   335
(* Tries to prove that the given function is eventually zero *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   336
fun ev_zeroness_oracle ectxt t = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   337
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   338
    val ctxt = Lazy_Eval.get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   339
    val goal = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   340
      betapply (@{term "\<lambda>f::real \<Rightarrow> real. eventually (\<lambda>x. f x = 0) at_top"}, t)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   341
      |> HOLogic.mk_Trueprop
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   342
    fun tac {context = ctxt, ...} =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   343
      HEADGOAL (Method.insert_tac ctxt (get_facts ectxt))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   344
      THEN Local_Defs.unfold_tac ctxt eval_simps
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   345
      THEN HEADGOAL (Simplifier.asm_full_simp_tac ctxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   346
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   347
    try (Goal.prove ctxt [] [] goal) tac
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   348
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   349
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   350
(* 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   351
  Encodes the kind of trimming/zeroness checking operation to be performed.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   352
  Simple_Trim only checks for zeroness/non-zeroness. Pos_Trim/Neg_Trim try to prove either
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   353
  zeroness or positivity (resp. negativity). Sgn_Trim tries all three possibilities (positive,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   354
  negative, zero). *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   355
datatype trim_mode = Simple_Trim | Pos_Trim | Neg_Trim | Sgn_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   356
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   357
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   358
  Checks (and proves) whether the given term (assumed to be a real number) is zero, positive,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   359
  or negative, depending on given flags. The "fail" flag determines whether an exception is
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   360
  thrown if this fails.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   361
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   362
fun zeroness_oracle fail mode ectxt exp = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   363
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   364
    val ctxt = Lazy_Eval.get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   365
    val eq = (exp, @{term "0::real"}) |> HOLogic.mk_eq
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   366
    val goal1 = (IsZero, eq |> HOLogic.mk_Trueprop)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   367
    val goal2 = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   368
      case mode of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   369
        SOME Pos_Trim => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   370
          (IsPos, @{term "(<) (0::real)"} $ exp |> HOLogic.mk_Trueprop)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   371
      | SOME Sgn_Trim => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   372
          (IsPos, @{term "(<) (0::real)"} $ exp |> HOLogic.mk_Trueprop)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   373
      | SOME Neg_Trim => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   374
          (IsNeg, betapply (@{term "\<lambda>x. x < (0::real)"}, exp) |> HOLogic.mk_Trueprop)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   375
      | _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   376
          (IsNonZero, eq |> HOLogic.mk_not |> HOLogic.mk_Trueprop)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   377
    val goals =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   378
      (if mode = SOME Sgn_Trim then 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   379
         [(IsNeg, betapply (@{term "\<lambda>x. x < (0::real)"}, exp) |> HOLogic.mk_Trueprop)] 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   380
       else 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   381
         [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   382
    val goals = goal2 :: goals
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   383
    fun tac {context = ctxt, ...} =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   384
      HEADGOAL (Method.insert_tac ctxt (get_facts ectxt))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   385
      THEN Local_Defs.unfold_tac ctxt eval_simps
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   386
      THEN HEADGOAL (apply_sign_oracles ctxt (Simplifier.asm_full_simp_tac ctxt))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   387
    fun prove (res, goal) = try (fn goal => (res, SOME (Goal.prove ctxt [] [] goal tac))) goal
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   388
    fun err () =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   389
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   390
        val mode_msg =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   391
          case mode of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   392
            SOME Simple_Trim => "whether the following constant is zero"
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   393
          | SOME Pos_Trim => "whether the following constant is zero or positive"
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   394
          | SOME Neg_Trim => "whether the following constant is zero or negative"
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   395
          | SOME Sgn_Trim => "the sign of the following constant"
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   396
          | _ => raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   397
        val t = simplify_term' (get_facts ectxt) ctxt exp
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   398
        val _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   399
          if #verbose (#ctxt ectxt) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   400
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   401
              val p = Pretty.str ("real_asymp failed to determine " ^ mode_msg ^ ":")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   402
              val p = Pretty.chunks [p, Pretty.indent 2 (Syntax.pretty_term ctxt t)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   403
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   404
              Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   405
            end else ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   406
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   407
        raise TERM ("zeroness_oracle", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   408
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   409
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   410
    case prove goal1 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   411
      SOME res => res
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   412
    | NONE => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   413
        if mode = NONE then 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   414
          (IsNonZero, NONE)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   415
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   416
          case get_first prove (goal2 :: goals) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   417
            NONE => if fail then err () else (IsNonZero, NONE)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   418
          | SOME res => res
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   419
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   420
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   421
(* Tries to prove a given equality of real numbers. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   422
fun try_prove_real_eq fail ectxt (lhs, rhs) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   423
  case zeroness_oracle false NONE ectxt (@{term "(-) :: real => _"} $ lhs $ rhs) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   424
    (IsZero, SOME thm) => SOME (thm RS @{thm real_eqI})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   425
  | _ => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   426
    if not fail then NONE else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   427
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   428
        val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   429
        val ts = map (simplify_term' (get_facts ectxt) ctxt) [lhs, rhs]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   430
        val _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   431
          if #verbose (#ctxt ectxt) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   432
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   433
              val p = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   434
                Pretty.str ("real_asymp failed to prove that the following two numbers are equal:")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   435
              val p = Pretty.chunks (p :: map (Pretty.indent 2 o Syntax.pretty_term ctxt) ts)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   436
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   437
              Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   438
            end else ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   439
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   440
        raise TERM ("try_prove_real_eq", [lhs, rhs])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   441
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   442
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   443
(* Tries to prove a given eventual equality of real functions. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   444
fun try_prove_ev_eq ectxt (f, g) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   445
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   446
    val t = Envir.beta_eta_contract (@{term "\<lambda>(f::real=>real) g x. f x - g x"} $ f $ g)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   447
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   448
    Option.map (fn thm => thm RS @{thm eventually_diff_zero_imp_eq}) (ev_zeroness_oracle ectxt t)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   449
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   450
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   451
fun real_less a b = @{term "(<) :: real \<Rightarrow> real \<Rightarrow> bool"} $ a $ b
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   452
fun real_eq a b = @{term "(=) :: real \<Rightarrow> real \<Rightarrow> bool"} $ a $ b
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   453
fun real_neq a b = @{term "(\<noteq>) :: real \<Rightarrow> real \<Rightarrow> bool"} $ a $ b
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   454
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   455
(* The hook that is called by the Lazy_Eval module whenever two real numbers have to be compared *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   456
fun real_sgn_hook ({pctxt = ctxt, facts, verbose, ...}) t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   457
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   458
    val get_rhs = Thm.concl_of #> Logic.dest_equals #> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   459
    fun tac {context = ctxt, ...} = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   460
      HEADGOAL (Method.insert_tac ctxt (Net.content facts) 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   461
        THEN' (apply_sign_oracles ctxt (Simplifier.asm_full_simp_tac ctxt)))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   462
    fun prove_first err [] [] =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   463
          if not verbose then raise TERM ("real_sgn_hook", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   464
            else let val _ = err () in raise TERM ("real_sgn_hook", [t]) end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   465
      | prove_first err (goal :: goals) (thm :: thms) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   466
          (case try (Goal.prove ctxt [] [] goal) tac of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   467
             SOME thm' => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   468
               let val thm'' = thm' RS thm in SOME (get_rhs thm'', Conv.rewr_conv thm'') end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   469
           | NONE => prove_first err goals thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   470
      | prove_first _ _ _ = raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   471
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   472
    case t of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   473
      @{term "(=) :: real => _"} $ a $ @{term "0 :: real"} =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   474
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   475
          val goals =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   476
            map (fn c => HOLogic.mk_Trueprop (c a @{term "0 :: real"})) [real_neq, real_eq]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   477
          fun err () = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   478
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   479
              val facts' = Net.content facts
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   480
              val a' = simplify_term' facts' ctxt a
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   481
              val p = Pretty.str ("real_asymp failed to determine whether the following " ^
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   482
                                    "constant is zero: ")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   483
              val p = Pretty.chunks [p, Pretty.indent 2 (Syntax.pretty_term ctxt a')]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   484
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   485
              Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   486
            end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   487
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   488
          prove_first err goals @{thms Eq_FalseI Eq_TrueI}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   489
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   490
    | Const (@{const_name COMPARE}, _) $ a $ b =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   491
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   492
          val goals = map HOLogic.mk_Trueprop [real_less a b, real_less b a, real_eq a b]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   493
          fun err () = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   494
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   495
              val facts' = Net.content facts
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   496
              val (a', b') = apply2 (simplify_term' facts' ctxt) (a, b)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   497
              val p = Pretty.str ("real_asymp failed to compare" ^
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   498
                        "the following two constants: ")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   499
              val p = Pretty.chunks (p :: map (Pretty.indent 2 o Syntax.pretty_term ctxt) [a', b'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   500
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   501
              Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   502
            end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   503
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   504
          prove_first err goals @{thms COMPARE_intros}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   505
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   506
    | _ => NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   507
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   508
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   509
(* 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   510
  Returns the datatype constructors registered for use with the Lazy_Eval package.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   511
  All constructors on which pattern matching is performed need to be registered for evaluation
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   512
  to work. It should be rare for users to add additional ones.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   513
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   514
fun get_constructors ctxt =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   515
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   516
    val thms = Named_Theorems.get ctxt @{named_theorems exp_log_eval_constructor}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   517
    fun go _ [] acc = rev acc
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   518
      | go f (x :: xs) acc =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   519
          case f x of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   520
            NONE => go f xs acc
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   521
          | SOME y => go f xs (y :: acc)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   522
    fun map_option f xs = go f xs []
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   523
    fun dest_constructor thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   524
      case Thm.concl_of thm of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   525
        Const (@{const_name HOL.Trueprop}, _) $
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   526
            (Const (@{const_name REAL_ASYMP_EVAL_CONSTRUCTOR}, _) $ Const (c, T)) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   527
          SOME (c, length (fst (strip_type T)))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   528
     | _ => NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   529
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   530
    thms |> map_option dest_constructor
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   531
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   532
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   533
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   534
  Creates an evaluation context with the correct setup of constructors,  equations, and hooks.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   535
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   536
fun mk_eval_ctxt ctxt =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   537
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   538
    val eval_eqs = (Named_Theorems.get ctxt @{named_theorems real_asymp_eval_eqs})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   539
    val constructors = get_constructors ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   540
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   541
    Lazy_Eval.mk_eval_ctxt ctxt constructors eval_eqs
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   542
    |> add_hook real_sgn_hook
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   543
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   544
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   545
(* A pattern for determining the leading coefficient of a multiseries *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   546
val exp_pat = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   547
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   548
    val anypat = AnyPat ("_", 0)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   549
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   550
    ConsPat (@{const_name MS}, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   551
      [ConsPat (@{const_name MSLCons}, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   552
         [ConsPat (@{const_name Pair}, [anypat, anypat]), anypat]), anypat])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   553
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   554
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   555
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   556
  Evaluates an expansion to (weak) head normal form, so that the leading coefficient and
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   557
  exponent can be read off.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   558
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   559
fun whnf_expansion ectxt thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   560
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   561
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   562
    val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   563
    val (_, _, conv) = match ectxt exp_pat exp (SOME [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   564
    val eq_thm = conv (Thm.cterm_of ctxt exp)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   565
    val exp' = eq_thm |> Thm.concl_of |> Logic.dest_equals |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   566
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   567
    case exp' of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   568
      Const (@{const_name MS}, _) $ (Const (@{const_name MSLCons}, _) $ 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   569
        (Const (@{const_name Pair}, _) $ c $ _) $ _) $ _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   570
          (SOME c, @{thm expands_to_meta_eq_cong} OF [thm, eq_thm], eq_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   571
    | Const (@{const_name MS}, _) $ Const (@{const_name MSLNil}, _) $ _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   572
        (NONE, @{thm expands_to_meta_eq_cong} OF [thm, eq_thm], eq_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   573
    | _ => raise TERM ("whnf_expansion", [exp'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   574
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   575
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   576
fun try_lift_function ectxt (thm, SEmpty) _ = (NONE, thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   577
  | try_lift_function ectxt (thm, basis) cont =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   578
  case whnf_expansion ectxt thm of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   579
    (SOME c, thm, _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   580
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   581
        val f = get_expanded_fun thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   582
        val T = fastype_of c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   583
        val t = Const (@{const_name eval}, T --> @{typ "real \<Rightarrow> real"}) $ c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   584
        val t = Term.betapply (Term.betapply (@{term "\<lambda>(f::real\<Rightarrow>real) g x. f x - g x"}, f), t)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   585
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   586
        case ev_zeroness_oracle ectxt t of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   587
          NONE => (NONE, thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   588
        | SOME zero_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   589
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   590
              val thm' = cont ectxt (thm RS @{thm expands_to_hd''}, tl_basis basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   591
              val thm'' = @{thm expands_to_lift_function} OF [zero_thm, thm']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   592
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   593
              (SOME (lift basis thm''), thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   594
            end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   595
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   596
  | _ => (NONE, thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   597
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   598
(* Turns an expansion theorem into an expansion theorem for the leading coefficient. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   599
fun expands_to_hd thm = thm RS
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   600
  (if fastype_of (get_expansion thm) = @{typ "real ms"} then 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   601
     @{thm expands_to_hd'}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   602
   else 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   603
     @{thm expands_to_hd})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   604
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   605
fun simplify_expansion ectxt thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   606
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   607
    val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   608
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   609
    val eq_thm = Simplifier.rewrite ctxt (Thm.cterm_of ctxt exp)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   610
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   611
    @{thm expands_to_meta_eq_cong} OF [thm, eq_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   612
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   613
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   614
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   615
  Simplifies a trimmed expansion and returns the simplified expansion theorem and
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   616
  the trimming theorem for that simplified expansion.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   617
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   618
fun simplify_trimmed_expansion ectxt (thm, trimmed_thm) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   619
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   620
    val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   621
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   622
    val eq_thm = Simplifier.rewrite ctxt (Thm.cterm_of ctxt exp)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   623
    val trimmed_cong_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   624
      case trimmed_thm |> concl_of' |> dest_fun of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   625
        Const (@{const_name trimmed}, _) => @{thm trimmed_eq_cong}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   626
      | Const (@{const_name trimmed_pos}, _) => @{thm trimmed_pos_eq_cong}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   627
      | Const (@{const_name trimmed_neg}, _) => @{thm trimmed_neg_eq_cong}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   628
      | _ => raise THM ("simplify_trimmed_expansion", 2, [thm, trimmed_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   629
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   630
    (@{thm expands_to_meta_eq_cong} OF [thm, eq_thm], 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   631
      trimmed_cong_thm OF [trimmed_thm, eq_thm])     
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   632
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   633
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   634
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   635
  Re-normalises a trimmed expansion (so that the leading term with its (real) coefficient and
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   636
  all exponents can be read off. This may be necessary after lifting a trimmed expansion to
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   637
  a larger basis.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   638
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   639
fun retrim_expansion ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   640
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   641
    val (c, thm, eq_thm) = whnf_expansion ectxt thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   642
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   643
    case c of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   644
      NONE => (thm, eq_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   645
    | SOME c =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   646
      if fastype_of c = @{typ real} then 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   647
        (thm, eq_thm) 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   648
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   649
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   650
          val c_thm = thm RS @{thm expands_to_hd''}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   651
          val (c_thm', eq_thm') = retrim_expansion ectxt (c_thm, tl_basis basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   652
          val thm = @{thm expands_to_trim_cong} OF [thm, c_thm']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   653
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   654
          (thm, @{thm trim_lift_eq} OF [eq_thm, eq_thm'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   655
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   656
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   657
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   658
fun retrim_pos_expansion ectxt (thm, basis, trimmed_thm) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   659
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   660
    val (thm', eq_thm) = retrim_expansion ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   661
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   662
    (thm', eq_thm, @{thm trimmed_pos_eq_cong} OF [trimmed_thm, eq_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   663
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   664
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   665
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   666
  Tries to determine whether the leading term is (identically) zero and drops it if it is.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   667
  If "fail" is set, an exception is thrown when that term is a real number and zeroness cannot
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   668
  be determined. (Which typically indicates missing facts or case distinctions)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   669
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   670
fun try_drop_leading_term_ex fail ectxt thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   671
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   672
    val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   673
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   674
    if fastype_of exp = @{typ real} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   675
      NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   676
    else if fastype_of (get_coeff exp) = @{typ real} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   677
      case zeroness_oracle fail (SOME Simple_Trim) ectxt (get_coeff exp) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   678
        (IsZero, SOME zero_thm) => SOME (@{thm drop_zero_ms'} OF [zero_thm, thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   679
      | _ => NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   680
    else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   681
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   682
        val c = get_coeff exp
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   683
        val T = fastype_of c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   684
        val t = Const (@{const_name eval}, T --> @{typ "real \<Rightarrow> real"}) $ c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   685
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   686
        case ev_zeroness_oracle ectxt t of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   687
          SOME zero_thm => SOME (@{thm expands_to_drop_zero} OF [zero_thm, thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   688
        | _ => NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   689
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   690
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   691
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   692
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   693
  Tries to drop the leading term of an expansion. If this is not possible, an exception 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   694
  is thrown and an informative error message is printed.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   695
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   696
fun try_drop_leading_term ectxt thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   697
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   698
    fun err () =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   699
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   700
        val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   701
        val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   702
        val c = get_coeff exp
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   703
        val t = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   704
          if fastype_of c = @{typ real} then c else c |> dest_arg
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   705
        val t = simplify_term' (get_facts ectxt) ctxt t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   706
        val _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   707
          if #verbose (#ctxt ectxt) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   708
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   709
              val p = Pretty.str ("real_asymp failed to prove that the following term is zero: ")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   710
              val p = Pretty.chunks [p, Pretty.indent 2 (Syntax.pretty_term ctxt t)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   711
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   712
              Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   713
            end else ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   714
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   715
        raise TERM ("try_drop_leading_term", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   716
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   717
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   718
    case try_drop_leading_term_ex true ectxt thm of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   719
      NONE => err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   720
    | SOME thm => thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   721
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   722
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   723
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   724
datatype trim_result =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   725
    Trimmed of zeroness * trimmed_thm option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   726
  | Aborted of order
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   727
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   728
fun cstrip_assms ct =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   729
  case Thm.term_of ct of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   730
    @{term "(==>)"} $ _ $ _ => cstrip_assms (snd (Thm.dest_implies ct))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   731
  | _ => ct
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   732
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   733
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   734
  Trims an expansion (i.e. drops leading zero terms) and provides a trimmedness theorem.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   735
  Optionally, a list of exponents can be given to instruct the function to only trim until
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   736
  the exponents of the leading term are lexicographically less than (or less than or equal) than
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   737
  the given ones. This is useful to avoid unnecessary trimming.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   738
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   739
  The "strict" flag indicates whether the trimming should already be aborted when the 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   740
  exponents are lexicographically equal or not.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   741
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   742
  The "fail" flag is passed on to the zeroness oracle and determines whether a failure to determine
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   743
  the sign of a real number leads to an exception.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   744
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   745
  "mode" indicates what kind of trimmedness theorem will be returned: Simple_Trim only gives the
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   746
  default trimmedness theorem, whereas Pos_Trim/Neg_Trim/Sgn_Trim will give trimmed_pos or
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   747
  trimmed_neg. Giving "None" as mode will produce no trimmedness theorem; it will only drop 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   748
  leading zero terms until zeroness cannot be proven anymore, upon which it will stop.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   749
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   750
  The main result of the function is the trimmed expansion theorem.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   751
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   752
  The function returns whether the trimming has been aborted or not. If was aborted, either
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   753
  LESS or EQUAL will be returned, indicating whether the exponents of the leading term are
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   754
  now lexicographically smaller or equal to the given ones. In the other case, the zeroness
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   755
  of the leading coefficient is returned (zero, non-zero, positive, negative) together with a
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   756
  trimmedness theorem.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   757
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   758
  Lastly, a list of the exponent comparison results and associated theorems is also returned, so
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   759
  that the caller can reconstruct the result of the lexicographic ordering without doing the
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   760
  exponent comparisons again.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   761
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   762
fun trim_expansion_while_greater strict es fail mode ectxt (thm, basis) = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   763
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   764
    val (_, thm, _) = whnf_expansion ectxt thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   765
    val thm = simplify_expansion ectxt thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   766
    val cexp = thm |> Thm.cprop_of |> cstrip_assms |> Thm.dest_arg |> Thm.dest_fun |> Thm.dest_arg
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   767
    val c = try_get_coeff (get_expansion thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   768
    fun lift_trimmed_thm nz thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   769
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   770
        val cexp = thm |> Thm.cprop_of |> cstrip_assms |> Thm.dest_arg |> Thm.dest_fun |> Thm.dest_arg
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   771
        val lift_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   772
          case nz of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   773
            IsNonZero => @{thm trimmed_eq_cong[rotated, OF _ lift_trimmed]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   774
          | IsPos => @{thm trimmed_pos_eq_cong[rotated, OF _ lift_trimmed_pos]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   775
          | IsNeg => @{thm trimmed_neg_eq_cong[rotated, OF _ lift_trimmed_neg]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   776
          | _ => raise TERM ("Unexpected zeroness result in trim_expansion", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   777
      in 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   778
        Thm.reflexive cexp RS lift_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   779
      end        
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   780
    fun trimmed_real_thm nz = Thm.reflexive cexp RS (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   781
      case nz of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   782
        IsNonZero => @{thm trimmed_eq_cong[rotated, OF _ lift_trimmed[OF trimmed_realI]]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   783
      | IsPos => @{thm trimmed_pos_eq_cong[rotated, OF _ lift_trimmed_pos[OF trimmed_pos_realI]]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   784
      | IsNeg => @{thm trimmed_neg_eq_cong[rotated, OF _ lift_trimmed_neg[OF trimmed_neg_realI]]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   785
      | _ => raise TERM ("Unexpected zeroness result in trim_expansion", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   786
    fun do_trim es =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   787
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   788
        val c = the c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   789
        val T = fastype_of c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   790
        val t = Const (@{const_name eval}, T --> @{typ "real \<Rightarrow> real"}) $ c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   791
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   792
        if T = @{typ real} then (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   793
          case zeroness_oracle fail mode ectxt c of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   794
            (IsZero, SOME zero_thm) => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   795
              trim_expansion_while_greater strict es fail mode ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   796
                (@{thm drop_zero_ms'} OF [zero_thm, thm], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   797
          | (nz, SOME nz_thm) => (thm, Trimmed (nz, SOME (nz_thm RS trimmed_real_thm nz)), [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   798
          | (nz, NONE) => (thm, Trimmed (nz, NONE), []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   799
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   800
          case trim_expansion_while_greater strict (Option.map tl es) fail mode ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   801
                 (thm RS @{thm expands_to_hd''}, tl_basis basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   802
            (c_thm', Aborted ord, thms) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   803
              (@{thm expands_to_trim_cong} OF [thm, c_thm'], Aborted ord, thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   804
          | (c_thm', Trimmed (nz, trimmed_thm), thms) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   805
              let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   806
                val thm = (@{thm expands_to_trim_cong} OF [thm, c_thm'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   807
                fun err () =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   808
                  raise TERM ("trim_expansion: zero coefficient should have been trimmed", [c])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   809
              in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   810
                case (nz, trimmed_thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   811
                  (IsZero, _) => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   812
                    if #verbose (#ctxt ectxt) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   813
                      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   814
                        val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   815
                        val t' = t |> simplify_eval ctxt |> simplify_term' (get_facts ectxt) ctxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   816
                        val p = Pretty.str ("trim_expansion failed to recognise zeroness of " ^
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   817
                          "the following term:")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   818
                        val p = Pretty.chunks [p, Pretty.indent 2 (Syntax.pretty_term ctxt t')]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   819
                        val _ = Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   820
                      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   821
                        err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   822
                      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   823
                    else err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   824
                | (_, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   825
                      (thm, Trimmed (nz, SOME (trimmed_thm RS lift_trimmed_thm nz thm)), thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   826
                | (_, NONE) => (thm, Trimmed (nz, NONE), thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   827
              end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   828
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   829
    val minus = @{term "(-) :: real => real => real"}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   830
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   831
    case (c, es) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   832
      (NONE, _) => (thm, Trimmed (IsZero, NONE), [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   833
    | (SOME c, SOME (e' :: _)) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   834
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   835
          val e = get_exponent (get_expansion thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   836
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   837
          case zeroness_oracle true (SOME Sgn_Trim) ectxt (minus $ e $ e') of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   838
            (IsPos, SOME pos_thm) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   839
              case try_drop_leading_term_ex false ectxt thm of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   840
                SOME thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   841
                  trim_expansion_while_greater strict es fail mode ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   842
              | NONE => do_trim NONE |> @{apply 3(3)} (fn thms => (IsPos, pos_thm) :: thms))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   843
          | (IsNeg, SOME neg_thm) => (thm, Aborted LESS, [(IsNeg, neg_thm)])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   844
          | (IsZero, SOME zero_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   845
              if not strict andalso fastype_of c = @{typ real} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   846
                (thm, Aborted EQUAL, [(IsZero, zero_thm)])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   847
              else (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   848
                case try_drop_leading_term_ex false ectxt thm of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   849
                  SOME thm => trim_expansion_while_greater strict es fail mode ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   850
                | NONE => (do_trim es |> @{apply 3(3)} (fn thms => (IsZero, zero_thm) :: thms)))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   851
          | _ => do_trim NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   852
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   853
    | _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   854
      case try_drop_leading_term_ex false ectxt thm of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   855
          SOME thm => trim_expansion_while_greater strict es fail mode ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   856
        | NONE => do_trim NONE)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   857
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   858
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   859
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   860
  Trims an expansion without any stopping criterion.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   861
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   862
fun trim_expansion fail mode ectxt (thm, basis) = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   863
  case trim_expansion_while_greater false NONE fail mode ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   864
    (thm, Trimmed (zeroness, trimmed_thm), _) => (thm, zeroness, trimmed_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   865
  | _ => raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   866
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   867
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   868
  Determines the sign of an expansion that has already been trimmed.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   869
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   870
fun determine_trimmed_sgn ectxt exp =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   871
  if fastype_of exp = @{typ real} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   872
    (case zeroness_oracle true (SOME Sgn_Trim) ectxt exp of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   873
       (IsPos, SOME thm) => (IsPos, thm RS @{thm trimmed_pos_realI})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   874
     | (IsNeg, SOME thm) => (IsNeg, thm RS @{thm trimmed_neg_realI})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   875
     | _ => raise TERM ("determine_trimmed_sgn", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   876
  else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   877
    let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   878
      val ct = Thm.cterm_of (get_ctxt ectxt) exp
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   879
    in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   880
      (case determine_trimmed_sgn ectxt (get_coeff exp) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   881
         (IsPos, thm) => (IsPos, @{thm lift_trimmed_pos'} OF [thm, Thm.reflexive ct])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   882
       | (IsNeg, thm) => (IsNeg, @{thm lift_trimmed_neg'} OF [thm, Thm.reflexive ct])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   883
       | _ => raise TERM ("determine_trimmed_sgn", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   884
    end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   885
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   886
fun mk_compare_expansions_const T =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   887
      Const (@{const_name compare_expansions}, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   888
        T --> T --> @{typ "cmp_result \<times> real \<times> real"})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   889
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   890
datatype comparison_result =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   891
  Cmp_Dominated of order * thm list * zeroness * trimmed_thm * expansion_thm * expansion_thm 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   892
| Cmp_Asymp_Equiv of thm * thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   893
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   894
fun compare_expansions' _ (thm1, thm2, SEmpty) = Cmp_Asymp_Equiv (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   895
  | compare_expansions' ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   896
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   897
    fun lift_trimmed_thm nz =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   898
      case nz of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   899
        IsPos => @{thm lift_trimmed_pos}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   900
      | IsNeg => @{thm lift_trimmed_neg}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   901
      | _ => raise TERM ("Unexpected zeroness result in compare_expansions'", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   902
    val (e1, e2) = apply2 (get_expansion #> get_exponent) (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   903
    val e = @{term "(-) :: real => _"} $ e1 $ e2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   904
    fun trim thm = trim_expansion true (SOME Sgn_Trim) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   905
    val try_drop = Option.map (whnf_expansion ectxt #> #2) o try_drop_leading_term_ex false ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   906
    fun handle_result ord zeroness trimmed_thm thm1 thm2 =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   907
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   908
        val (e1, e2) = apply2 (get_expansion #> get_exponent) (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   909
        val e = @{term "(-) :: real => _"} $ e1 $ e2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   910
        val mode = if ord = LESS then Neg_Trim else Pos_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   911
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   912
        case zeroness_oracle true (SOME mode) ectxt e of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   913
          (_, SOME e_thm) => Cmp_Dominated (ord, [e_thm], zeroness, trimmed_thm, thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   914
        | _ => raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   915
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   916
    fun recurse e_zero_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   917
      case basis of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   918
        SNE (SSng _) => Cmp_Asymp_Equiv (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   919
      | _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   920
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   921
          val (thm1', thm2') = apply2 (fn thm => thm RS @{thm expands_to_hd''}) (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   922
          val (thm1', thm2') = apply2 (whnf_expansion ectxt #> #2) (thm1', thm2')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   923
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   924
          case compare_expansions' ectxt (thm1', thm2', tl_basis basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   925
            Cmp_Dominated (order, e_thms, zeroness, trimmed_thm, thm1', thm2') =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   926
              Cmp_Dominated (order, e_zero_thm :: e_thms, zeroness,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   927
                trimmed_thm RS lift_trimmed_thm zeroness,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   928
                @{thm expands_to_trim_cong} OF [thm1, thm1'],
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   929
                @{thm expands_to_trim_cong} OF [thm2, thm2'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   930
          | Cmp_Asymp_Equiv (thm1', thm2') => Cmp_Asymp_Equiv
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   931
              (@{thm expands_to_trim_cong} OF [thm1, thm1'],
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   932
                @{thm expands_to_trim_cong} OF [thm2, thm2'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   933
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   934
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   935
    case zeroness_oracle false (SOME Sgn_Trim) ectxt e of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   936
      (IsPos, SOME _) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   937
        case try_drop thm1 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   938
          SOME thm1 => compare_expansions' ectxt (thm1, thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   939
        | NONE => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   940
            case trim thm1 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   941
              (thm1, zeroness, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   942
                handle_result GREATER zeroness trimmed_thm thm1 thm2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   943
            | _ => raise TERM ("compare_expansions", map get_expansion [thm1, thm2])))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   944
    | (IsNeg, SOME _) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   945
        case try_drop thm2 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   946
          SOME thm2 => compare_expansions' ectxt (thm1, thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   947
        | NONE => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   948
            case trim thm2 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   949
              (thm2, zeroness, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   950
                handle_result LESS zeroness trimmed_thm thm1 thm2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   951
            | _ => raise TERM ("compare_expansions", map get_expansion [thm1, thm2])))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   952
    | (IsZero, SOME e_zero_thm) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   953
        case try_drop thm1 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   954
          SOME thm1 => compare_expansions' ectxt (thm1, thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   955
        | NONE => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   956
            case try_drop thm2 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   957
              SOME thm2 => compare_expansions' ectxt (thm1, thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   958
            | NONE => recurse e_zero_thm))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   959
    | _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   960
        case try_drop thm1 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   961
          SOME thm1 => compare_expansions' ectxt (thm1, thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   962
        | NONE => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   963
            case try_drop thm2 of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   964
              SOME thm2 => compare_expansions' ectxt (thm1, thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   965
            | NONE => raise TERM ("compare_expansions", [e1, e2]))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   966
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   967
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   968
(* Uses a list of exponent comparison results to show that compare_expansions has a given result.*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   969
fun prove_compare_expansions ord [thm] = (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   970
      case ord of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   971
        LESS => @{thm compare_expansions_LT_I} OF [thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   972
      | GREATER => @{thm compare_expansions_GT_I} OF [thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   973
      | EQUAL => @{thm compare_expansions_same_exp[OF _ compare_expansions_real]} OF [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   974
  | prove_compare_expansions ord (thm :: thms) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   975
      @{thm compare_expansions_same_exp} OF [thm, prove_compare_expansions ord thms]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   976
  | prove_compare_expansions _ [] = raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   977
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   978
val ev_zero_pos_thm = Eventuallize.eventuallize @{context}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   979
  @{lemma "\<forall>x::real. f x = 0 \<longrightarrow> g x > 0 \<longrightarrow> f x < g x" by auto} NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   980
  OF @{thms _ expands_to_imp_eventually_pos}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   981
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   982
val ev_zero_neg_thm = Eventuallize.eventuallize @{context}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   983
  @{lemma "\<forall>x::real. f x = 0 \<longrightarrow> g x < 0 \<longrightarrow> f x > g x" by auto} NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   984
  OF @{thms _ expands_to_imp_eventually_neg}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   985
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   986
val ev_zero_zero_thm = Eventuallize.eventuallize @{context}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   987
  @{lemma "\<forall>x::real. f x = 0 \<longrightarrow> g x = 0 \<longrightarrow> f x = g x" by auto} NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   988
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   989
fun compare_expansions_trivial ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   990
  case try_prove_ev_eq ectxt (apply2 get_expanded_fun (thm1, thm2)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   991
    SOME thm => SOME (EQUAL, thm, thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   992
  | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   993
      case apply2 (ev_zeroness_oracle ectxt o get_expanded_fun) (thm1, thm2) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   994
        (NONE, NONE) => NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   995
      | (SOME zero1_thm, NONE) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   996
          case trim_expansion true (SOME Sgn_Trim) ectxt (thm2, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   997
            (thm2, IsPos, SOME trimmed2_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   998
              SOME (LESS, ev_zero_pos_thm OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
   999
                [zero1_thm, get_basis_wf_thm basis, thm2, trimmed2_thm], thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1000
          | (thm2, IsNeg, SOME trimmed2_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1001
              SOME (GREATER, ev_zero_neg_thm OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1002
                [zero1_thm, get_basis_wf_thm basis, thm2, trimmed2_thm], thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1003
          | _ => raise TERM ("Unexpected zeroness result in compare_expansions", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1004
      | (NONE, SOME zero2_thm) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1005
          case trim_expansion true (SOME Sgn_Trim) ectxt (thm1, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1006
            (thm1, IsPos, SOME trimmed1_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1007
              SOME (GREATER, ev_zero_pos_thm OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1008
                [zero2_thm, get_basis_wf_thm basis, thm1, trimmed1_thm], thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1009
          | (thm1, IsNeg, SOME trimmed1_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1010
              SOME (LESS, ev_zero_neg_thm OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1011
                [zero2_thm, get_basis_wf_thm basis, thm1, trimmed1_thm], thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1012
          | _ => raise TERM ("Unexpected zeroness result in compare_expansions", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1013
      | (SOME zero1_thm, SOME zero2_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1014
          SOME (EQUAL, ev_zero_zero_thm OF [zero1_thm, zero2_thm] , thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1015
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1016
fun compare_expansions ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1017
  case compare_expansions_trivial ectxt (thm1, thm2, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1018
    SOME res => res
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1019
  | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1020
    let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1021
      val (_, thm1, _) = whnf_expansion ectxt thm1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1022
      val (_, thm2, _) = whnf_expansion ectxt thm2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1023
    in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1024
      case compare_expansions' ectxt (thm1, thm2, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1025
        Cmp_Dominated (order, e_thms, zeroness, trimmed_thm, thm1, thm2) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1026
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1027
            val wf_thm = get_basis_wf_thm basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1028
            val cmp_thm = prove_compare_expansions order e_thms
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1029
            val trimmed_thm' = trimmed_thm RS
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1030
              (if zeroness = IsPos then @{thm trimmed_pos_imp_trimmed}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1031
                 else @{thm trimmed_neg_imp_trimmed})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1032
            val smallo_thm = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1033
              (if order = LESS then @{thm compare_expansions_LT} else @{thm compare_expansions_GT}) OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1034
                [cmp_thm, trimmed_thm', thm1, thm2, wf_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1035
            val thm' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1036
              if zeroness = IsPos then @{thm smallo_trimmed_imp_eventually_less} 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1037
              else @{thm smallo_trimmed_imp_eventually_greater}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1038
            val result_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1039
              thm' OF [smallo_thm, if order = LESS then thm2 else thm1, wf_thm, trimmed_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1040
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1041
            (order, result_thm, thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1042
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1043
       | Cmp_Asymp_Equiv (thm1, thm2) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1044
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1045
            val thm = @{thm expands_to_minus} OF [get_basis_wf_thm basis, thm1, thm2]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1046
            val (order, result_thm) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1047
              case trim_expansion true (SOME Sgn_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1048
                (thm, IsPos, SOME pos_thm) => (GREATER,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1049
                  @{thm expands_to_imp_eventually_gt} OF [get_basis_wf_thm basis, thm, pos_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1050
              | (thm, IsNeg, SOME neg_thm) => (LESS,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1051
                  @{thm expands_to_imp_eventually_lt} OF [get_basis_wf_thm basis, thm, neg_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1052
              | _ => raise TERM ("Unexpected zeroness result in prove_eventually_less", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1053
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1054
            (order, result_thm, thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1055
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1056
    end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1057
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1058
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1059
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1060
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1061
  Throws an exception and prints an error message indicating that the leading term could 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1062
  not be determined to be either zero or non-zero.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1063
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1064
fun raise_trimming_error ectxt thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1065
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1066
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1067
    fun lead_coeff exp =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1068
      if fastype_of exp = @{typ real} then exp else lead_coeff (get_coeff exp)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1069
    val c = lead_coeff (get_expansion thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1070
    fun err () =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1071
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1072
        val t = simplify_term' (get_facts ectxt) ctxt c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1073
        val _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1074
          if #verbose (#ctxt ectxt) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1075
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1076
              val p = Pretty.str 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1077
                ("real_asymp failed to determine whether the following constant is zero:")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1078
              val p = Pretty.chunks [p, Pretty.indent 2 (Syntax.pretty_term ctxt t)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1079
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1080
              Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1081
            end else ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1082
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1083
        raise TERM ("zeroness_oracle", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1084
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1085
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1086
    err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1087
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1088
    
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1089
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1090
(* TODO Here be dragons *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1091
fun solve_eval_eq thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1092
  case try (fn _ => @{thm refl} RS thm) () of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1093
    SOME thm' => thm'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1094
  | NONE => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1095
      case try (fn _ => @{thm eval_real_def} RS thm) () of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1096
        SOME thm' => thm'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1097
      | NONE => @{thm eval_ms.simps} RS thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1098
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1099
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1100
  Returns an expansion theorem for the logarithm of the given expansion.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1101
  May add one additional element to the basis at the end.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1102
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1103
fun ln_expansion _ _ _ SEmpty = raise TERM ("ln_expansion: empty basis", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1104
  | ln_expansion ectxt trimmed_thm thm (SNE basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1105
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1106
    fun trailing_exponent expr (SSng _) = get_exponent expr
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1107
      | trailing_exponent expr (SCons (_, _, tl)) = trailing_exponent (get_coeff expr) tl
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1108
    val e = trailing_exponent (get_expansion thm) basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1109
    fun ln_expansion_aux trimmed_thm zero_thm thm basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1110
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1111
        val t = betapply (@{term "\<lambda>(f::real \<Rightarrow> real) x. f x - 1 :: real"}, get_expanded_fun thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1112
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1113
        case ev_zeroness_oracle ectxt t of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1114
          NONE => ln_expansion_aux' trimmed_thm zero_thm thm basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1115
        | SOME zero_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1116
            @{thm expands_to_ln_eventually_1} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1117
              [get_basis_wf_thm' basis, mk_expansion_level_eq_thm' basis, zero_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1118
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1119
    and ln_expansion_aux' trimmed_thm zero_thm thm (SSng {wf_thm, ...}) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1120
          ( @{thm expands_to_ln} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1121
            [trimmed_thm, wf_thm, thm, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1122
              @{thm expands_to_ln_aux_0} OF [zero_thm, @{thm expands_to_ln_const}]])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1123
          |> solve_eval_eq
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1124
      | ln_expansion_aux' trimmed_thm zero_thm thm (SCons ({wf_thm, ...}, {ln_thm, ...}, basis')) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1125
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1126
            val c_thm = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1127
              ln_expansion_aux (trimmed_thm RS @{thm trimmed_pos_hd_coeff}) zero_thm 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1128
                (expands_to_hd thm) basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1129
            val e = get_exponent (get_expansion thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1130
            val c_thm' =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1131
              case zeroness_oracle true NONE ectxt e of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1132
                (IsZero, SOME thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1133
                  @{thm expands_to_ln_to_expands_to_ln_eval [OF expands_to_ln_aux_0]} OF [thm,c_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1134
              | _ => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1135
                case try_prove_real_eq false ectxt (e, @{term "1::real"}) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1136
                  SOME thm => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1137
                    @{thm expands_to_ln_to_expands_to_ln_eval [OF expands_to_ln_aux_1]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1138
                      OF [thm, wf_thm, c_thm, ln_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1139
                | NONE => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1140
                    @{thm expands_to_ln_to_expands_to_ln_eval [OF expands_to_ln_aux]} 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1141
                      OF [wf_thm, c_thm, ln_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1142
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1143
            (@{thm expands_to_ln} OF [trimmed_thm, wf_thm, thm, c_thm'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1144
            |> solve_eval_eq
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1145
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1146
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1147
    case zeroness_oracle true NONE ectxt e of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1148
      (IsZero, SOME zero_thm) => (ln_expansion_aux trimmed_thm zero_thm thm basis, SNE basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1149
    | _ => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1150
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1151
          val basis' = insert_ln (SNE basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1152
          val lifting = mk_lifting (get_basis_list' basis) basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1153
          val thm' = lift_expands_to_thm lifting thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1154
          val trimmed_thm' = lift_trimmed_pos_thm lifting trimmed_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1155
          val (thm'', eq_thm) = retrim_expansion ectxt (thm', basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1156
          val trimmed_thm'' = @{thm trimmed_pos_eq_cong} OF [trimmed_thm', eq_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1157
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1158
          ln_expansion ectxt trimmed_thm'' thm'' basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1159
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1160
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1161
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1162
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1163
  Handles a possible basis change after expanding exp(c(x)) for an expansion of the form
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1164
  f(x) = c(x) + g(x). Expanding exp(c(x)) may have inserted an additional basis element. If the 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1165
  old basis was b :: bs (i.e. c is an expansion w.r.t. bs) and the updated one is bs' (which
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1166
  agrees with bs except for one additional element b'), we need to argue that b :: bs' is still
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1167
  well-formed. This may require us to show that ln(b') is o(ln(b)), which the function takes
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1168
  as an argument.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1169
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1170
fun adjust_exp_basis basis basis' ln_smallo_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1171
  if length (get_basis_list basis) = length (get_basis_list basis') + 1 then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1172
    basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1173
  else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1174
    let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1175
      val SNE (SCons (info, ln_info, tail)) = basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1176
      val SNE tail' = basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1177
      val wf_thms = map get_basis_wf_thm [basis, basis']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1178
      val wf_thm' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1179
        case
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1180
          get_first (fn f => try f ())
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1181
            [fn _ => @{thm basis_wf_lift_modification} OF wf_thms,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1182
             fn _ => @{thm basis_wf_insert_exp_near} OF (wf_thms @ [ln_smallo_thm]),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1183
             fn _ => @{thm basis_wf_insert_exp_near} OF (wf_thms @ 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1184
               [ln_smallo_thm RS @{thm basis_wf_insert_exp_uminus'}])] of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1185
          SOME wf_thm => wf_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1186
        | _ => raise TERM ("Lifting basis modification in exp_expansion failed.", map Thm.concl_of (wf_thms @ [ln_smallo_thm]))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1187
      val info' = {wf_thm = wf_thm', head = #head info}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1188
      val lifting = mk_lifting (get_basis_list' tail) basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1189
      val ln_info' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1190
        {trimmed_thm = lift_trimmed_pos_thm lifting (#trimmed_thm ln_info),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1191
         ln_thm = lift_expands_to_thm lifting (#ln_thm ln_info)}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1192
    in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1193
      SNE (SCons (info', ln_info', tail'))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1194
    end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1195
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1196
(* inserts the exponential of a given function at the beginning of the given basis *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1197
fun insert_exp _ _ _ _ _ SEmpty = raise TERM ("insert_exp", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1198
  | insert_exp t ln_thm ln_smallo_thm ln_trimmed_thm lim_thm (SNE basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1199
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1200
        val head = Envir.beta_eta_contract (@{term "\<lambda>(f::real\<Rightarrow>real) x. exp (f x)"} $ t)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1201
        val ln_smallo_thm = ln_smallo_thm RS @{thm ln_smallo_ln_exp}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1202
        val wf_thm = @{thm basis_wf_manyI} OF [lim_thm, ln_smallo_thm, get_basis_wf_thm' basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1203
        val basis' = SNE (SCons ({wf_thm = wf_thm, head = head}, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1204
          {ln_thm = ln_thm, trimmed_thm = ln_trimmed_thm} , basis))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1205
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1206
        check_basis basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1207
      end 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1208
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1209
(* 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1210
  Returns an expansion of the exponential of the given expansion. This may add several
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1211
  new basis elements at any position of the basis (except at the very end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1212
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1213
fun exp_expansion _ thm SEmpty = (thm RS @{thm expands_to_exp_real}, SEmpty)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1214
  | exp_expansion ectxt thm basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1215
    let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1216
      val (_, thm, _) = whnf_expansion ectxt thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1217
    in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1218
      case ev_zeroness_oracle ectxt (get_eval (get_expansion thm)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1219
        SOME zero_thm => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1220
          (@{thm expands_to_exp_zero} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1221
             [thm, zero_thm, get_basis_wf_thm basis, mk_expansion_level_eq_thm basis], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1222
      | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1223
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1224
            val ln =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1225
              Option.map (fn x => (#ln_thm x, #trimmed_thm x)) (get_ln_info basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1226
            val ln = Option.map (fn (x, y) => retrim_pos_expansion ectxt (x, basis, y)) ln
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1227
            val es' = @{term "0::real"} :: (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1228
              case ln of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1229
                NONE => []
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1230
              | SOME (ln_thm, _, _) => get_exponents (get_expansion ln_thm))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1231
            val trim_result =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1232
              trim_expansion_while_greater true (SOME es') false (SOME Simple_Trim) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1233
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1234
            exp_expansion' ectxt trim_result ln basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1235
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1236
    end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1237
and exp_expansion' _ (thm, _, _) _ SEmpty = (thm RS @{thm expands_to_exp_real}, SEmpty)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1238
  | exp_expansion' ectxt (thm, trim_result, e_thms) ln basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1239
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1240
    val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1241
    val wf_thm = get_basis_wf_thm basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1242
    val f = get_expanded_fun thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1243
    fun exp_expansion_insert ln_smallo_thm = (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1244
      case determine_trimmed_sgn ectxt exp of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1245
        (IsPos, trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1246
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1247
            val [lim_thm, ln_thm', thm'] =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1248
              @{thms expands_to_exp_insert_pos}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1249
              |> map (fn thm' => thm' OF [thm, wf_thm, trimmed_thm, ln_smallo_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1250
            val basis' = insert_exp f ln_thm' ln_smallo_thm trimmed_thm lim_thm basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1251
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1252
            (thm', basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1253
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1254
      | (IsNeg, trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1255
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1256
            val [lim_thm, ln_thm', ln_trimmed_thm, thm'] = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1257
              @{thms expands_to_exp_insert_neg}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1258
              |> map (fn thm' => thm' OF [thm, wf_thm, trimmed_thm, ln_smallo_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1259
            val ln_smallo_thm = ln_smallo_thm RS @{thm basis_wf_insert_exp_uminus}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1260
            val f' = Envir.beta_eta_contract (@{term "\<lambda>(f::real\<Rightarrow>real) x. -f x"} $ f)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1261
            val basis' = insert_exp f' ln_thm' ln_smallo_thm ln_trimmed_thm lim_thm basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1262
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1263
            (thm', basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1264
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1265
      | _ => raise TERM ("Unexpected zeroness result in exp_expansion", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1266
    fun lexord (IsNeg :: _) = LESS
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1267
      | lexord (IsPos :: _) = GREATER
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1268
      | lexord (IsZero :: xs) = lexord xs
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1269
      | lexord [] = EQUAL
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1270
      | lexord _ = raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1271
    val compare_result = lexord (map fst e_thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1272
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1273
    case (trim_result, e_thms, compare_result) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1274
      (Aborted _, (IsNeg, e_neg_thm) :: _, _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1275
        (* leading exponent is negative; we can simply Taylor-expand exp(x) around 0 *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1276
        (@{thm expands_to_exp_neg} OF [thm, get_basis_wf_thm basis, e_neg_thm], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1277
    | (Trimmed (_, SOME trimmed_thm), (IsPos, e_pos_thm) :: _, GREATER) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1278
        (* leading exponent is positive; exp(f(x)) or exp(-f(x)) is new basis element *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1279
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1280
          val ln_smallo_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1281
            @{thm basis_wf_insert_exp_pos} OF [thm, get_basis_wf_thm basis, trimmed_thm, e_pos_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1282
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1283
          exp_expansion_insert ln_smallo_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1284
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1285
    | (Trimmed (_, SOME trimmed_thm), _, GREATER) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1286
        (* leading exponent is zero, but f(x) grows faster than ln(b(x)), so 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1287
           exp(f(x)) or exp(-f(x)) must still be new basis elements *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1288
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1289
          val ln_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1290
            case ln of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1291
              SOME (ln_thm, _, _) => ln_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1292
            | NONE => raise TERM ("TODO blubb", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1293
          val ln_thm = @{thm expands_to_lift''} OF [get_basis_wf_thm basis, ln_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1294
          val ln_smallo_thm = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1295
             @{thm compare_expansions_GT} OF [prove_compare_expansions GREATER (map snd e_thms),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1296
               trimmed_thm, thm, ln_thm, get_basis_wf_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1297
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1298
          exp_expansion_insert ln_smallo_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1299
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1300
    | (Aborted LESS, (IsZero, e_zero_thm) :: e_thms', _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1301
        (* leading exponent is zero and f(x) grows more slowly than ln(b(x)), so 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1302
           we can write f(x) = c(x) + g(x) and therefore exp(f(x)) = exp(c(x)) * exp(g(x)).
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1303
           The former is treated by a recursive call; the latter by Taylor expansion. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1304
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1305
          val (ln_thm, trimmed_thm) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1306
            case ln of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1307
              SOME (ln_thm, _, trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1308
                (ln_thm, trimmed_thm RS @{thm trimmed_pos_imp_trimmed})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1309
            | NONE => raise TERM ("TODO foo", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1310
          val c_thm = expands_to_hd thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1311
          val ln_smallo_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1312
            @{thm compare_expansions_LT} OF [prove_compare_expansions LESS (map snd e_thms'),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1313
              trimmed_thm, c_thm, ln_thm, get_basis_wf_thm (tl_basis basis)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1314
          val (c_thm, c_basis) = exp_expansion ectxt c_thm (tl_basis basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1315
          val basis' = adjust_exp_basis basis c_basis ln_smallo_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1316
          val wf_thm = get_basis_wf_thm basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1317
          val thm' = lift basis' thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1318
          val (thm'', _) = retrim_expansion ectxt (thm', basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1319
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1320
          (@{thm expands_to_exp_0} OF [thm'', wf_thm, e_zero_thm, c_thm], basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1321
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1322
    | (Trimmed _, [(IsZero, e_zero_thm)], EQUAL) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1323
        (* f(x) can be written as c + g(x) where c is just a real constant.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1324
           We can therefore write exp(f(x)) = exp(c) * exp(g(x)), where the latter is
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1325
           a simple Taylor expansion. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1326
        (@{thm expands_to_exp_0_real} OF [thm, wf_thm, e_zero_thm], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1327
    | (Trimmed _, (_, e_zero_thm) :: _, EQUAL) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1328
        (* f(x) is asymptotically equivalent to c * ln(b(x)), so we can write f(x) as
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1329
           c * ln(b(x)) + g(x) and therefore exp(f(x)) = b(x)^c * exp(g(x)). The second
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1330
           factor is handled by a recursive call *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1331
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1332
          val ln_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1333
            case ln of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1334
              SOME (ln_thm, _, _) => ln_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1335
            | NONE => raise TERM ("TODO blargh", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1336
          val c =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1337
            case (thm, ln_thm) |> apply2 (get_expansion #> get_lead_coeff) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1338
              (c1, c2) => @{term "(/) :: real => _"} $ c1 $ c2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1339
          val c = Thm.cterm_of (get_ctxt ectxt) c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1340
          
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1341
          val thm' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1342
            @{thm expands_to_exp_0_pull_out1} 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1343
                OF [thm, ln_thm, wf_thm, e_zero_thm, Thm.reflexive c]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1344
          val (thm'', basis') = exp_expansion ectxt thm' basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1345
          val pat = ConsPat ("MS", [AnyPat ("_", 0), AnyPat ("_", 0)])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1346
          val (_, _, conv) = match ectxt pat (get_expansion thm'') (SOME [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1347
          val eq_thm = conv (Thm.cterm_of (get_ctxt ectxt) (get_expansion thm''))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1348
          val thm''' = @{thm expands_to_meta_eq_cong} OF [thm'', eq_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1349
          val thm'''' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1350
            case get_intyness (get_ctxt ectxt) c of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1351
              No_Nat =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1352
                @{thm expands_to_exp_0_pull_out2} OF [thm''', get_basis_wf_thm basis']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1353
             | Nat nat_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1354
                @{thm expands_to_exp_0_pull_out2_nat} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1355
                  [thm''', get_basis_wf_thm basis', nat_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1356
             | Neg_Nat nat_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1357
                @{thm expands_to_exp_0_pull_out2_neg_nat} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1358
                  [thm''', get_basis_wf_thm basis', nat_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1359
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1360
          (thm'''', basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1361
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1362
    | (Trimmed (IsZero, _), [], _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1363
        (* Expansion is empty, i.e. f(x) is identically zero *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1364
        (@{thm expands_to_exp_MSLNil} OF [thm, get_basis_wf_thm basis], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1365
    | (Trimmed (_, NONE), _, GREATER) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1366
        (* We could not determine whether f(x) grows faster than ln(b(x)) or not. *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1367
        raise_trimming_error ectxt thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1368
    | _ => raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1369
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1370
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1371
fun powr_expansion ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1372
      case ev_zeroness_oracle ectxt (get_expanded_fun thm1) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1373
        SOME zero_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1374
          (@{thm expands_to_powr_0} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1375
             [zero_thm, Thm.reflexive (Thm.cterm_of (get_ctxt ectxt) (get_expanded_fun thm2)),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1376
              get_basis_wf_thm basis, mk_expansion_level_eq_thm basis],
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1377
           basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1378
      | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1379
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1380
            val (thm1, _, SOME trimmed_thm) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1381
              trim_expansion true (SOME Pos_Trim) ectxt (thm1, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1382
            val (ln_thm, basis') = ln_expansion ectxt trimmed_thm thm1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1383
            val thm2' = lift basis' thm2 |> simplify_expansion ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1384
            val mult_thm = @{thm expands_to_mult} OF [get_basis_wf_thm basis', ln_thm, thm2']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1385
            val (exp_thm, basis'') = exp_expansion ectxt mult_thm basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1386
            val thm = @{thm expands_to_powr} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1387
              [trimmed_thm, get_basis_wf_thm basis, thm1, exp_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1388
          in  
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1389
            (thm, basis'')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1390
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1391
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1392
fun powr_nat_expansion ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1393
      case ev_zeroness_oracle ectxt (get_expanded_fun thm1) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1394
        SOME zero_thm => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1395
          case ev_zeroness_oracle ectxt (get_expanded_fun thm2) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1396
            SOME zero'_thm => (@{thm expands_to_powr_nat_0_0} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1397
             [zero_thm, zero'_thm, get_basis_wf_thm basis, mk_expansion_level_eq_thm basis], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1398
          | NONE => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1399
              case trim_expansion true (SOME Simple_Trim) ectxt (thm2, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1400
                (thm2, _, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1401
                  (@{thm expands_to_powr_nat_0} OF [zero_thm, thm2, trimmed_thm, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1402
                     get_basis_wf_thm basis, mk_expansion_level_eq_thm basis], basis)))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1403
      | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1404
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1405
            val (thm1, _, SOME trimmed_thm) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1406
              trim_expansion true (SOME Pos_Trim) ectxt (thm1, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1407
            val (ln_thm, basis') = ln_expansion ectxt trimmed_thm thm1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1408
            val thm2' = lift basis' thm2 |> simplify_expansion ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1409
            val mult_thm = @{thm expands_to_mult} OF [get_basis_wf_thm basis', ln_thm, thm2']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1410
            val (exp_thm, basis'') = exp_expansion ectxt mult_thm basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1411
            val thm = @{thm expands_to_powr_nat} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1412
              [trimmed_thm, get_basis_wf_thm basis, thm1, exp_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1413
          in  
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1414
            (thm, basis'')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1415
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1416
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1417
fun is_numeral t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1418
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1419
    val _ = HOLogic.dest_number t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1420
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1421
    true
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1422
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1423
    handle TERM _ => false
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1424
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1425
fun power_expansion ectxt (thm, n, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1426
      case ev_zeroness_oracle ectxt (get_expanded_fun thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1427
        SOME zero_thm => @{thm expands_to_power_0} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1428
          [zero_thm, get_basis_wf_thm basis, mk_expansion_level_eq_thm basis,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1429
             Thm.reflexive (Thm.cterm_of (get_ctxt ectxt) n)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1430
      | NONE => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1431
          case trim_expansion true (SOME Simple_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1432
            (thm', _, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1433
              let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1434
                val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1435
                val thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1436
                  if is_numeral n then @{thm expands_to_power[where abort = True]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1437
                    else @{thm expands_to_power[where abort = False]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1438
                val thm = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1439
                  Drule.infer_instantiate' ctxt [NONE, NONE, NONE, SOME (Thm.cterm_of ctxt n)] thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1440
              in                
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1441
                thm OF [trimmed_thm, get_basis_wf_thm basis, thm']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1442
              end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1443
          | _ => raise TERM ("Unexpected zeroness result in power_expansion", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1444
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1445
fun powr_const_expansion ectxt (thm, p, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1446
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1447
    val pthm = Thm.reflexive (Thm.cterm_of (get_ctxt ectxt) p)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1448
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1449
    case ev_zeroness_oracle ectxt (get_expanded_fun thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1450
      SOME zero_thm => @{thm expands_to_powr_const_0} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1451
        [zero_thm, get_basis_wf_thm basis, mk_expansion_level_eq_thm basis, pthm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1452
    | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1453
        case trim_expansion true (SOME Pos_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1454
          (_, _, NONE) => raise TERM ("Unexpected zeroness result for powr", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1455
        | (thm, _, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1456
            (if is_numeral p then @{thm expands_to_powr_const[where abort = True]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1457
                 else @{thm expands_to_powr_const[where abort = False]})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1458
               OF [trimmed_thm, get_basis_wf_thm basis, thm, pthm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1459
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1460
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1461
fun sgn_expansion ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1462
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1463
    val thms = [get_basis_wf_thm basis, mk_expansion_level_eq_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1464
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1465
    case ev_zeroness_oracle ectxt (get_expanded_fun thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1466
      SOME zero_thm => @{thm expands_to_sgn_zero} OF (zero_thm :: thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1467
    | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1468
        case trim_expansion true (SOME Sgn_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1469
          (thm, IsPos, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1470
            @{thm expands_to_sgn_pos} OF ([trimmed_thm, thm] @ thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1471
        | (thm, IsNeg, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1472
            @{thm expands_to_sgn_neg} OF ([trimmed_thm, thm] @ thms)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1473
        | _ => raise TERM ("Unexpected zeroness result in sgn_expansion", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1474
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1475
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1476
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1477
  Returns an expansion of the sine and cosine of the given expansion. Fails if that function
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1478
  goes to infinity.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1479
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1480
fun sin_cos_expansion _ thm SEmpty =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1481
      (thm RS @{thm expands_to_sin_real}, thm RS @{thm expands_to_cos_real})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1482
  | sin_cos_expansion ectxt thm basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1483
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1484
        val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1485
        val e = get_exponent exp
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1486
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1487
        case zeroness_oracle true (SOME Sgn_Trim) ectxt e of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1488
          (IsPos, _) => raise THM ("sin_cos_expansion", 0, [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1489
        | (IsNeg, SOME e_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1490
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1491
              val [thm1, thm2] = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1492
                map (fn thm' => thm' OF [e_thm, get_basis_wf_thm basis, thm]) 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1493
                  @{thms expands_to_sin_ms_neg_exp expands_to_cos_ms_neg_exp}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1494
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1495
              (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1496
            end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1497
        | (IsZero, SOME e_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1498
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1499
              val (sin_thm, cos_thm) = (sin_cos_expansion ectxt (expands_to_hd thm) (tl_basis basis))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1500
              fun mk_thm thm' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1501
                (thm' OF [e_thm, get_basis_wf_thm basis, thm, sin_thm, cos_thm]) |> solve_eval_eq
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1502
              val [thm1, thm2] = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1503
                map mk_thm @{thms expands_to_sin_ms_zero_exp expands_to_cos_ms_zero_exp}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1504
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1505
              (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1506
            end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1507
        | _ => raise TERM ("Unexpected zeroness result in sin_exp_expansion", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1508
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1509
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1510
fun abconv (t, t') = Envir.beta_eta_contract t aconv Envir.beta_eta_contract t'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1511
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1512
(*
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1513
  Makes sure that an expansion theorem really talks about the right function.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1514
  This is basically a sanity check to make things fail early and in the right place.
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1515
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1516
fun check_expansion e thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1517
  if abconv (expr_to_term e, get_expanded_fun thm) then 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1518
    thm 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1519
  else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1520
(* TODO Remove Debugging stuff *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1521
let val _ = @{print} e
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1522
val _ = @{print} (get_expanded_fun thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1523
in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1524
    raise TERM ("check_expansion", [Thm.concl_of thm, expr_to_term e])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1525
end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1526
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1527
fun minmax_expansion max [less_thm, eq_thm, gt_thm] ectxt (thm1, thm2, basis) = (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1528
      case compare_expansions ectxt (thm1, thm2, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1529
        (LESS, less_thm', thm1, thm2) => less_thm OF [if max then thm2 else thm1, less_thm']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1530
      | (GREATER, gt_thm', thm1, thm2) => gt_thm OF [if max then thm1 else thm2, gt_thm']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1531
      | (EQUAL, eq_thm', thm1, _) => eq_thm OF [thm1, eq_thm'])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1532
  | minmax_expansion _ _ _ _ = raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1533
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1534
val min_expansion =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1535
  minmax_expansion false @{thms expands_to_min_lt expands_to_min_eq expands_to_min_gt}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1536
val max_expansion =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1537
  minmax_expansion true @{thms expands_to_max_lt expands_to_max_eq expands_to_max_gt}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1538
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1539
fun zero_expansion basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1540
  @{thm expands_to_zero} OF [get_basis_wf_thm basis, mk_expansion_level_eq_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1541
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1542
fun const_expansion _ basis @{term "0 :: real"} = zero_expansion basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1543
  | const_expansion ectxt basis t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1544
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1545
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1546
    val thm = Drule.infer_instantiate' ctxt [NONE, SOME (Thm.cterm_of ctxt t)] 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1547
                @{thm expands_to_const}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1548
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1549
    thm OF [get_basis_wf_thm basis, mk_expansion_level_eq_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1550
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1551
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1552
fun root_expansion ectxt (thm, n, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1553
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1554
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1555
    fun tac {context = ctxt, ...} =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1556
      HEADGOAL (Method.insert_tac ctxt (get_facts ectxt))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1557
      THEN Local_Defs.unfold_tac ctxt eval_simps
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1558
      THEN HEADGOAL (Simplifier.asm_full_simp_tac ctxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1559
    fun prove goal =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1560
      try (Goal.prove ctxt [] [] (HOLogic.mk_Trueprop (Term.betapply (goal, n)))) tac
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1561
    fun err () =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1562
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1563
        val t = simplify_term' (get_facts ectxt) ctxt n
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1564
        val _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1565
          if #verbose (#ctxt ectxt) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1566
            let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1567
              val p = Pretty.str ("real_asymp failed to determine whether the following constant " ^
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1568
                "is zero or not:")
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1569
              val p = Pretty.chunks [p, Pretty.indent 2 (Syntax.pretty_term ctxt t)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1570
            in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1571
              Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1572
            end else ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1573
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1574
        raise TERM ("zeroness_oracle", [n])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1575
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1576
    fun aux nz_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1577
      case trim_expansion true (SOME Sgn_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1578
        (thm, IsPos, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1579
          @{thm expands_to_root} OF [nz_thm, trimmed_thm, get_basis_wf_thm basis, thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1580
      | (thm, IsNeg, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1581
          @{thm expands_to_root_neg} OF [nz_thm, trimmed_thm, get_basis_wf_thm basis, thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1582
      | _ => raise TERM ("Unexpected zeroness result in root_expansion", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1583
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1584
    case prove @{term "\<lambda>n::nat. n = 0"} of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1585
      SOME zero_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1586
        @{thm expands_to_0th_root} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1587
          [zero_thm, get_basis_wf_thm basis, mk_expansion_level_eq_thm basis, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1588
             Thm.reflexive (Thm.cterm_of ctxt (get_expanded_fun thm))]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1589
    | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1590
        case prove @{term "\<lambda>n::nat. n > 0"} of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1591
          NONE => err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1592
        | SOME nz_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1593
            case ev_zeroness_oracle ectxt (get_expanded_fun thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1594
              SOME zero_thm => @{thm expands_to_root_0} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1595
                [nz_thm, zero_thm, get_basis_wf_thm basis, mk_expansion_level_eq_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1596
            | NONE => aux nz_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1597
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1598
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1599
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1600
fun arctan_expansion _ SEmpty thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1601
      @{thm expands_to_real_compose[where g = arctan]} OF [thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1602
  | arctan_expansion ectxt basis thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1603
      case ev_zeroness_oracle ectxt (get_expanded_fun thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1604
        SOME zero_thm => @{thm expands_to_arctan_zero} OF [zero_expansion basis, zero_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1605
      | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1606
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1607
            val (thm, _, _) = trim_expansion true (SOME Simple_Trim) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1608
            val e = get_exponent (get_expansion thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1609
            fun cont ectxt (thm, basis) = arctan_expansion ectxt basis thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1610
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1611
            case zeroness_oracle true (SOME Sgn_Trim) ectxt e of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1612
                (IsNeg, SOME neg_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1613
                  @{thm expands_to_arctan_ms_neg_exp} OF [neg_thm, get_basis_wf_thm basis, thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1614
              | (IsPos, SOME e_pos_thm) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1615
                  case determine_trimmed_sgn ectxt (get_expansion thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1616
                    (IsPos, trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1617
                      @{thm expands_to_arctan_ms_pos_exp_pos} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1618
                        [e_pos_thm, trimmed_thm, get_basis_wf_thm basis, thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1619
                  | (IsNeg, trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1620
                      @{thm expands_to_arctan_ms_pos_exp_neg} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1621
                        [e_pos_thm, trimmed_thm, get_basis_wf_thm basis, thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1622
                  | _ => raise TERM ("Unexpected trim result during expansion of arctan", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1623
              | (IsZero, _) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1624
                  case try_lift_function ectxt (thm, basis) cont of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1625
                    (SOME thm', _) => thm'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1626
                  | _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1627
                      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1628
                        val _ = if get_verbose ectxt then 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1629
                          writeln "Unsupported occurrence of arctan" else ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1630
                      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1631
                        raise TERM ("Unsupported occurence of arctan", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1632
                      end)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1633
              | _ => raise TERM ("Unexpected trim result during expansion of arctan", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1634
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1635
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1636
(* Returns an expansion theorem for a function that is already a basis element *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1637
fun expand_basic _ t SEmpty = raise TERM ("expand_basic", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1638
  | expand_basic thm t basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1639
      if abconv (get_basis_head basis, t) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1640
        thm (get_basis_wf_thm basis) (mk_expansion_level_eq_thm (tl_basis basis))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1641
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1642
        @{thm expands_to_lift'} OF [get_basis_wf_thm basis, expand_basic thm t (tl_basis basis)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1643
  
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1644
fun expand_unary ectxt thm e basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1645
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1646
        val (thm', basis') = expand' ectxt e basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1647
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1648
        (thm OF [get_basis_wf_thm basis', thm'], basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1649
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1650
and expand_binary ectxt thm (e1, e2) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1651
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1652
        val (thm1, basis') = expand' ectxt e1 basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1653
        val (thm2, basis'') = expand' ectxt e2 basis' |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1654
        val thm1 = lift basis'' thm1 |> simplify_expansion ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1655
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1656
        (thm OF [get_basis_wf_thm basis'', thm1, thm2], basis'')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1657
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1658
and trim_nz mode ectxt e basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1659
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1660
        val (thm, basis') = expand' ectxt e basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1661
        val (thm', nz, trimmed_thm) = trim_expansion true (SOME mode) ectxt (thm, basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1662
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1663
        case trimmed_thm of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1664
          NONE => raise TERM ("expand: zero denominator", [get_expansion thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1665
        | SOME trimmed_thm => (thm', basis', nz, trimmed_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1666
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1667
and expand'' ectxt (ConstExpr c) basis = (const_expansion ectxt basis c, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1668
  | expand'' _ X basis = (lift basis @{thm expands_to_X}, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1669
  | expand'' ectxt (Uminus e) basis = expand_unary ectxt @{thm expands_to_uminus} e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1670
  | expand'' ectxt (Add e12) basis = expand_binary ectxt @{thm expands_to_add} e12 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1671
  | expand'' ectxt (Minus e12) basis = expand_binary ectxt @{thm expands_to_minus} e12 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1672
  | expand'' ectxt (Mult e12) basis = expand_binary ectxt @{thm expands_to_mult} e12 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1673
  | expand'' ectxt (Powr' (e, p)) basis = (* TODO zero basis *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1674
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1675
        val (thm, basis') = expand' ectxt e basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1676
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1677
        (powr_const_expansion ectxt (thm, p, basis'), basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1678
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1679
  | expand'' ectxt (Powr (e1, e2)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1680
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1681
        val (thm2, basis1) = expand' ectxt e2 basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1682
        val (thm1, basis2) = expand' ectxt e1 basis1 |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1683
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1684
        powr_expansion ectxt (thm1, thm2, basis2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1685
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1686
  | expand'' ectxt (Powr_Nat (e1, e2)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1687
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1688
        val (thm2, basis1) = expand' ectxt e2 basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1689
        val (thm1, basis2) = expand' ectxt e1 basis1 |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1690
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1691
        powr_nat_expansion ectxt (thm1, thm2, basis2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1692
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1693
  | expand'' ectxt (LnPowr (e1, e2)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1694
      let (* TODO zero base *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1695
        val (thm2, basis1) = expand' ectxt e2 basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1696
        val (thm1, basis2, _, trimmed_thm) = trim_nz Pos_Trim ectxt e1 basis1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1697
        val (ln_thm, basis3) = ln_expansion ectxt trimmed_thm thm1 basis2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1698
        val thm2' = lift basis3 thm2 |> simplify_expansion ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1699
        val mult_thm = @{thm expands_to_mult} OF [get_basis_wf_thm basis3, ln_thm, thm2']
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1700
        val thm = @{thm expands_to_ln_powr} OF 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1701
          [trimmed_thm, get_basis_wf_thm basis2, thm1, mult_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1702
      in  
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1703
        (thm, basis3)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1704
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1705
  | expand'' ectxt (ExpLn e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1706
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1707
        val (thm, basis', _, trimmed_thm) = trim_nz Pos_Trim ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1708
        val thm = @{thm expands_to_exp_ln} OF [trimmed_thm, get_basis_wf_thm basis', thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1709
      in  
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1710
        (thm, basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1711
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1712
  | expand'' ectxt (Power (e, n)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1713
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1714
        val (thm, basis') = expand' ectxt e basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1715
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1716
        (power_expansion ectxt (thm, n, basis'), basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1717
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1718
  | expand'' ectxt (Root (e, n)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1719
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1720
        val (thm, basis') = expand' ectxt e basis |> apfst (simplify_expansion ectxt)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1721
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1722
        (root_expansion ectxt (thm, n, basis'), basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1723
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1724
  | expand'' ectxt (Inverse e) basis = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1725
      (case trim_nz Simple_Trim ectxt e basis of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1726
         (thm, basis', _, trimmed_thm) => 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1727
           (@{thm expands_to_inverse} OF [trimmed_thm, get_basis_wf_thm basis', thm], basis'))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1728
  | expand'' ectxt (Div (e1, e2)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1729
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1730
        val (thm1, basis') = expand' ectxt e1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1731
        val (thm2, basis'', _, trimmed_thm) = trim_nz Simple_Trim ectxt e2 basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1732
        val thm1 = lift basis'' thm1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1733
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1734
        (@{thm expands_to_divide} OF [trimmed_thm, get_basis_wf_thm basis'', thm1, thm2], basis'')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1735
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1736
  | expand'' ectxt (Ln e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1737
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1738
        val (thm, basis', _, trimmed_thm) = trim_nz Pos_Trim ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1739
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1740
        ln_expansion ectxt trimmed_thm thm basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1741
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1742
  | expand'' ectxt (Exp e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1743
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1744
        val (thm, basis') = expand' ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1745
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1746
        exp_expansion ectxt thm basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1747
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1748
  | expand'' ectxt (Absolute e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1749
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1750
        val (thm, basis', nz, trimmed_thm) = trim_nz Sgn_Trim ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1751
        val thm' =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1752
          case nz of 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1753
            IsPos => @{thm expands_to_abs_pos} 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1754
          | IsNeg => @{thm expands_to_abs_neg}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1755
          | _ => raise TERM ("Unexpected trim result during expansion of abs", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1756
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1757
        (thm' OF [trimmed_thm, get_basis_wf_thm basis', thm], basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1758
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1759
  | expand'' ectxt (Sgn e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1760
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1761
        val (thm, basis') = expand' ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1762
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1763
        (sgn_expansion ectxt (thm, basis'), basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1764
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1765
  | expand'' ectxt (Min (e1, e2)) basis = (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1766
      case try_prove_ev_eq ectxt (apply2 expr_to_term (e1, e2)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1767
        SOME eq_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1768
          expand' ectxt e1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1769
          |> apfst (fn thm => @{thm expands_to_min_eq} OF [thm, eq_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1770
      | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1771
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1772
            val (thm1, basis') = expand' ectxt e1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1773
            val (thm2, basis'') = expand' ectxt e2 basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1774
            val thm1' = lift basis'' thm1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1775
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1776
            (min_expansion ectxt (thm1', thm2, basis''), basis'')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1777
          end)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1778
  | expand'' ectxt (Max (e1, e2)) basis = (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1779
      case try_prove_ev_eq ectxt (apply2 expr_to_term (e1, e2)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1780
        SOME eq_thm =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1781
          expand' ectxt e1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1782
          |> apfst (fn thm => @{thm expands_to_max_eq} OF [thm, eq_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1783
      | NONE =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1784
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1785
            val (thm1, basis') = expand' ectxt e1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1786
            val (thm2, basis'') = expand' ectxt e2 basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1787
            val thm1' = lift basis'' thm1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1788
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1789
            (max_expansion ectxt (thm1', thm2, basis''), basis'')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1790
          end)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1791
  | expand'' ectxt (Sin e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1792
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1793
        val (thm, basis', _, _) = trim_nz Simple_Trim ectxt e basis (* TODO could be relaxed *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1794
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1795
        (sin_cos_expansion ectxt thm basis' |> fst, basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1796
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1797
  | expand'' ectxt (Cos e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1798
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1799
        val (thm, basis', _, _) = trim_nz Simple_Trim ectxt e basis (* TODO could be relaxed *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1800
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1801
        (sin_cos_expansion ectxt thm basis' |> snd, basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1802
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1803
  | expand'' _ (Floor _) _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1804
      raise TERM ("floor not supported.", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1805
  | expand'' _ (Ceiling _) _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1806
      raise TERM ("ceiling not supported.", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1807
  | expand'' _ (Frac _) _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1808
      raise TERM ("frac not supported.", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1809
  | expand'' _ (NatMod _) _ =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1810
      raise TERM ("mod not supported.", [])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1811
  | expand'' ectxt (ArcTan e) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1812
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1813
        (* TODO: what if it's zero *)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1814
        val (thm, basis') = expand' ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1815
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1816
        (arctan_expansion ectxt basis' thm, basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1817
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1818
  | expand'' ectxt (Custom (name, t, args)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1819
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1820
        fun expand_args acc basis [] = (rev acc, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1821
          | expand_args acc basis (arg :: args) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1822
              case expand' ectxt arg basis of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1823
                (thm, basis') => expand_args (thm :: acc) basis' args          
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1824
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1825
        case expand_custom (get_ctxt ectxt) name of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1826
          NONE => raise TERM ("Unsupported custom function: " ^ name, [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1827
        | SOME e => e ectxt t (expand_args [] basis args)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1828
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1829
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1830
and expand' ectxt (e' as (Inverse e)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1831
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1832
        val t = expr_to_term e
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1833
        fun thm wf_thm len_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1834
          @{thm expands_to_basic_inverse} OF [wf_thm, len_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1835
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1836
        if member abconv (get_basis_list basis) t then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1837
          (expand_basic thm t basis, basis) |> apfst (check_expansion e')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1838
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1839
          expand'' ectxt e' basis |> apfst (check_expansion e')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1840
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1841
  | expand' ectxt (Div (e1, e2)) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1842
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1843
        val (thm1, basis') = expand' ectxt e1 basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1844
        val t = expr_to_term e2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1845
        fun thm wf_thm len_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1846
          @{thm expands_to_basic_inverse} OF [wf_thm, len_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1847
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1848
        if member abconv (get_basis_list basis') t then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1849
          (@{thm expands_to_div'} OF [get_basis_wf_thm basis', thm1, expand_basic thm t basis'], 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1850
             basis')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1851
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1852
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1853
            val (thm2, basis'', _, trimmed_thm) = trim_nz Simple_Trim ectxt e2 basis'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1854
            val thm1 = lift basis'' thm1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1855
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1856
            (@{thm expands_to_divide} OF [trimmed_thm, get_basis_wf_thm basis'', thm1, thm2], 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1857
               basis'')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1858
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1859
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1860
  | expand' ectxt (e' as (Powr' (e, p))) basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1861
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1862
        val t = expr_to_term e
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1863
        val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1864
        fun thm wf_thm len_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1865
          (Drule.infer_instantiate' ctxt [NONE, NONE, SOME (Thm.cterm_of ctxt p)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1866
            @{thm expands_to_basic_powr}) OF [wf_thm, len_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1867
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1868
        if member abconv (get_basis_list basis) t then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1869
          (expand_basic thm t basis, basis) |> apfst (check_expansion e')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1870
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1871
          expand'' ectxt e' basis |> apfst (check_expansion e')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1872
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1873
  | expand' ectxt e basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1874
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1875
        val t = expr_to_term e
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1876
        fun thm wf_thm len_thm = @{thm expands_to_basic} OF [wf_thm, len_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1877
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1878
        if member abconv (get_basis_list basis) t then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1879
          (expand_basic thm t basis, basis) |> apfst (check_expansion e)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1880
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1881
          expand'' ectxt e basis |> apfst (check_expansion e)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1882
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1883
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1884
fun expand ectxt e basis = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1885
  expand' ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1886
  |> apfst (simplify_expansion ectxt) 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1887
  |> apfst (check_expansion e)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1888
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1889
fun expand_term ectxt t basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1890
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1891
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1892
    val (e, eq_thm) = reify ctxt t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1893
    val (thm,  basis) = expand ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1894
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1895
    (@{thm expands_to_meta_eq_cong'} OF [thm, eq_thm], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1896
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1897
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1898
fun expand_terms ectxt ts basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1899
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1900
    val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1901
    val e_eq_thms = map (reify ctxt) ts
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1902
    fun step (e, eq_thm) (thms, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1903
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1904
        val (thm, basis) = expand' ectxt e basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1905
        val thm = @{thm expands_to_meta_eq_cong'} OF [simplify_expansion ectxt thm, eq_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1906
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1907
        (thm :: thms, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1908
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1909
    val (thms, basis) = fold step e_eq_thms ([], basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1910
    fun lift thm = lift_expands_to_thm (mk_lifting (extract_basis_list thm) basis) thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1911
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1912
    (map lift (rev thms), basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1913
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1914
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1915
datatype limit =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1916
   Zero_Limit of bool option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1917
 | Finite_Limit of term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1918
 | Infinite_Limit of bool option
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1919
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1920
fun is_empty_expansion (Const (@{const_name MS}, _) $ Const (@{const_name MSLNil}, _) $ _) = true
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1921
  | is_empty_expansion _ = false
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1922
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1923
fun limit_of_expansion_aux ectxt basis thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1924
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1925
    val n = length (get_basis_list basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1926
    val (thm, res, e_thms) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1927
      trim_expansion_while_greater false (SOME (replicate n @{term "0::real"})) true
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1928
        (SOME Simple_Trim) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1929
    val trimmed_thm = case res of Trimmed (_, trimmed_thm) => trimmed_thm | _ => NONE
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1930
    val res = case res of Trimmed _ => GREATER | Aborted res => res
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1931
    val exp = get_expansion thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1932
    val _ = if res = GREATER andalso is_none trimmed_thm andalso not (is_empty_expansion exp) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1933
              raise TERM ("limit_of_expansion", [get_expansion thm]) else ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1934
    fun go thm _ _ [] = (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1935
          case zeroness_oracle false (SOME Simple_Trim) ectxt (get_expansion thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1936
            (IsZero, _) => (Zero_Limit NONE, @{thm expands_to_real_imp_filterlim} OF [thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1937
          | _ => (Finite_Limit @{term "0::real"}, @{thm expands_to_real_imp_filterlim} OF [thm]))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1938
      | go thm _ basis ((IsNeg, neg_thm) :: _) = (Zero_Limit NONE,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1939
          @{thm expands_to_neg_exponent_imp_filterlim} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1940
            [thm, get_basis_wf_thm basis, neg_thm RS @{thm compare_reals_diff_sgnD(1)}])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1941
      | go thm trimmed_thm basis ((IsPos, pos_thm) :: _) = (Infinite_Limit NONE,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1942
          @{thm expands_to_pos_exponent_imp_filterlim} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1943
            [thm, the trimmed_thm, get_basis_wf_thm basis,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1944
             pos_thm RS @{thm compare_reals_diff_sgnD(3)}])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1945
      | go thm trimmed_thm basis ((IsZero, zero_thm) :: e_thms) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1946
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1947
             val thm' = thm RS @{thm expands_to_hd''}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1948
             val trimmed_thm' = Option.map (fn thm => thm RS @{thm trimmed_hd}) trimmed_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1949
             val (lim, lim_thm) = go thm' trimmed_thm' (tl_basis basis) e_thms
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1950
             val lim_lift_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1951
                case lim of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1952
                  Infinite_Limit _ => @{thm expands_to_zero_exponent_imp_filterlim(1)}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1953
                | _ => @{thm expands_to_zero_exponent_imp_filterlim(2)}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1954
             val lim_thm' = 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1955
               lim_lift_thm OF [thm, get_basis_wf_thm basis, 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1956
                 zero_thm RS @{thm compare_reals_diff_sgnD(2)}, lim_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1957
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1958
              (lim, lim_thm')
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1959
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1960
      | go _ _ _ _ = raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1961
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1962
    if is_empty_expansion exp then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1963
      (Zero_Limit NONE, thm RS @{thm expands_to_MSLNil_imp_filterlim}, thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1964
    else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1965
      case go thm trimmed_thm basis e_thms of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1966
        (lim, lim_thm) => (lim, lim_thm, thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1967
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1968
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1969
(* 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1970
  Determines the limit of a function from its expansion. The two flags control whether the
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1971
  the sign of the approach should be determined for the infinite case (i.e. at_top/at_bot instead
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1972
  of just at_infinity) and the zero case (i.e. at_right 0/at_left 0 instead of just nhds 0)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1973
*)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1974
fun limit_of_expansion (sgn_zero, sgn_inf) ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1975
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1976
    val (lim, lim_thm, thm) = limit_of_expansion_aux ectxt basis thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1977
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1978
    case lim of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1979
      Zero_Limit _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1980
        if sgn_zero then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1981
          case trim_expansion false (SOME Sgn_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1982
            (thm, IsPos, SOME pos_thm) => (Zero_Limit (SOME true),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1983
              @{thm tendsto_imp_filterlim_at_right[OF _ expands_to_imp_eventually_pos]} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1984
                [lim_thm, get_basis_wf_thm basis, thm, pos_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1985
          | (thm, IsNeg, SOME neg_thm) => (Zero_Limit (SOME false),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1986
              @{thm tendsto_imp_filterlim_at_left[OF _ expands_to_imp_eventually_neg]} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1987
                [lim_thm, get_basis_wf_thm basis, thm, neg_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1988
          | _ => (Zero_Limit NONE, lim_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1989
        else (Zero_Limit NONE, lim_thm))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1990
    | Infinite_Limit _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1991
        if sgn_inf then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1992
          case trim_expansion false (SOME Sgn_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1993
            (thm, IsPos, SOME pos_thm) => (Infinite_Limit (SOME true),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1994
              (@{thm filterlim_at_infinity_imp_filterlim_at_top[OF _ expands_to_imp_eventually_pos]} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1995
                 [lim_thm, get_basis_wf_thm basis, thm, pos_thm]))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1996
          | (thm, IsNeg, SOME neg_thm) => (Infinite_Limit (SOME false),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1997
              @{thm filterlim_at_infinity_imp_filterlim_at_bot[OF _ expands_to_imp_eventually_neg]} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1998
                [lim_thm, get_basis_wf_thm basis, thm, neg_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  1999
          | _ => (Infinite_Limit NONE, lim_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2000
        else (Infinite_Limit NONE, lim_thm))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2001
    | Finite_Limit c => (Finite_Limit c, lim_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2002
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2003
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2004
fun compute_limit ectxt t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2005
  case expand_term ectxt t default_basis of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2006
    (thm, basis) => limit_of_expansion (true, true) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2007
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2008
fun prove_at_infinity ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2009
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2010
    fun err () = raise TERM ("prove_at_infinity", [get_expanded_fun thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2011
    val (thm, _, SOME trimmed_thm) = trim_expansion true (SOME Simple_Trim) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2012
    fun go basis thm trimmed_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2013
      if fastype_of (get_expansion thm) = @{typ "real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2014
        err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2015
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2016
        case zeroness_oracle true (SOME Pos_Trim) ectxt (get_exponent (get_expansion thm)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2017
          (IsPos, SOME pos_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2018
            @{thm expands_to_pos_exponent_imp_filterlim} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2019
              [thm, trimmed_thm, get_basis_wf_thm basis, pos_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2020
        | (IsZero, SOME zero_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2021
            @{thm expands_to_zero_exponent_imp_filterlim(1)} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2022
              [thm, get_basis_wf_thm basis, zero_thm,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2023
                 go (tl_basis basis) (thm RS @{thm expands_to_hd''})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2024
                   (trimmed_thm RS @{thm trimmed_hd})]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2025
        | _ => err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2026
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2027
    go basis thm trimmed_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2028
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2029
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2030
fun prove_at_top_at_bot mode ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2031
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2032
    val s = if mode = Pos_Trim then "prove_at_top" else "prove_at_bot"
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2033
    fun err () = raise TERM (s, [get_expanded_fun thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2034
    val (thm, _, SOME trimmed_thm) = trim_expansion true (SOME mode) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2035
    val trimmed_thm' = trimmed_thm RS
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2036
      (if mode = Pos_Trim then @{thm trimmed_pos_imp_trimmed} else @{thm trimmed_neg_imp_trimmed})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2037
    fun go basis thm trimmed_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2038
      if fastype_of (get_expansion thm) = @{typ "real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2039
        err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2040
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2041
        case zeroness_oracle true (SOME Pos_Trim) ectxt (get_exponent (get_expansion thm)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2042
          (IsPos, SOME pos_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2043
            @{thm expands_to_pos_exponent_imp_filterlim} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2044
              [thm, trimmed_thm, get_basis_wf_thm basis, pos_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2045
        | (IsZero, SOME zero_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2046
            @{thm expands_to_zero_exponent_imp_filterlim(1)} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2047
              [thm, get_basis_wf_thm basis, zero_thm,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2048
                 go (tl_basis basis) (thm RS @{thm expands_to_hd''})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2049
                   (trimmed_thm RS @{thm trimmed_hd})]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2050
        | _ => err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2051
    val lim_thm = go basis thm trimmed_thm'
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2052
    val add_sign_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2053
      if mode = Pos_Trim then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2054
        @{thm filterlim_at_infinity_imp_filterlim_at_top[OF _ expands_to_imp_eventually_pos]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2055
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2056
        @{thm filterlim_at_infinity_imp_filterlim_at_bot[OF _ expands_to_imp_eventually_neg]}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2057
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2058
    add_sign_thm OF [lim_thm, get_basis_wf_thm basis, thm, trimmed_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2059
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2060
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2061
val prove_at_top = prove_at_top_at_bot Pos_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2062
val prove_at_bot = prove_at_top_at_bot Neg_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2063
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2064
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2065
fun prove_at_aux mode ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2066
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2067
    val (s, add_sign_thm) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2068
      case mode of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2069
        Simple_Trim =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2070
          ("prove_at_0", @{thm Topological_Spaces.filterlim_atI[OF _ expands_to_imp_eventually_nz]})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2071
      | Pos_Trim =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2072
          ("prove_at_right_0",
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2073
             @{thm tendsto_imp_filterlim_at_right[OF _ expands_to_imp_eventually_pos]})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2074
      | Neg_Trim =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2075
          ("prove_at_left_0",
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2076
             @{thm tendsto_imp_filterlim_at_left[OF _ expands_to_imp_eventually_neg]})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2077
    fun err () = raise TERM (s, [get_expanded_fun thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2078
    val (thm, _, SOME trimmed_thm) = trim_expansion true (SOME mode) ectxt (thm, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2079
    fun go basis thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2080
      if fastype_of (get_expansion thm) = @{typ "real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2081
        err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2082
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2083
        case zeroness_oracle true (SOME Neg_Trim) ectxt (get_exponent (get_expansion thm)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2084
          (IsNeg, SOME neg_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2085
            @{thm expands_to_neg_exponent_imp_filterlim} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2086
              [thm, get_basis_wf_thm basis, neg_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2087
        | (IsZero, SOME zero_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2088
            @{thm expands_to_zero_exponent_imp_filterlim(2)} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2089
              [thm, get_basis_wf_thm basis, zero_thm,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2090
                 go (tl_basis basis) (thm RS @{thm expands_to_hd''})]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2091
        | _ => err ()
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2092
    val lim_thm = go basis thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2093
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2094
    add_sign_thm OF [lim_thm, get_basis_wf_thm basis, thm, trimmed_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2095
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2096
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2097
val prove_at_0 = prove_at_aux Simple_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2098
val prove_at_left_0 = prove_at_aux Neg_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2099
val prove_at_right_0 = prove_at_aux Pos_Trim
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2100
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2101
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2102
fun prove_nhds ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2103
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2104
    fun simplify (a, b, c) = (a, simplify_expansion ectxt b, c)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2105
    fun go thm basis =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2106
      if fastype_of (get_expansion thm) = @{typ "real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2107
        @{thm expands_to_real_imp_filterlim} OF [thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2108
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2109
        case whnf_expansion ectxt thm |> simplify of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2110
          (NONE, thm, _) => @{thm expands_to_MSLNil_imp_filterlim} OF [thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2111
        | (SOME _, thm, _) => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2112
            case zeroness_oracle true (SOME Sgn_Trim) ectxt (get_exponent (get_expansion thm)) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2113
              (IsZero, SOME zero_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2114
                @{thm expands_to_zero_exponent_imp_filterlim(2)} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2115
                  [thm, get_basis_wf_thm basis, zero_thm,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2116
                    go (thm RS @{thm expands_to_hd''}) (tl_basis basis)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2117
            | (IsNeg, SOME neg_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2118
                @{thm expands_to_neg_exponent_imp_filterlim} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2119
                  [thm, get_basis_wf_thm basis, neg_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2120
            | (IsPos, _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2121
                go (try_drop_leading_term ectxt thm) basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2122
            | _ => raise TERM ("Unexpected zeroness result in prove_nhds",
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2123
                     [get_exponent (get_expansion thm)]))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2124
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2125
    go thm basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2126
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2127
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2128
fun prove_equivalent theta ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2129
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2130
    val ((thm1, _, SOME trimmed_thm1), (thm2, _, SOME trimmed_thm2)) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2131
      apply2 (trim_expansion true (SOME Simple_Trim) ectxt) ((thm1, basis), (thm2, basis))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2132
    val pat = ConsPat (@{const_name Pair}, [ConsPat (@{const_name Lazy_Eval.cmp_result.EQ}, []), 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2133
                ConsPat (@{const_name Pair}, [AnyPat ("_", 0), AnyPat ("_", 0)])])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2134
    val (exp1, exp2) = apply2 get_expansion (thm1, thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2135
    val T = fastype_of exp1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2136
    val t = mk_compare_expansions_const T $ exp1 $ exp2
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2137
    fun eq_thm conv = HOLogic.mk_obj_eq (conv (Thm.cterm_of (get_ctxt ectxt) t))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2138
    val imp_thm =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2139
      if theta then @{thm compare_expansions_EQ_imp_bigtheta}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2140
      else @{thm compare_expansions_EQ_same}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2141
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2142
    case match ectxt pat t (SOME []) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2143
      (SOME _, t, conv) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2144
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2145
          val [_, c1, c2] = HOLogic.strip_tuple t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2146
          val c12_thm = if theta then [] else [the (try_prove_real_eq true ectxt (c1, c2))]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2147
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2148
          imp_thm OF ([eq_thm conv, trimmed_thm1, trimmed_thm2, thm1, thm2, get_basis_wf_thm basis] 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2149
            @ c12_thm)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2150
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2151
    | _ => raise TERM ("prove_equivalent", map get_expanded_fun [thm1, thm2])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2152
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2153
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2154
val prove_bigtheta = prove_equivalent true
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2155
val prove_asymp_equiv = prove_equivalent false
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2156
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2157
fun print_trimming_error s ectxt exp =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2158
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2159
    val c = get_coeff exp
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2160
    val t = if fastype_of c = @{typ real} then c else get_eval c
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2161
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2162
    if #verbose (#ctxt ectxt) then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2163
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2164
        val ctxt = get_ctxt ectxt
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2165
        val p = Pretty.str "real_asymp failed to show zeroness of the following expression:"
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2166
        val p = Pretty.chunks [p, Pretty.indent 2 (Syntax.pretty_term ctxt t)]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2167
        val _ = Pretty.writeln p
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2168
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2169
        raise TERM (s, [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2170
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2171
    else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2172
      raise TERM (s, [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2173
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2174
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2175
fun prove_smallo ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2176
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2177
    val (thm2, _, SOME trimmed_thm) = trim_expansion true (SOME Simple_Trim) ectxt (thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2178
    val es = get_exponents (get_expansion thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2179
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2180
    case trim_expansion_while_greater true (SOME es) false NONE ectxt (thm1, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2181
      (thm1, Aborted LESS, thms) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2182
        @{thm compare_expansions_LT} OF [prove_compare_expansions LESS (map snd thms),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2183
          trimmed_thm, thm1, thm2, get_basis_wf_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2184
    | (thm1, Aborted _, _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2185
        print_trimming_error "prove_smallo" ectxt (get_expansion thm1)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2186
    | (thm1, Trimmed _, _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2187
        print_trimming_error "prove_smallo" ectxt (get_expansion thm1)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2188
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2189
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2190
fun prove_bigo ectxt (thm1, thm2, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2191
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2192
    val (thm2, _, SOME trimmed_thm) = trim_expansion true (SOME Simple_Trim) ectxt (thm2, basis)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2193
    val es = get_exponents (get_expansion thm2)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2194
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2195
    case trim_expansion_while_greater false (SOME es) false NONE ectxt (thm1, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2196
      (thm1, Aborted LESS, thms) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2197
        @{thm landau_o.small_imp_big[OF compare_expansions_LT]} OF
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2198
          [prove_compare_expansions LESS (map snd thms), trimmed_thm, thm1, thm2,
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2199
           get_basis_wf_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2200
    | (thm1, Aborted EQ, thms) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2201
        @{thm compare_expansions_EQ_imp_bigo} OF [prove_compare_expansions EQ (map snd thms),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2202
          trimmed_thm, thm1, thm2, get_basis_wf_thm basis]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2203
    | (thm1, Trimmed _, _) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2204
        print_trimming_error "prove_bigo" ectxt (get_expansion thm1)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2205
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2206
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2207
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2208
fun prove_asymptotic_relation_aux mode f ectxt (thm1, thm2, basis) = f (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2209
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2210
    val thm = @{thm expands_to_minus} OF [get_basis_wf_thm basis, thm1, thm2]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2211
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2212
    case ev_zeroness_oracle ectxt (get_expanded_fun thm) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2213
      SOME zero_thm => (EQUAL, zero_thm RS @{thm eventually_diff_zero_imp_eq})
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2214
    | _ => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2215
      case trim_expansion true (SOME mode) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2216
        (thm, IsPos, SOME pos_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2217
          (GREATER, @{thm expands_to_imp_eventually_gt} OF [get_basis_wf_thm basis, thm, pos_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2218
      | (thm, IsNeg, SOME neg_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2219
          (LESS, @{thm expands_to_imp_eventually_lt} OF [get_basis_wf_thm basis, thm, neg_thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2220
      | _ => raise TERM ("Unexpected zeroness result in prove_asymptotic_relation", []))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2221
  end)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2222
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2223
val prove_eventually_greater = prove_asymptotic_relation_aux Pos_Trim snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2224
val prove_eventually_less = prove_asymptotic_relation_aux Neg_Trim snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2225
val prove_asymptotic_relation = prove_asymptotic_relation_aux Sgn_Trim I
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2226
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2227
fun prove_eventually_nonzero ectxt (thm, basis) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2228
  case trim_expansion true (SOME Simple_Trim) ectxt (thm, basis) of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2229
    (thm, _, SOME trimmed_thm) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2230
      @{thm expands_to_imp_eventually_nz} OF [get_basis_wf_thm basis, thm, trimmed_thm]
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2231
  | _ => raise TERM ("prove_eventually_nonzero", [get_expanded_fun thm])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2232
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2233
fun extract_terms (n, strict) ectxt basis t =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2234
  let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2235
    val bs = get_basis_list basis
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2236
    fun mk_constfun c = (Abs ("x", @{typ real}, c))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2237
    val const_0 = mk_constfun @{term "0 :: real"}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2238
    val const_1 = mk_constfun @{term "1 :: real"}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2239
    fun uminus t = Term.betapply (@{term "\<lambda>(f::real\<Rightarrow>real) x. -f x"}, t)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2240
    fun betapply2 a b c = Term.betapply (Term.betapply (a, b), c)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2241
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2242
    fun mk_sum' [] acc = acc
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2243
      | mk_sum' ((t, sgn) :: ts) acc = mk_sum' ts (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2244
          if sgn then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2245
            betapply2 @{term "%(f::real=>real) g x. f x - g x"} acc t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2246
          else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2247
            betapply2 @{term "%(f::real=>real) g x. f x + g x"} acc t)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2248
    fun mk_sum [] = const_0
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2249
      | mk_sum ((t, sgn) :: ts) = mk_sum' ts (if sgn then uminus t else t) 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2250
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2251
    fun mk_mult a b =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2252
      if a aconv const_0 then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2253
        const_0
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2254
      else if b aconv const_0 then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2255
        const_0
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2256
      else if a aconv @{term "\<lambda>_::real. 1 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2257
        b
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2258
      else if b aconv @{term "\<lambda>_::real. 1 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2259
        a
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2260
      else if a aconv @{term "\<lambda>_::real. -1 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2261
        Term.betapply (@{term "\<lambda>(f::real\<Rightarrow>real) x. -f x"}, b)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2262
      else if b aconv @{term "\<lambda>_::real. -1 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2263
        Term.betapply (@{term "\<lambda>(f::real\<Rightarrow>real) x. -f x"}, a)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2264
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2265
        Abs ("x", @{typ real}, @{term "( *) :: real => _"} $
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2266
          (Term.betapply (a, Bound 0)) $ (Term.betapply (b, Bound 0)))
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2267
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2268
    fun mk_powr b e =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2269
      if e = @{term "0 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2270
        const_1
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2271
      else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2272
        let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2273
          val n = HOLogic.dest_number e |> snd
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2274
        in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2275
          if n >= 0 then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2276
            Term.betapply (Term.betapply (@{term "%(b::real=>real) e x. b x ^ e"}, b),
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2277
              HOLogic.mk_number @{typ nat} n)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2278
          else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2279
            Term.betapply (Term.betapply (@{term "%(b::real=>real) e x. b x powr e"}, b), e)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2280
        end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2281
      handle TERM _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2282
        Term.betapply (Term.betapply (@{term "%(b::real=>real) e x. b x powr e"}, b), e)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2283
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2284
    fun mk_scale_elem b e acc =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2285
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2286
        val e = simplify_term ectxt e
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2287
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2288
        if e = @{term "0 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2289
          acc
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2290
        else if e = @{term "1 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2291
          mk_mult acc b
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2292
        else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2293
          mk_mult acc (mk_powr b e)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2294
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2295
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2296
    fun mk_scale_elems [] _ acc = acc
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2297
      | mk_scale_elems (b :: bs) (e :: es) acc =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2298
          mk_scale_elems bs es (mk_scale_elem b e acc)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2299
      | mk_scale_elems _ _ _ = raise Match
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2300
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2301
    fun mk_summand c es =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2302
      let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2303
        val es = mk_scale_elems bs es @{term "\<lambda>_::real. 1 :: real"}
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2304
      in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2305
        case c of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2306
          Const (@{const_name uminus}, _) $ c => ((c, true), es)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2307
        | _ => ((c, false), es)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2308
      end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2309
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2310
    fun go _ _ _ acc 0 = (acc, 0)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2311
      | go 0 es t acc n =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2312
          let
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2313
            val c = simplify_term ectxt t
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2314
          in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2315
            if strict andalso c = @{term "0 :: real"} then
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2316
              (acc, n)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2317
            else
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2318
              (mk_summand c (rev es) :: acc, n - 1)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2319
          end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2320
      | go m es t acc n =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2321
          case Lazy_Eval.whnf ectxt t |> fst of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2322
            Const (@{const_name MS}, _) $ cs $ _ =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2323
              go' m es (simplify_term ectxt cs) acc n
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2324
          | _ => raise TERM("extract_terms", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2325
    and go' _ _ _ acc 0 = (acc, 0)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2326
      | go' m es cs acc n =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2327
          case Lazy_Eval.whnf ectxt cs |> fst of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2328
            Const (@{const_name MSLNil}, _) => (acc, n)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2329
          | Const (@{const_name MSLCons}, _) $ c $ cs => (
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2330
              case Lazy_Eval.whnf ectxt c |> fst |> HOLogic.dest_prod of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2331
                (c, e) =>
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2332
                  case go (m - 1) (e :: es) c acc n of
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2333
                   (acc, n) => go' m es (simplify_term ectxt cs) acc n)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2334
          | _ => raise TERM("extract_terms", [t])
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2335
    val (summands, remaining) = go (basis_size basis) [] t [] (n + 1)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2336
    val (summands, error) =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2337
      if remaining = 0 then (rev (tl summands), SOME (snd (hd summands))) else (rev summands, NONE)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2338
    val summands = map (fn ((c, sgn), es) => (mk_mult (mk_constfun c) es, sgn)) summands
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2339
    val error = Option.map (fn err => Term.betapply (@{term "\<lambda>f::real\<Rightarrow>real. O(f)"}, err)) error
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2340
    val expansion = mk_sum summands 
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2341
  in
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2342
    (expansion, error)
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2343
  end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2344
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2345
end
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2346
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2347
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2348
structure Multiseries_Expansion_Basic : EXPANSION_INTERFACE =
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2349
struct
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2350
open Multiseries_Expansion;
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2351
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2352
type T = expansion_thm
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2353
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2354
val expand_term = expand_term
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2355
val expand_terms = expand_terms
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2356
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2357
val prove_nhds = prove_nhds
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2358
val prove_at_infinity = prove_at_infinity
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2359
val prove_at_top = prove_at_top
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2360
val prove_at_bot = prove_at_bot
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2361
val prove_at_0 = prove_at_0
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2362
val prove_at_right_0 = prove_at_right_0
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2363
val prove_at_left_0 = prove_at_left_0
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2364
val prove_eventually_nonzero = prove_eventually_nonzero
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2365
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2366
val prove_eventually_less = prove_eventually_less
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2367
val prove_eventually_greater = prove_eventually_greater
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2368
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2369
val prove_smallo = prove_smallo
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2370
val prove_bigo = prove_bigo
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2371
val prove_bigtheta = prove_bigtheta
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2372
val prove_asymp_equiv = prove_asymp_equiv
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2373
c55f6f0b3854 Added Real_Asymp package
Manuel Eberl <eberlm@in.tum.de>
parents:
diff changeset
  2374
end