src/Pure/Isar/calculation.ML
author wenzelm
Wed Mar 15 18:25:42 2000 +0100 (2000-03-15)
changeset 8461 2693a3a9fcc1
parent 8300 4c3f83414de3
child 8562 ce0e2b8e8844
permissions -rw-r--r--
tuned comment;
wenzelm@6778
     1
(*  Title:      Pure/Isar/calculation.ML
wenzelm@6778
     2
    ID:         $Id$
wenzelm@6778
     3
    Author:     Markus Wenzel, TU Muenchen
wenzelm@6778
     4
wenzelm@6778
     5
Support for calculational proofs.
wenzelm@6778
     6
*)
wenzelm@6778
     7
wenzelm@6778
     8
signature CALCULATION =
wenzelm@6778
     9
sig
wenzelm@6778
    10
  val print_global_rules: theory -> unit
wenzelm@6778
    11
  val print_local_rules: Proof.context -> unit
wenzelm@6778
    12
  val trans_add_global: theory attribute
wenzelm@6778
    13
  val trans_del_global: theory attribute
wenzelm@6778
    14
  val trans_add_local: Proof.context attribute
wenzelm@6778
    15
  val trans_del_local: Proof.context attribute
wenzelm@7414
    16
  val also: thm list option -> (thm list -> unit) -> Proof.state -> Proof.state Seq.seq
wenzelm@7414
    17
  val finally: thm list option -> (thm list -> unit) -> Proof.state -> Proof.state Seq.seq
wenzelm@6778
    18
  val setup: (theory -> theory) list
wenzelm@6778
    19
end;
wenzelm@6778
    20
wenzelm@6778
    21
structure Calculation: CALCULATION =
wenzelm@6778
    22
struct
wenzelm@6778
    23
wenzelm@6778
    24
(** global and local calculation data **)
wenzelm@6778
    25
wenzelm@8300
    26
(* theory data kind 'Isar/calculation' *)
wenzelm@6778
    27
wenzelm@8300
    28
fun print_rules rs = Pretty.writeln (Pretty.big_list "calculation rules:"
wenzelm@8300
    29
  (map Display.pretty_thm (NetRules.rules rs)));
wenzelm@6778
    30
wenzelm@6778
    31
structure GlobalCalculationArgs =
wenzelm@6778
    32
struct
wenzelm@6778
    33
  val name = "Isar/calculation";
wenzelm@8300
    34
  type T = thm NetRules.T
wenzelm@6778
    35
wenzelm@8300
    36
  val empty = NetRules.init_elim;
wenzelm@6778
    37
  val copy = I;
wenzelm@6778
    38
  val prep_ext = I;
wenzelm@8300
    39
  val merge = NetRules.merge;
wenzelm@6778
    40
  fun print _ = print_rules;
wenzelm@6778
    41
end;
wenzelm@6778
    42
wenzelm@6778
    43
structure GlobalCalculation = TheoryDataFun(GlobalCalculationArgs);
wenzelm@6778
    44
val print_global_rules = GlobalCalculation.print;
wenzelm@6778
    45
wenzelm@6778
    46
wenzelm@6778
    47
(* proof data kind 'Isar/calculation' *)
wenzelm@6778
    48
wenzelm@6778
    49
structure LocalCalculationArgs =
wenzelm@6778
    50
struct
wenzelm@6778
    51
  val name = "Isar/calculation";
wenzelm@8300
    52
  type T = thm NetRules.T * (thm list * int) option;
wenzelm@6778
    53
wenzelm@6778
    54
  fun init thy = (GlobalCalculation.get thy, None);
wenzelm@8300
    55
  fun print _ (rs, _) = print_rules rs;
wenzelm@6778
    56
end;
wenzelm@6778
    57
wenzelm@6778
    58
structure LocalCalculation = ProofDataFun(LocalCalculationArgs);
wenzelm@6787
    59
val get_local_rules = #1 o LocalCalculation.get_st;
wenzelm@6778
    60
val print_local_rules = LocalCalculation.print;
wenzelm@6778
    61
wenzelm@6778
    62
wenzelm@6778
    63
(* access calculation *)
wenzelm@6778
    64
wenzelm@6778
    65
fun get_calculation state =
wenzelm@6787
    66
  (case #2 (LocalCalculation.get_st state) of
wenzelm@6778
    67
    None => None
wenzelm@7414
    68
  | Some (thms, lev) => if lev = Proof.level state then Some thms else None);
wenzelm@6778
    69
wenzelm@7414
    70
fun put_calculation thms state =
wenzelm@7414
    71
  LocalCalculation.put_st (get_local_rules state, Some (thms, Proof.level state)) state;
wenzelm@6778
    72
wenzelm@6787
    73
fun reset_calculation state =
wenzelm@6787
    74
  LocalCalculation.put_st (get_local_rules state, None) state;
wenzelm@6787
    75
wenzelm@6778
    76
wenzelm@6778
    77
wenzelm@6778
    78
(** attributes **)
wenzelm@6778
    79
wenzelm@6778
    80
