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