src/Pure/Isar/class.ML
changeset 25195 62638dcafe38
parent 25163 f737a88a3248
child 25209 bc21d8de18a9
     1.1 --- a/src/Pure/Isar/class.ML	Thu Oct 25 19:27:52 2007 +0200
     1.2 +++ b/src/Pure/Isar/class.ML	Thu Oct 25 19:27:53 2007 +0200
     1.3 @@ -26,6 +26,8 @@
     1.4    val refresh_syntax: class -> Proof.context -> Proof.context
     1.5    val intro_classes_tac: thm list -> tactic
     1.6    val default_intro_classes_tac: thm list -> tactic
     1.7 +  val prove_subclass: class * class -> thm list -> Proof.context
     1.8 +    -> theory -> theory
     1.9    val print_classes: theory -> unit
    1.10    val uncheck: bool ref
    1.11  
    1.12 @@ -61,6 +63,13 @@
    1.13        (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
    1.14    #> ProofContext.theory_of;
    1.15  
    1.16 +fun prove_interpretation_in tac after_qed (name, expr) =
    1.17 +  Locale.interpretation_in_locale
    1.18 +      (ProofContext.theory after_qed) (name, expr)
    1.19 +  #> Proof.global_terminal_proof
    1.20 +      (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
    1.21 +  #> ProofContext.theory_of;
    1.22 +
    1.23  fun OF_LAST thm1 thm2 = thm1 RSN (Thm.nprems_of thm2, thm2);
    1.24  
    1.25  fun strip_all_ofclass thy sort =
    1.26 @@ -315,29 +324,31 @@
    1.27      (*partial morphism of canonical interpretation*)
    1.28    intro: thm,
    1.29    defs: thm list,
    1.30 -  operations: (string * ((term * (typ * int)) * (term * typ))) list
    1.31 -    (*constant name ~> ((locale term,
    1.32 -        (constant constraint, instantiaton index of class typ)), locale term & typ for uncheck)*)
    1.33 +  operations: (string * (term * (typ * int))) list,
    1.34 +    (*constant name ~> (locale term,
    1.35 +        (constant constraint, instantiaton index of class typ))*)
    1.36 +  unchecks: (term * term) list
    1.37  };
    1.38  
    1.39  fun rep_class_data (ClassData d) = d;
    1.40  fun mk_class_data ((consts, base_sort, inst, morphism, intro),
    1.41 -    (defs, operations)) =
    1.42 +    (defs, (operations, unchecks))) =
    1.43    ClassData { consts = consts, base_sort = base_sort, inst = inst,
    1.44      morphism = morphism, intro = intro, defs = defs,
    1.45 -    operations = operations };
    1.46 +    operations = operations, unchecks = unchecks };
    1.47  fun map_class_data f (ClassData { consts, base_sort, inst, morphism, intro,
    1.48 -    defs, operations }) =
    1.49 +    defs, operations, unchecks }) =
    1.50    mk_class_data (f ((consts, base_sort, inst, morphism, intro),
    1.51 -    (defs, operations)));
    1.52 +    (defs, (operations, unchecks))));
    1.53  fun merge_class_data _ (ClassData { consts = consts,
    1.54      base_sort = base_sort, inst = inst, morphism = morphism, intro = intro,
    1.55 -    defs = defs1, operations = operations1 },
    1.56 +    defs = defs1, operations = operations1, unchecks = unchecks1 },
    1.57    ClassData { consts = _, base_sort = _, inst = _, morphism = _, intro = _,
    1.58 -    defs = defs2, operations = operations2 }) =
    1.59 +    defs = defs2, operations = operations2, unchecks = unchecks2 }) =
    1.60    mk_class_data ((consts, base_sort, inst, morphism, intro),
    1.61      (Thm.merge_thms (defs1, defs2),
    1.62 -      AList.merge (op =) (K true) (operations1, operations2)));
    1.63 +      (AList.merge (op =) (K true) (operations1, operations2),
    1.64 +        Library.merge (op aconv o pairself snd) (unchecks1, unchecks2))));
    1.65  
    1.66  structure ClassData = TheoryDataFun
    1.67  (
    1.68 @@ -383,7 +394,8 @@
    1.69  fun these_operations thy =
    1.70    maps (#operations o the_class_data thy) o ancestry thy;
    1.71  
    1.72 -fun local_operation thy = AList.lookup (op =) o these_operations thy;
    1.73 +fun these_unchecks thy =
    1.74 +  maps (#unchecks o the_class_data thy) o ancestry thy;
    1.75  
    1.76  fun sups_base_sort thy sort =
    1.77    let
    1.78 @@ -435,30 +447,35 @@
    1.79  
    1.80  fun add_class_data ((class, superclasses), (cs, base_sort, inst, phi, intro)) thy =
    1.81    let
    1.82 -    val operations = map (fn (v_ty as (_, ty'), (c, ty)) =>
    1.83 -      (c, ((Free v_ty, (Logic.varifyT ty, 0)), (Free v_ty, ty')))) cs;
    1.84 +    val operations = map (fn (v_ty, (c, ty)) =>
    1.85 +      (c, ((Free v_ty, (Logic.varifyT ty, 0))))) cs;
    1.86 +    val unchecks = map (fn ((v, ty'), (c, _)) =>
    1.87 +      (Free (v, Type.strip_sorts ty'), Const (c, Type.strip_sorts ty'))) cs;
    1.88      val cs = (map o pairself) fst cs;
    1.89      val add_class = Graph.new_node (class,
    1.90 -        mk_class_data ((cs, base_sort, map (SOME o Const) inst, phi, intro), ([], operations)))
    1.91 +        mk_class_data ((cs, base_sort, map (SOME o Const) inst, phi, intro), ([], (operations, unchecks))))
    1.92        #> fold (curry Graph.add_edge class) superclasses;
    1.93    in
    1.94      ClassData.map add_class thy
    1.95    end;
    1.96  
    1.97 -fun register_operation class ((c, (t, t_rev)), some_def) thy =
    1.98 +fun register_operation class (c, ((t, some_t_rev), some_def)) thy =
    1.99    let
   1.100      val ty = Sign.the_const_constraint thy c;
   1.101      val typargs = Sign.const_typargs thy (c, ty);
   1.102      val typidx = find_index (fn TVar ((v, _), _) => Name.aT = v | _ => false) typargs;
   1.103 -    val t_rev' = (map_types o map_atyps)
   1.104 -      (fn ty as TFree (v, _) => if Name.aT = v then TFree (v, []) else ty | ty => ty) t_rev;
   1.105 -    val ty' = Term.fastype_of t_rev';
   1.106 +    fun mk_uncheck t_rev =
   1.107 +      let
   1.108 +        val t_rev' = map_types Type.strip_sorts t_rev;
   1.109 +        val ty' = Term.fastype_of t_rev';
   1.110 +      in (t_rev', Const (c, ty')) end;
   1.111 +    val some_t_rev' = Option.map mk_uncheck some_t_rev;
   1.112    in
   1.113      thy
   1.114      |> (ClassData.map o Graph.map_node class o map_class_data o apsnd)
   1.115 -      (fn (defs, operations) =>
   1.116 +      (fn (defs, (operations, unchecks)) =>
   1.117          (fold cons (the_list some_def) defs,
   1.118 -          (c, ((t, (ty, typidx)), (t_rev', ty'))) :: operations))
   1.119 +          ((c, (t, (ty, typidx))) :: operations, fold cons (the_list some_t_rev') unchecks)))
   1.120    end;
   1.121  
   1.122  
   1.123 @@ -550,6 +567,56 @@
   1.124    ("default", Method.thms_ctxt_args (Method.METHOD oo default_tac),
   1.125      "apply some intro/elim rule")]);
   1.126  
   1.127 +fun subclass_rule thy (sub, sup) =
   1.128 +  let
   1.129 +    val ctxt = Locale.init sub thy;
   1.130 +    val ctxt_thy = ProofContext.init thy;
   1.131 +    val props =
   1.132 +      Locale.global_asms_of thy sup
   1.133 +      |> maps snd
   1.134 +      |> map (ObjectLogic.ensure_propT thy);
   1.135 +    fun tac { prems, context } =
   1.136 +      Locale.intro_locales_tac true context prems
   1.137 +        ORELSE ALLGOALS assume_tac;
   1.138 +  in
   1.139 +    Goal.prove_multi ctxt [] [] props tac
   1.140 +    |> map (Assumption.export false ctxt ctxt_thy)
   1.141 +    |> Variable.export ctxt ctxt_thy
   1.142 +  end;
   1.143 +
   1.144 +fun prove_single_subclass (sub, sup) thms ctxt thy =
   1.145 +  let
   1.146 +    val ctxt_thy = ProofContext.init thy;
   1.147 +    val subclass_rule = Conjunction.intr_balanced thms
   1.148 +      |> Assumption.export false ctxt ctxt_thy
   1.149 +      |> singleton (Variable.export ctxt ctxt_thy);
   1.150 +    val sub_inst = Thm.ctyp_of thy (TVar ((Name.aT, 0), [sub]));
   1.151 +    val sub_ax = #axioms (AxClass.get_info thy sub);
   1.152 +    val classrel =
   1.153 +      #intro (AxClass.get_info thy sup)
   1.154 +      |> Drule.instantiate' [SOME sub_inst] []
   1.155 +      |> OF_LAST (subclass_rule OF sub_ax)
   1.156 +      |> strip_all_ofclass thy (Sign.super_classes thy sup)
   1.157 +      |> Thm.strip_shyps
   1.158 +  in
   1.159 +    thy
   1.160 +    |> AxClass.add_classrel classrel
   1.161 +    |> prove_interpretation_in (ALLGOALS (ProofContext.fact_tac thms))
   1.162 +         I (sub, Locale.Locale sup)
   1.163 +    |> ClassData.map (Graph.add_edge (sub, sup))
   1.164 +  end;
   1.165 +
   1.166 +fun prove_subclass (sub, sup) thms ctxt thy =
   1.167 +  let
   1.168 +    val supclasses = Sign.complete_sort thy [sup]
   1.169 +      |> filter_out (fn class => Sign.subsort thy ([sub], [class]));
   1.170 +    fun transform sup' = subclass_rule thy (sup, sup') |> map (fn thm => thm OF thms);
   1.171 +  in
   1.172 +    thy
   1.173 +    |> fold_rev (fn sup' => prove_single_subclass (sub, sup')
   1.174 +         (transform sup') ctxt) supclasses
   1.175 + end;
   1.176 +
   1.177  
   1.178  (** classes and class target **)
   1.179  
   1.180 @@ -560,7 +627,7 @@
   1.181      constraints: (string * typ) list,
   1.182      base_sort: sort,
   1.183      local_operation: string * typ -> (typ * term) option,
   1.184 -    rews: (term * term) list,
   1.185 +    unchecks: (term * term) list,
   1.186      passed: bool
   1.187    } option;
   1.188    fun init _ = NONE;
   1.189 @@ -568,27 +635,30 @@
   1.190  
   1.191  fun synchronize_syntax thy sups base_sort ctxt =
   1.192    let
   1.193 +    (* constraints *)
   1.194      val operations = these_operations thy sups;
   1.195 -
   1.196 -    (* constraints *)
   1.197 -    fun local_constraint (c, ((_, (ty, _)),_ )) =
   1.198 +    fun local_constraint (c, (_, (ty, _))) =
   1.199        let
   1.200          val ty' = ty
   1.201            |> map_atyps (fn ty as TVar ((v, 0), _) =>
   1.202                 if v = Name.aT then TVar ((v, 0), base_sort) else ty)
   1.203            |> SOME;
   1.204        in (c, ty') end
   1.205 -    val constraints = (map o apsnd) (fst o snd o fst) operations;
   1.206 +    val constraints = (map o apsnd) (fst o snd) operations;
   1.207  
   1.208      (* check phase *)
   1.209      val typargs = Consts.typargs (ProofContext.consts_of ctxt);
   1.210 -    fun check_const (c, ty) ((t, (_, idx)), _) =
   1.211 +    fun check_const (c, ty) (t, (_, idx)) =
   1.212        ((nth (typargs (c, ty)) idx), t);
   1.213      fun local_operation (c_ty as (c, _)) = AList.lookup (op =) operations c
   1.214        |> Option.map (check_const c_ty);
   1.215  
   1.216      (* uncheck phase *)
   1.217 -    val rews = map (fn (c, (_, (t, ty))) => (t, Const (c, ty))) operations;
   1.218 +    val basify =
   1.219 +      map_atyps (fn ty as TFree (v, _) => if Name.aT = v then TFree (v, base_sort)
   1.220 +        else ty | ty => ty);
   1.221 +    val unchecks = these_unchecks thy sups
   1.222 +      |> (map o pairself o map_types) basify;
   1.223    in
   1.224      ctxt
   1.225      |> fold (ProofContext.add_const_constraint o local_constraint) operations
   1.226 @@ -596,7 +666,7 @@
   1.227          constraints = constraints,
   1.228          base_sort = base_sort,
   1.229          local_operation = local_operation,
   1.230 -        rews = rews,
   1.231 +        unchecks = unchecks,
   1.232          passed = false
   1.233        }))
   1.234    end;
   1.235 @@ -608,9 +678,9 @@
   1.236    in synchronize_syntax thy [class] base_sort ctxt end;
   1.237  
   1.238  val mark_passed = (ClassSyntax.map o Option.map)
   1.239 -  (fn { constraints, base_sort, local_operation, rews, passed } =>
   1.240 +  (fn { constraints, base_sort, local_operation, unchecks, passed } =>
   1.241      { constraints = constraints, base_sort = base_sort,
   1.242 -      local_operation = local_operation, rews = rews, passed = true });
   1.243 +      local_operation = local_operation, unchecks = unchecks, passed = true });
   1.244  
   1.245  fun sort_term_check ts ctxt =
   1.246    let
   1.247 @@ -647,9 +717,9 @@
   1.248    let
   1.249      (*FIXME abbreviations*)
   1.250      val thy = ProofContext.theory_of ctxt;
   1.251 -    val rews = (#rews o the o ClassSyntax.get) ctxt;
   1.252 +    val unchecks = (#unchecks o the o ClassSyntax.get) ctxt;
   1.253      val ts' = if ! uncheck
   1.254 -      then map (Pattern.rewrite_term thy rews []) ts else ts;
   1.255 +      then map (Pattern.rewrite_term thy unchecks []) ts else ts;
   1.256    in if eq_list (op aconv) (ts, ts') then NONE else SOME (ts', ctxt) end;
   1.257  
   1.258  fun init_ctxt thy sups base_sort ctxt =
   1.259 @@ -802,6 +872,7 @@
   1.260      val prfx = class_prefix class;
   1.261      val thy' = thy |> Sign.add_path prfx;
   1.262      val phi = morphism thy' class;
   1.263 +    val base_sort = (#base_sort o the_class_data thy) class;
   1.264  
   1.265      val c' = Sign.full_name thy' c;
   1.266      val dict' = (map_types Logic.unvarifyT o Morphism.term phi) dict;
   1.267 @@ -817,7 +888,7 @@
   1.268      |> Thm.add_def false (c, def_eq)
   1.269      |>> Thm.symmetric
   1.270      |-> (fn def => class_interpretation class [def] [Thm.prop_of def]
   1.271 -          #> register_operation class ((c', (dict, dict')), SOME (Thm.varifyT def)))
   1.272 +          #> register_operation class (c', ((dict, SOME dict'), SOME (Thm.varifyT def))))
   1.273      |> Sign.restore_naming thy
   1.274      |> Sign.add_const_constraint (c', SOME ty')
   1.275    end;
   1.276 @@ -834,8 +905,7 @@
   1.277      val c' = Sign.full_name thy' c;
   1.278      val rews = map (Logic.dest_equals o Thm.prop_of) (these_defs thy' [class])
   1.279      val rhs' = (Pattern.rewrite_term thy rews [] o Morphism.term phi) rhs;
   1.280 -    val rhs'' = map_types Logic.unvarifyT rhs';
   1.281 -    val ty' = Term.fastype_of rhs'';
   1.282 +    val ty' = (Logic.unvarifyT o Term.fastype_of) rhs';
   1.283  
   1.284      val c'' = NameSpace.full (Sign.naming_of thy' |> NameSpace.add_path prfx) c;
   1.285      val ty'' = (Type.strip_sorts o Logic.unvarifyT) (Sign.the_const_constraint thy' c'');
   1.286 @@ -846,7 +916,7 @@
   1.287      |> Sign.add_abbrev (#1 prmode) pos (c, map_types Type.strip_sorts rhs') |> snd
   1.288      |> Sign.add_const_constraint (c', SOME ty')
   1.289      |> Sign.notation true prmode [(Const (c', ty'), mx)]
   1.290 -    |> register_operation class ((c', (rhs, rhs'')), NONE)
   1.291 +    |> register_operation class (c', ((rhs, NONE), NONE))
   1.292      |> Sign.restore_naming thy
   1.293    end;
   1.294