explicit history for equations; tuned
authorhaftmann
Mon Oct 27 16:15:50 2008 +0100 (2008-10-27)
changeset 28695f7a06d7284c8
parent 28694 4e9edaef64dc
child 28696 f1701105d651
explicit history for equations; tuned
src/Pure/Isar/code.ML
     1.1 --- a/src/Pure/Isar/code.ML	Mon Oct 27 16:15:49 2008 +0100
     1.2 +++ b/src/Pure/Isar/code.ML	Mon Oct 27 16:15:50 2008 +0100
     1.3 @@ -10,7 +10,6 @@
     1.4  sig
     1.5    val add_eqn: thm -> theory -> theory
     1.6    val add_nonlinear_eqn: thm -> theory -> theory
     1.7 -  val add_liberal_eqn: thm -> theory -> theory
     1.8    val add_default_eqn: thm -> theory -> theory
     1.9    val add_default_eqn_attr: Attrib.src
    1.10    val del_eqn: thm -> theory -> theory
    1.11 @@ -19,9 +18,6 @@
    1.12    val map_pre: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory
    1.13    val map_post: (MetaSimplifier.simpset -> MetaSimplifier.simpset) -> theory -> theory
    1.14    val add_inline: thm -> theory -> theory
    1.15 -  val del_inline: thm -> theory -> theory
    1.16 -  val add_post: thm -> theory -> theory
    1.17 -  val del_post: thm -> theory -> theory
    1.18    val add_functrans: string * (theory -> (thm * bool) list -> (thm * bool) list option) -> theory -> theory
    1.19    val del_functrans: string -> theory -> theory
    1.20    val add_datatype: (string * typ) list -> theory -> theory
    1.21 @@ -115,7 +111,10 @@
    1.22  
    1.23  (** logical and syntactical specification of executable code **)
    1.24  
    1.25 -(* defining equations with linear flag, default flag and lazy theorems *)
    1.26 +(* defining equations *)
    1.27 +
    1.28 +type eqns = bool * (thm * bool) list Lazy.T;
    1.29 +  (*default flag, theorems with linear flag (perhaps lazy)*)
    1.30  
    1.31  fun pretty_lthms ctxt r = case Lazy.peek r
    1.32   of SOME thms => map (ProofContext.pretty_thm ctxt o fst) (Exn.release thms)
    1.33 @@ -149,45 +148,38 @@
    1.34  
    1.35  fun del_thm thm = (apsnd o Lazy.map_force) (remove (eq_fst Thm.eq_thm_prop) (thm, true));
    1.36  
    1.37 -fun merge_defthms ((true, _), defthms2) = defthms2
    1.38 -  | merge_defthms (defthms1 as (false, _), (true, _)) = defthms1
    1.39 -  | merge_defthms ((false, _), defthms2 as (false, _)) = defthms2;
    1.40 -
    1.41 -
    1.42 -(* syntactic datatypes *)
    1.43 -
    1.44 -val eq_string = op = : string * string -> bool;
    1.45 -
    1.46 -fun eq_dtyp ((vs1, cs1), (vs2, cs2)) = 
    1.47 -  gen_eq_set (eq_pair eq_string (gen_eq_set eq_string)) (vs1, vs2)
    1.48 -    andalso gen_eq_set (eq_fst eq_string) (cs1, cs2);
    1.49 -
    1.50 -fun merge_dtyps (tabs as (tab1, tab2)) =
    1.51 -  let
    1.52 -    fun join _ (cos as (_, cos2)) = if eq_dtyp cos then raise Symtab.SAME else cos2;
    1.53 -  in Symtab.join join tabs end;
    1.54 -
    1.55  
    1.56  (* specification data *)
    1.57  
    1.58  datatype spec = Spec of {
    1.59 -  eqns: (bool * (thm * bool) list Lazy.T) Symtab.table,
    1.60 -  dtyps: ((string * sort) list * (string * typ list) list) Symtab.table,
    1.61 +  concluded_history: bool,
    1.62 +  eqns: ((bool * eqns) * (serial * eqns) list) Symtab.table
    1.63 +    (*with explicit history*),
    1.64 +  dtyps: ((serial * ((string * sort) list * (string * typ list) list)) list) Symtab.table
    1.65 +    (*with explicit history*),
    1.66    cases: (int * string list) Symtab.table * unit Symtab.table
    1.67  };
    1.68  
    1.69 -fun mk_spec (eqns, (dtyps, cases)) =
    1.70 -  Spec { eqns = eqns, dtyps = dtyps, cases = cases };
    1.71 -fun map_spec f (Spec { eqns = eqns, dtyps = dtyps, cases = cases }) =
    1.72 -  mk_spec (f (eqns, (dtyps, cases)));
    1.73 -fun merge_spec (Spec { eqns = eqns1, dtyps = dtyps1, cases = (cases1, undefs1) },
    1.74 -  Spec { eqns = eqns2, dtyps = dtyps2, cases = (cases2, undefs2) }) =
    1.75 +fun mk_spec ((concluded_history, eqns), (dtyps, cases)) =
    1.76 +  Spec { concluded_history = concluded_history, eqns = eqns, dtyps = dtyps, cases = cases };
    1.77 +fun map_spec f (Spec { concluded_history = concluded_history, eqns = eqns,
    1.78 +  dtyps = dtyps, cases = cases }) =
    1.79 +  mk_spec (f ((concluded_history, eqns), (dtyps, cases)));
    1.80 +fun merge_spec (Spec { concluded_history = _, eqns = eqns1, dtyps = dtyps1, cases = (cases1, undefs1) },
    1.81 +  Spec { concluded_history = _, eqns = eqns2, dtyps = dtyps2, cases = (cases2, undefs2) }) =
    1.82    let
    1.83 -    val eqns = Symtab.join (K merge_defthms) (eqns1, eqns2);
    1.84 -    val dtyps = merge_dtyps (dtyps1, dtyps2);
    1.85 +    fun merge_eqns ((_, history1), (_, history2)) =
    1.86 +      let
    1.87 +        val raw_history = AList.merge (op =) (K true) (history1, history2)
    1.88 +        val filtered_history = filter_out (fst o snd) raw_history
    1.89 +        val history = if null filtered_history
    1.90 +          then raw_history else filtered_history;
    1.91 +      in ((false, (snd o hd) history), history) end;
    1.92 +    val eqns = Symtab.join (K merge_eqns) (eqns1, eqns2);
    1.93 +    val dtyps = Symtab.join (K (AList.merge (op =) (K true))) (dtyps1, dtyps2);
    1.94      val cases = (Symtab.merge (K true) (cases1, cases2),
    1.95        Symtab.merge (K true) (undefs1, undefs2));
    1.96 -  in mk_spec (eqns, (dtyps, cases)) end;
    1.97 +  in mk_spec ((false, eqns), (dtyps, cases)) end;
    1.98  
    1.99  
   1.100  (* pre- and postprocessor *)
   1.101 @@ -229,7 +221,7 @@
   1.102      val spec = merge_spec (spec1, spec2);
   1.103    in mk_exec (thmproc, spec) end;
   1.104  val empty_exec = mk_exec (mk_thmproc ((MetaSimplifier.empty_ss, MetaSimplifier.empty_ss), []),
   1.105 -  mk_spec (Symtab.empty, (Symtab.empty, (Symtab.empty, Symtab.empty))));
   1.106 +  mk_spec ((false, Symtab.empty), (Symtab.empty, (Symtab.empty, Symtab.empty))));
   1.107  
   1.108  fun the_thmproc (Exec { thmproc = Thmproc x, ...}) = x;
   1.109  fun the_spec (Exec { spec = Spec x, ...}) = x;
   1.110 @@ -237,7 +229,8 @@
   1.111  val the_dtyps = #dtyps o the_spec;
   1.112  val the_cases = #cases o the_spec;
   1.113  val map_thmproc = map_exec o apfst o map_thmproc;
   1.114 -val map_eqns = map_exec o apsnd o map_spec o apfst;
   1.115 +val map_concluded_history = map_exec o apsnd o map_spec o apfst o apfst;
   1.116 +val map_eqns = map_exec o apsnd o map_spec o apfst o apsnd;
   1.117  val map_dtyps = map_exec o apsnd o map_spec o apsnd o apfst;
   1.118  val map_cases = map_exec o apsnd o map_spec o apsnd o apsnd;
   1.119  
   1.120 @@ -297,8 +290,6 @@
   1.121      (merge_exec (exec1, exec2), ref empty_data);
   1.122  );
   1.123  
   1.124 -val _ = Context.>> (Context.map_theory CodeData.init);
   1.125 -
   1.126  fun thy_data f thy = f ((snd o CodeData.get) thy);
   1.127  
   1.128  fun get_ensure_init kind data_ref =
   1.129 @@ -326,6 +317,34 @@
   1.130  val purge_data = (CodeData.map o apsnd) (K (ref empty_data));
   1.131  
   1.132  
   1.133 +(* tackling equation history *)
   1.134 +
   1.135 +fun get_eqns thy c =
   1.136 +  Symtab.lookup ((the_eqns o the_exec) thy) c
   1.137 +  |> Option.map (Lazy.force o snd o snd o fst)
   1.138 +  |> these;
   1.139 +
   1.140 +fun continue_history thy = if (#concluded_history o the_spec o the_exec) thy
   1.141 +  then thy
   1.142 +    |> (CodeData.map o apfst o map_concluded_history) (K false)
   1.143 +    |> SOME
   1.144 +  else NONE;
   1.145 +
   1.146 +fun conclude_history thy = if (#concluded_history o the_spec o the_exec) thy
   1.147 +  then NONE
   1.148 +  else thy
   1.149 +    |> (CodeData.map o apfst)
   1.150 +        ((map_eqns o Symtab.map) (fn ((changed, current), history) =>
   1.151 +          ((false, current),
   1.152 +            if changed then (serial (), current) :: history else history))
   1.153 +        #> map_concluded_history (K true))
   1.154 +    |> SOME;
   1.155 +
   1.156 +val _ = Context.>> (Context.map_theory (CodeData.init
   1.157 +  #> Theory.at_begin continue_history
   1.158 +  #> Theory.at_end conclude_history));
   1.159 +
   1.160 +
   1.161  (* access to data dependent on abstract executable content *)
   1.162  
   1.163  fun get_data (kind, _, dest) = thy_data (get_ensure_init kind #> dest);
   1.164 @@ -380,10 +399,11 @@
   1.165      val eqns = the_eqns exec
   1.166        |> Symtab.dest
   1.167        |> (map o apfst) (Code_Unit.string_of_const thy)
   1.168 +      |> (map o apsnd) (snd o fst)
   1.169        |> sort (string_ord o pairself fst);
   1.170      val dtyps = the_dtyps exec
   1.171        |> Symtab.dest
   1.172 -      |> map (fn (dtco, (vs, cos)) =>
   1.173 +      |> map (fn (dtco, (_, (vs, cos)) :: _) =>
   1.174            (Syntax.string_of_typ_global thy (Type (dtco, map TFree vs)), cos))
   1.175        |> sort (string_ord o pairself fst)
   1.176    in
   1.177 @@ -455,7 +475,6 @@
   1.178  
   1.179  fun mk_eqn thy linear =
   1.180    Code_Unit.error_thm ((if linear then check_linear else I) o Code_Unit.mk_eqn thy);
   1.181 -fun mk_liberal_eqn thy = Code_Unit.warning_thm (check_linear o Code_Unit.mk_eqn thy);
   1.182  fun mk_syntactic_eqn thy = Code_Unit.warning_thm (Code_Unit.mk_eqn thy);
   1.183  fun mk_default_eqn thy = Code_Unit.try_thm (check_linear o Code_Unit.mk_eqn thy);
   1.184  
   1.185 @@ -470,9 +489,7 @@
   1.186      val classparam_constraints = Sorts.complete_sort algebra [class]
   1.187        |> maps (map fst o these o try (#params o AxClass.get_info thy))
   1.188        |> map_filter (fn c => try (AxClass.param_of_inst thy) (c, tyco))
   1.189 -      |> map (Symtab.lookup ((the_eqns o the_exec) thy))
   1.190 -      |> (map o Option.map) (map fst o Lazy.force o snd)
   1.191 -      |> maps these
   1.192 +      |> maps (map fst o get_eqns thy)
   1.193        |> map (map (snd o dest_TVar) o Sign.const_typargs thy o Code_Unit.const_typ_eqn);
   1.194      val inter_sorts = map2 (curry (Sorts.inter_sort algebra));
   1.195    in fold inter_sorts classparam_constraints base_constraints end;
   1.196 @@ -502,17 +519,16 @@
   1.197    else error ("No such " ^ msg ^ ": " ^ quote key);
   1.198  
   1.199  fun get_datatype thy tyco =
   1.200 -  case Symtab.lookup ((the_dtyps o the_exec) thy) tyco
   1.201 -   of SOME spec => spec
   1.202 -    | NONE => Sign.arity_number thy tyco
   1.203 +  case these (Symtab.lookup ((the_dtyps o the_exec) thy) tyco)
   1.204 +   of (_, spec) :: _ => spec
   1.205 +    | [] => Sign.arity_number thy tyco
   1.206          |> Name.invents Name.context Name.aT
   1.207          |> map (rpair [])
   1.208          |> rpair [];
   1.209  
   1.210  fun get_datatype_of_constr thy c =
   1.211    case (snd o strip_type o Sign.the_const_type thy) c
   1.212 -   of Type (tyco, _) => if member (op =)
   1.213 -       ((the_default [] o Option.map (map fst o snd) o Symtab.lookup ((the_dtyps o the_exec) thy)) tyco) c
   1.214 +   of Type (tyco, _) => if member (op =) ((map fst o snd o get_datatype thy) tyco) c
   1.215         then SOME tyco else NONE
   1.216      | _ => NONE;
   1.217  
   1.218 @@ -525,55 +541,49 @@
   1.219          in SOME (Logic.varifyT ty) end
   1.220      | NONE => NONE;
   1.221  
   1.222 -val get_case_data = Symtab.lookup o fst o the_cases o the_exec;
   1.223 +fun change_eqns delete c f = (map_exec_purge (SOME [c]) o map_eqns
   1.224 +  o (if delete then Symtab.map_entry c else Symtab.map_default (c, ((false, (true, Lazy.value [])), [])))
   1.225 +    o apfst) (fn (_, eqns) => (true, f eqns));
   1.226  
   1.227 -val is_undefined = Symtab.defined o snd o the_cases o the_exec;
   1.228 -
   1.229 -fun gen_add_eqn linear strict default thm thy =
   1.230 -  case (if strict then SOME o mk_eqn thy linear else mk_liberal_eqn thy) thm
   1.231 +fun gen_add_eqn linear default thm thy =
   1.232 +  case (if default then mk_default_eqn thy else SOME o mk_eqn thy linear) thm
   1.233     of SOME (thm, _) =>
   1.234          let
   1.235            val c = Code_Unit.const_eqn thm;
   1.236 -          val _ = if strict andalso (is_some o AxClass.class_of_param thy) c
   1.237 +          val _ = if not default andalso (is_some o AxClass.class_of_param thy) c
   1.238              then error ("Rejected polymorphic equation for overloaded constant:\n"
   1.239                ^ Display.string_of_thm thm)
   1.240              else ();
   1.241 -          val _ = if strict andalso (is_some o get_datatype_of_constr thy) c
   1.242 +          val _ = if not default andalso (is_some o get_datatype_of_constr thy) c
   1.243              then error ("Rejected equation for datatype constructor:\n"
   1.244                ^ Display.string_of_thm thm)
   1.245              else ();
   1.246 -        in
   1.247 -          (map_exec_purge (SOME [c]) o map_eqns) (Symtab.map_default
   1.248 -            (c, (true, Lazy.value [])) (add_thm thy default (thm, linear))) thy
   1.249 -        end
   1.250 +        in change_eqns false c (add_thm thy default (thm, linear)) thy end
   1.251      | NONE => thy;
   1.252  
   1.253 -val add_eqn = gen_add_eqn true true false;
   1.254 -val add_liberal_eqn = gen_add_eqn true false false;
   1.255 -val add_default_eqn = gen_add_eqn true false true;
   1.256 -val add_nonlinear_eqn = gen_add_eqn false true false;
   1.257 -
   1.258 -fun del_eqn thm thy = case mk_syntactic_eqn thy thm
   1.259 - of SOME (thm, _) => let val c = Code_Unit.const_eqn thm
   1.260 -      in map_exec_purge (SOME [c]) (map_eqns (Symtab.map_entry c (del_thm thm))) thy end
   1.261 -  | NONE => thy;
   1.262 -
   1.263 -fun del_eqns c = map_exec_purge (SOME [c])
   1.264 -  (map_eqns (Symtab.map_entry c (K (false, Lazy.value []))));
   1.265 +val add_eqn = gen_add_eqn true false;
   1.266 +val add_default_eqn = gen_add_eqn true true;
   1.267 +val add_nonlinear_eqn = gen_add_eqn false false;
   1.268  
   1.269  fun add_eqnl (c, lthms) thy =
   1.270    let
   1.271      val lthms' = certificate thy
   1.272        (fn thy => map (Code_Unit.assert_linear) o certify_const thy c) lthms;
   1.273 -  in
   1.274 -    map_exec_purge (SOME [c])
   1.275 -      (map_eqns (Symtab.map_default (c, (true, Lazy.value []))
   1.276 -        (add_lthms lthms'))) thy
   1.277 -  end;
   1.278 +  in change_eqns false c (add_lthms lthms') thy end;
   1.279  
   1.280  val add_default_eqn_attr = Attrib.internal (fn _ => Thm.declaration_attribute
   1.281    (fn thm => Context.mapping (add_default_eqn thm) I));
   1.282  
   1.283 +fun del_eqn thm thy = case mk_syntactic_eqn thy thm
   1.284 + of SOME (thm, _) => change_eqns true (Code_Unit.const_eqn thm) (del_thm thm) thy
   1.285 +  | NONE => thy;
   1.286 +
   1.287 +fun del_eqns c = change_eqns true c (K (false, Lazy.value []));
   1.288 +
   1.289 +val get_case_data = Symtab.lookup o fst o the_cases o the_exec;
   1.290 +
   1.291 +val is_undefined = Symtab.defined o snd o the_cases o the_exec;
   1.292 +
   1.293  structure TypeInterpretation = InterpretationFun(type T = string * serial val eq = eq_snd (op =) : T * T -> bool);
   1.294  
   1.295  fun add_datatype raw_cs thy =
   1.296 @@ -581,12 +591,13 @@
   1.297      val cs = map (fn c_ty as (_, ty) => (AxClass.unoverload_const thy c_ty, ty)) raw_cs;
   1.298      val (tyco, vs_cos) = Code_Unit.constrset_of_consts thy cs;
   1.299      val cs' = map fst (snd vs_cos);
   1.300 -    val purge_cs = case Symtab.lookup ((the_dtyps o the_exec) thy) tyco
   1.301 -     of SOME (vs, cos) => if null cos then NONE else SOME (cs' @ map fst cos)
   1.302 -      | NONE => NONE;
   1.303 +    val purge_cs = case get_datatype thy tyco
   1.304 +     of (_, []) => NONE
   1.305 +      | (_, cos) => SOME (cs' @ map fst cos);
   1.306    in
   1.307      thy
   1.308 -    |> map_exec_purge purge_cs (map_dtyps (Symtab.update (tyco, vs_cos))
   1.309 +    |> map_exec_purge purge_cs
   1.310 +        ((map_dtyps o Symtab.map_default (tyco, [])) (cons (serial (), vs_cos))
   1.311          #> map_eqns (fold (Symtab.delete_safe o fst) cs))
   1.312      |> TypeInterpretation.data (tyco, serial ())
   1.313    end;
   1.314 @@ -646,12 +657,6 @@
   1.315  
   1.316  local
   1.317  
   1.318 -fun get_eqns thy c =
   1.319 -  Symtab.lookup ((the_eqns o the_exec) thy) c
   1.320 -  |> Option.map (Lazy.force o snd)
   1.321 -  |> these
   1.322 -  |> (map o apfst) (Thm.transfer thy);
   1.323 -
   1.324  fun apply_functrans thy c _ [] = []
   1.325    | apply_functrans thy c [] eqns = eqns
   1.326    | apply_functrans thy c functrans eqns = eqns
   1.327 @@ -709,6 +714,7 @@
   1.328  
   1.329  fun these_raw_eqns thy c =
   1.330    get_eqns thy c
   1.331 +  |> (map o apfst) (Thm.transfer thy)
   1.332    |> burrow_fst (common_typ_eqns thy);
   1.333  
   1.334  fun these_eqns thy c =
   1.335 @@ -717,6 +723,7 @@
   1.336        o the_thmproc o the_exec) thy;
   1.337    in
   1.338      get_eqns thy c
   1.339 +    |> (map o apfst) (Thm.transfer thy)
   1.340      |> preprocess thy functrans c
   1.341    end;
   1.342