(* trans add/del *)
wenzelm@6778
    81
wenzelm@6778
    82
fun mk_att f g (x, thm) = (f (g thm) x, thm);
wenzelm@6778
    83
wenzelm@8300
    84
val trans_add_global = mk_att GlobalCalculation.map NetRules.insert;
wenzelm@8300
    85
val trans_del_global = mk_att GlobalCalculation.map NetRules.delete;
wenzelm@8300
    86
val trans_add_local = mk_att LocalCalculation.map (Library.apfst o NetRules.insert);
wenzelm@8300
    87
val trans_del_local = mk_att LocalCalculation.map (Library.apfst o NetRules.delete);
wenzelm@6778
    88
wenzelm@6778
    89
wenzelm@6778
    90
(* concrete syntax *)
wenzelm@6778
    91
wenzelm@6778
    92
val transN = "trans";
wenzelm@6778
    93
val addN = "add";
wenzelm@6778
    94
val delN = "del";
wenzelm@6778
    95
wenzelm@6778
    96
fun trans_att add del =
wenzelm@6778
    97
  Attrib.syntax (Scan.lift (Args.$$$ addN >> K add || Args.$$$ delN >> K del || Scan.succeed add));
wenzelm@6778
    98
wenzelm@6778
    99
val trans_attr =
wenzelm@6778
   100
  (trans_att trans_add_global trans_del_global, trans_att trans_add_local trans_del_local);
wenzelm@6778
   101
wenzelm@6778
   102
wenzelm@6787
   103
wenzelm@6778
   104
(** proof commands **)
wenzelm@6778
   105
wenzelm@6778
   106
val calculationN = "calculation";
wenzelm@6778
   107
wenzelm@6877
   108
fun calculate final opt_rules print state =
wenzelm@6778
   109
  let
wenzelm@6903
   110
    fun err_if b msg = if b then raise Proof.STATE (msg, state) else ();
wenzelm@7414
   111
    val facts = Proof.the_facts state;
wenzelm@7414
   112
wenzelm@7554
   113
    val eq_prop = op aconv o pairself (#prop o Thm.rep_thm);
wenzelm@7554
   114
    fun differ thms thms' = not (Library.equal_lists eq_prop (thms, thms'));
wenzelm@8300
   115
wenzelm@7414
   116
    fun combine thms =
wenzelm@8300
   117
      let
wenzelm@8300
   118
        val ths = thms @ facts;
wenzelm@8300
   119
        val rs = NetRules.inserts (if_none opt_rules []) (get_local_rules state);
wenzelm@8300
   120
        val rules =
wenzelm@8300
   121
          (case ths of [] => NetRules.rules rs
wenzelm@8300
   122
          | th :: _ => NetRules.may_unify rs (Logic.strip_assums_concl (#prop (Thm.rep_thm th))));
wenzelm@8300
   123
        val ruleq = Seq.of_list rules;
wenzelm@8300
   124
      in Seq.map Library.single (Seq.flat (Seq.map (Method.multi_resolve ths) ruleq)) end;
wenzelm@7414
   125
wenzelm@6903
   126
    val (initial, calculations) =
wenzelm@6778
   127
      (case get_calculation state of
wenzelm@7414
   128
        None => (true, Seq.single facts)
wenzelm@7414
   129
      | Some thms => (false, Seq.filter (differ thms) (combine thms)))
wenzelm@6778
   130
  in
wenzelm@6903
   131
    err_if (initial andalso final) "No calculation yet";
wenzelm@6903
   132
    err_if (initial andalso is_some opt_rules) "Initial calculation -- no rules to be given";
wenzelm@6782
   133
    calculations |> Seq.map (fn calc =>
wenzelm@6782
   134
      (print calc;
wenzelm@6787
   135
        (if final then
wenzelm@6787
   136
          state
wenzelm@6787
   137
          |> reset_calculation
wenzelm@7600
   138
          |> Proof.reset_thms calculationN
wenzelm@7414
   139
          |> Proof.simple_have_thms "" calc
wenzelm@6787
   140
          |> Proof.chain
wenzelm@6787
   141
        else
wenzelm@6787
   142
          state
wenzelm@6787
   143
          |> put_calculation calc
wenzelm@7414
   144
          |> Proof.simple_have_thms calculationN calc
wenzelm@6787
   145
          |> Proof.reset_facts)))
wenzelm@6778
   146
  end;
wenzelm@6778
   147
wenzelm@6782
   148
fun also print = calculate false print;
wenzelm@6782
   149
fun finally print = calculate true print;
wenzelm@6778
   150
wenzelm@6778
   151
wenzelm@6778
   152
wenzelm@6778
   153
(** theory setup **)
wenzelm@6778
   154
wenzelm@6778
   155
val setup = [GlobalCalculation.init, LocalCalculation.init,
wenzelm@8461
   156
  Attrib.add_attributes [(transN, trans_attr, "declare transitivity rule")]];
wenzelm@6778
   157
wenzelm@6778
   158
wenzelm@6778
   159
end;