src/Pure/Isar/class.ML
changeset 25195 62638dcafe38
parent 25163 f737a88a3248
child 25209 bc21d8de18a9
equal deleted inserted replaced
25194:37a1743f0fc3 25195:62638dcafe38
    24   val add_syntactic_const: string -> Syntax.mode -> Markup.property list
    24   val add_syntactic_const: string -> Syntax.mode -> Markup.property list
    25     -> (string * mixfix) * term -> theory -> theory
    25     -> (string * mixfix) * term -> theory -> theory
    26   val refresh_syntax: class -> Proof.context -> Proof.context
    26   val refresh_syntax: class -> Proof.context -> Proof.context
    27   val intro_classes_tac: thm list -> tactic
    27   val intro_classes_tac: thm list -> tactic
    28   val default_intro_classes_tac: thm list -> tactic
    28   val default_intro_classes_tac: thm list -> tactic
       
    29   val prove_subclass: class * class -> thm list -> Proof.context
       
    30     -> theory -> theory
    29   val print_classes: theory -> unit
    31   val print_classes: theory -> unit
    30   val uncheck: bool ref
    32   val uncheck: bool ref
    31 
    33 
    32   val instance_arity: (theory -> theory) -> arity list -> theory -> Proof.state
    34   val instance_arity: (theory -> theory) -> arity list -> theory -> Proof.state
    33   val instance: arity list -> ((bstring * Attrib.src list) * term) list
    35   val instance: arity list -> ((bstring * Attrib.src list) * term) list
    55 val classN = "class";
    57 val classN = "class";
    56 val introN = "intro";
    58 val introN = "intro";
    57 
    59 
    58 fun prove_interpretation tac prfx_atts expr inst =
    60 fun prove_interpretation tac prfx_atts expr inst =
    59   Locale.interpretation_i I prfx_atts expr inst
    61   Locale.interpretation_i I prfx_atts expr inst
       
    62   #> Proof.global_terminal_proof
       
    63       (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
       
    64   #> ProofContext.theory_of;
       
    65 
       
    66 fun prove_interpretation_in tac after_qed (name, expr) =
       
    67   Locale.interpretation_in_locale
       
    68       (ProofContext.theory after_qed) (name, expr)
    60   #> Proof.global_terminal_proof
    69   #> Proof.global_terminal_proof
    61       (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
    70       (Method.Basic (K (Method.SIMPLE_METHOD tac), Position.none), NONE)
    62   #> ProofContext.theory_of;
    71   #> ProofContext.theory_of;
    63 
    72 
    64 fun OF_LAST thm1 thm2 = thm1 RSN (Thm.nprems_of thm2, thm2);
    73 fun OF_LAST thm1 thm2 = thm1 RSN (Thm.nprems_of thm2, thm2);
   313     (*canonical interpretation*),
   322     (*canonical interpretation*),
   314   morphism: morphism,
   323   morphism: morphism,
   315     (*partial morphism of canonical interpretation*)
   324     (*partial morphism of canonical interpretation*)
   316   intro: thm,
   325   intro: thm,
   317   defs: thm list,
   326   defs: thm list,
   318   operations: (string * ((term * (typ * int)) * (term * typ))) list
   327   operations: (string * (term * (typ * int))) list,
   319     (*constant name ~> ((locale term,
   328     (*constant name ~> (locale term,
   320         (constant constraint, instantiaton index of class typ)), locale term & typ for uncheck)*)
   329         (constant constraint, instantiaton index of class typ))*)
       
   330   unchecks: (term * term) list
   321 };
   331 };
   322 
   332 
   323 fun rep_class_data (ClassData d) = d;
   333 fun rep_class_data (ClassData d) = d;
   324 fun mk_class_data ((consts, base_sort, inst, morphism, intro),
   334 fun mk_class_data ((consts, base_sort, inst, morphism, intro),
   325     (defs, operations)) =
   335     (defs, (operations, unchecks))) =
   326   ClassData { consts = consts, base_sort = base_sort, inst = inst,
   336   ClassData { consts = consts, base_sort = base_sort, inst = inst,
   327     morphism = morphism, intro = intro, defs = defs,
   337     morphism = morphism, intro = intro, defs = defs,
   328     operations = operations };
   338     operations = operations, unchecks = unchecks };
   329 fun map_class_data f (ClassData { consts, base_sort, inst, morphism, intro,
   339 fun map_class_data f (ClassData { consts, base_sort, inst, morphism, intro,
   330     defs, operations }) =
   340     defs, operations, unchecks }) =
   331   mk_class_data (f ((consts, base_sort, inst, morphism, intro),
   341   mk_class_data (f ((consts, base_sort, inst, morphism, intro),
   332     (defs, operations)));
   342     (defs, (operations, unchecks))));
   333 fun merge_class_data _ (ClassData { consts = consts,
   343 fun merge_class_data _ (ClassData { consts = consts,
   334     base_sort = base_sort, inst = inst, morphism = morphism, intro = intro,
   344     base_sort = base_sort, inst = inst, morphism = morphism, intro = intro,
   335     defs = defs1, operations = operations1 },
   345     defs = defs1, operations = operations1, unchecks = unchecks1 },
   336   ClassData { consts = _, base_sort = _, inst = _, morphism = _, intro = _,
   346   ClassData { consts = _, base_sort = _, inst = _, morphism = _, intro = _,
   337     defs = defs2, operations = operations2 }) =
   347     defs = defs2, operations = operations2, unchecks = unchecks2 }) =
   338   mk_class_data ((consts, base_sort, inst, morphism, intro),
   348   mk_class_data ((consts, base_sort, inst, morphism, intro),
   339     (Thm.merge_thms (defs1, defs2),
   349     (Thm.merge_thms (defs1, defs2),
   340       AList.merge (op =) (K true) (operations1, operations2)));
   350       (AList.merge (op =) (K true) (operations1, operations2),
       
   351         Library.merge (op aconv o pairself snd) (unchecks1, unchecks2))));
   341 
   352 
   342 structure ClassData = TheoryDataFun
   353 structure ClassData = TheoryDataFun
   343 (
   354 (
   344   type T = class_data Graph.T
   355   type T = class_data Graph.T
   345   val empty = Graph.empty;
   356   val empty = Graph.empty;
   381     (ClassData.get thy) [];
   392     (ClassData.get thy) [];
   382 
   393 
   383 fun these_operations thy =
   394 fun these_operations thy =
   384   maps (#operations o the_class_data thy) o ancestry thy;
   395   maps (#operations o the_class_data thy) o ancestry thy;
   385 
   396 
   386 fun local_operation thy = AList.lookup (op =) o these_operations thy;
   397 fun these_unchecks thy =
       
   398   maps (#unchecks o the_class_data thy) o ancestry thy;
   387 
   399 
   388 fun sups_base_sort thy sort =
   400 fun sups_base_sort thy sort =
   389   let
   401   let
   390     val sups = filter (is_class thy) sort
   402     val sups = filter (is_class thy) sort
   391       |> Sign.minimize_sort thy;
   403       |> Sign.minimize_sort thy;
   433 
   445 
   434 (* updaters *)
   446 (* updaters *)
   435 
   447 
   436 fun add_class_data ((class, superclasses), (cs, base_sort, inst, phi, intro)) thy =
   448 fun add_class_data ((class, superclasses), (cs, base_sort, inst, phi, intro)) thy =
   437   let
   449   let
   438     val operations = map (fn (v_ty as (_, ty'), (c, ty)) =>
   450     val operations = map (fn (v_ty, (c, ty)) =>
   439       (c, ((Free v_ty, (Logic.varifyT ty, 0)), (Free v_ty, ty')))) cs;
   451       (c, ((Free v_ty, (Logic.varifyT ty, 0))))) cs;
       
   452     val unchecks = map (fn ((v, ty'), (c, _)) =>
       
   453       (Free (v, Type.strip_sorts ty'), Const (c, Type.strip_sorts ty'))) cs;
   440     val cs = (map o pairself) fst cs;
   454     val cs = (map o pairself) fst cs;
   441     val add_class = Graph.new_node (class,
   455     val add_class = Graph.new_node (class,
   442         mk_class_data ((cs, base_sort, map (SOME o Const) inst, phi, intro), ([], operations)))
   456         mk_class_data ((cs, base_sort, map (SOME o Const) inst, phi, intro), ([], (operations, unchecks))))
   443       #> fold (curry Graph.add_edge class) superclasses;
   457       #> fold (curry Graph.add_edge class) superclasses;
   444   in
   458   in
   445     ClassData.map add_class thy
   459     ClassData.map add_class thy
   446   end;
   460   end;
   447 
   461 
   448 fun register_operation class ((c, (t, t_rev)), some_def) thy =
   462 fun register_operation class (c, ((t, some_t_rev), some_def)) thy =
   449   let
   463   let
   450     val ty = Sign.the_const_constraint thy c;
   464     val ty = Sign.the_const_constraint thy c;
   451     val typargs = Sign.const_typargs thy (c, ty);
   465     val typargs = Sign.const_typargs thy (c, ty);
   452     val typidx = find_index (fn TVar ((v, _), _) => Name.aT = v | _ => false) typargs;
   466     val typidx = find_index (fn TVar ((v, _), _) => Name.aT = v | _ => false) typargs;
   453     val t_rev' = (map_types o map_atyps)
   467     fun mk_uncheck t_rev =
   454       (fn ty as TFree (v, _) => if Name.aT = v then TFree (v, []) else ty | ty => ty) t_rev;
   468       let
   455     val ty' = Term.fastype_of t_rev';
   469         val t_rev' = map_types Type.strip_sorts t_rev;
       
   470         val ty' = Term.fastype_of t_rev';
       
   471       in (t_rev', Const (c, ty')) end;
       
   472     val some_t_rev' = Option.map mk_uncheck some_t_rev;
   456   in
   473   in
   457     thy
   474     thy
   458     |> (ClassData.map o Graph.map_node class o map_class_data o apsnd)
   475     |> (ClassData.map o Graph.map_node class o map_class_data o apsnd)
   459       (fn (defs, operations) =>
   476       (fn (defs, (operations, unchecks)) =>
   460         (fold cons (the_list some_def) defs,
   477         (fold cons (the_list some_def) defs,
   461           (c, ((t, (ty, typidx)), (t_rev', ty'))) :: operations))
   478           ((c, (t, (ty, typidx))) :: operations, fold cons (the_list some_t_rev') unchecks)))
   462   end;
   479   end;
   463 
   480 
   464 
   481 
   465 (** rule calculation, tactics and methods **)
   482 (** rule calculation, tactics and methods **)
   466 
   483 
   548  [("intro_classes", Method.no_args (Method.METHOD intro_classes_tac),
   565  [("intro_classes", Method.no_args (Method.METHOD intro_classes_tac),
   549     "back-chain introduction rules of classes"),
   566     "back-chain introduction rules of classes"),
   550   ("default", Method.thms_ctxt_args (Method.METHOD oo default_tac),
   567   ("default", Method.thms_ctxt_args (Method.METHOD oo default_tac),
   551     "apply some intro/elim rule")]);
   568     "apply some intro/elim rule")]);
   552 
   569 
       
   570 fun subclass_rule thy (sub, sup) =
       
   571   let
       
   572     val ctxt = Locale.init sub thy;
       
   573     val ctxt_thy = ProofContext.init thy;
       
   574     val props =
       
   575       Locale.global_asms_of thy sup
       
   576       |> maps snd
       
   577       |> map (ObjectLogic.ensure_propT thy);
       
   578     fun tac { prems, context } =
       
   579       Locale.intro_locales_tac true context prems
       
   580         ORELSE ALLGOALS assume_tac;
       
   581   in
       
   582     Goal.prove_multi ctxt [] [] props tac
       
   583     |> map (Assumption.export false ctxt ctxt_thy)
       
   584     |> Variable.export ctxt ctxt_thy
       
   585   end;
       
   586 
       
   587 fun prove_single_subclass (sub, sup) thms ctxt thy =
       
   588   let
       
   589     val ctxt_thy = ProofContext.init thy;
       
   590     val subclass_rule = Conjunction.intr_balanced thms
       
   591       |> Assumption.export false ctxt ctxt_thy
       
   592       |> singleton (Variable.export ctxt ctxt_thy);
       
   593     val sub_inst = Thm.ctyp_of thy (TVar ((Name.aT, 0), [sub]));
       
   594     val sub_ax = #axioms (AxClass.get_info thy sub);
       
   595     val classrel =
       
   596       #intro (AxClass.get_info thy sup)
       
   597       |> Drule.instantiate' [SOME sub_inst] []
       
   598       |> OF_LAST (subclass_rule OF sub_ax)
       
   599       |> strip_all_ofclass thy (Sign.super_classes thy sup)
       
   600       |> Thm.strip_shyps
       
   601   in
       
   602     thy
       
   603     |> AxClass.add_classrel classrel
       
   604     |> prove_interpretation_in (ALLGOALS (ProofContext.fact_tac thms))
       
   605          I (sub, Locale.Locale sup)
       
   606     |> ClassData.map (Graph.add_edge (sub, sup))
       
   607   end;
       
   608 
       
   609 fun prove_subclass (sub, sup) thms ctxt thy =
       
   610   let
       
   611     val supclasses = Sign.complete_sort thy [sup]
       
   612       |> filter_out (fn class => Sign.subsort thy ([sub], [class]));
       
   613     fun transform sup' = subclass_rule thy (sup, sup') |> map (fn thm => thm OF thms);
       
   614   in
       
   615     thy
       
   616     |> fold_rev (fn sup' => prove_single_subclass (sub, sup')
       
   617          (transform sup') ctxt) supclasses
       
   618  end;
       
   619 
   553 
   620 
   554 (** classes and class target **)
   621 (** classes and class target **)
   555 
   622 
   556 (* class context syntax *)
   623 (* class context syntax *)
   557 
   624 
   558 structure ClassSyntax = ProofDataFun(
   625 structure ClassSyntax = ProofDataFun(
   559   type T = {
   626   type T = {
   560     constraints: (string * typ) list,
   627     constraints: (string * typ) list,
   561     base_sort: sort,
   628     base_sort: sort,
   562     local_operation: string * typ -> (typ * term) option,
   629     local_operation: string * typ -> (typ * term) option,
   563     rews: (term * term) list,
   630     unchecks: (term * term) list,
   564     passed: bool
   631     passed: bool
   565   } option;
   632   } option;
   566   fun init _ = NONE;
   633   fun init _ = NONE;
   567 );
   634 );
   568 
   635 
   569 fun synchronize_syntax thy sups base_sort ctxt =
   636 fun synchronize_syntax thy sups base_sort ctxt =
   570   let
   637   let
       
   638     (* constraints *)
   571     val operations = these_operations thy sups;
   639     val operations = these_operations thy sups;
   572 
   640     fun local_constraint (c, (_, (ty, _))) =
   573     (* constraints *)
       
   574     fun local_constraint (c, ((_, (ty, _)),_ )) =
       
   575       let
   641       let
   576         val ty' = ty
   642         val ty' = ty
   577           |> map_atyps (fn ty as TVar ((v, 0), _) =>
   643           |> map_atyps (fn ty as TVar ((v, 0), _) =>
   578                if v = Name.aT then TVar ((v, 0), base_sort) else ty)
   644                if v = Name.aT then TVar ((v, 0), base_sort) else ty)
   579           |> SOME;
   645           |> SOME;
   580       in (c, ty') end
   646       in (c, ty') end
   581     val constraints = (map o apsnd) (fst o snd o fst) operations;
   647     val constraints = (map o apsnd) (fst o snd) operations;
   582 
   648 
   583     (* check phase *)
   649     (* check phase *)
   584     val typargs = Consts.typargs (ProofContext.consts_of ctxt);
   650     val typargs = Consts.typargs (ProofContext.consts_of ctxt);
   585     fun check_const (c, ty) ((t, (_, idx)), _) =
   651     fun check_const (c, ty) (t, (_, idx)) =
   586       ((nth (typargs (c, ty)) idx), t);
   652       ((nth (typargs (c, ty)) idx), t);
   587     fun local_operation (c_ty as (c, _)) = AList.lookup (op =) operations c
   653     fun local_operation (c_ty as (c, _)) = AList.lookup (op =) operations c
   588       |> Option.map (check_const c_ty);
   654       |> Option.map (check_const c_ty);
   589 
   655 
   590     (* uncheck phase *)
   656     (* uncheck phase *)
   591     val rews = map (fn (c, (_, (t, ty))) => (t, Const (c, ty))) operations;
   657     val basify =
       
   658       map_atyps (fn ty as TFree (v, _) => if Name.aT = v then TFree (v, base_sort)
       
   659         else ty | ty => ty);
       
   660     val unchecks = these_unchecks thy sups
       
   661       |> (map o pairself o map_types) basify;
   592   in
   662   in
   593     ctxt
   663     ctxt
   594     |> fold (ProofContext.add_const_constraint o local_constraint) operations
   664     |> fold (ProofContext.add_const_constraint o local_constraint) operations
   595     |> ClassSyntax.map (K (SOME {
   665     |> ClassSyntax.map (K (SOME {
   596         constraints = constraints,
   666         constraints = constraints,
   597         base_sort = base_sort,
   667         base_sort = base_sort,
   598         local_operation = local_operation,
   668         local_operation = local_operation,
   599         rews = rews,
   669         unchecks = unchecks,
   600         passed = false
   670         passed = false
   601       }))
   671       }))
   602   end;
   672   end;
   603 
   673 
   604 fun refresh_syntax class ctxt =
   674 fun refresh_syntax class ctxt =
   606     val thy = ProofContext.theory_of ctxt;
   676     val thy = ProofContext.theory_of ctxt;
   607     val base_sort = (#base_sort o the_class_data thy) class;
   677     val base_sort = (#base_sort o the_class_data thy) class;
   608   in synchronize_syntax thy [class] base_sort ctxt end;
   678   in synchronize_syntax thy [class] base_sort ctxt end;
   609 
   679 
   610 val mark_passed = (ClassSyntax.map o Option.map)
   680 val mark_passed = (ClassSyntax.map o Option.map)
   611   (fn { constraints, base_sort, local_operation, rews, passed } =>
   681   (fn { constraints, base_sort, local_operation, unchecks, passed } =>
   612     { constraints = constraints, base_sort = base_sort,
   682     { constraints = constraints, base_sort = base_sort,
   613       local_operation = local_operation, rews = rews, passed = true });
   683       local_operation = local_operation, unchecks = unchecks, passed = true });
   614 
   684 
   615 fun sort_term_check ts ctxt =
   685 fun sort_term_check ts ctxt =
   616   let
   686   let
   617     val { constraints, base_sort, local_operation, passed, ... } =
   687     val { constraints, base_sort, local_operation, passed, ... } =
   618       the (ClassSyntax.get ctxt);
   688       the (ClassSyntax.get ctxt);
   645 
   715 
   646 fun sort_term_uncheck ts ctxt =
   716 fun sort_term_uncheck ts ctxt =
   647   let
   717   let
   648     (*FIXME abbreviations*)
   718     (*FIXME abbreviations*)
   649     val thy = ProofContext.theory_of ctxt;
   719     val thy = ProofContext.theory_of ctxt;
   650     val rews = (#rews o the o ClassSyntax.get) ctxt;
   720     val unchecks = (#unchecks o the o ClassSyntax.get) ctxt;
   651     val ts' = if ! uncheck
   721     val ts' = if ! uncheck
   652       then map (Pattern.rewrite_term thy rews []) ts else ts;
   722       then map (Pattern.rewrite_term thy unchecks []) ts else ts;
   653   in if eq_list (op aconv) (ts, ts') then NONE else SOME (ts', ctxt) end;
   723   in if eq_list (op aconv) (ts, ts') then NONE else SOME (ts', ctxt) end;
   654 
   724 
   655 fun init_ctxt thy sups base_sort ctxt =
   725 fun init_ctxt thy sups base_sort ctxt =
   656   ctxt
   726   ctxt
   657   |> Variable.declare_term
   727   |> Variable.declare_term
   800 fun add_logical_const class pos ((c, mx), dict) thy =
   870 fun add_logical_const class pos ((c, mx), dict) thy =
   801   let
   871   let
   802     val prfx = class_prefix class;
   872     val prfx = class_prefix class;
   803     val thy' = thy |> Sign.add_path prfx;
   873     val thy' = thy |> Sign.add_path prfx;
   804     val phi = morphism thy' class;
   874     val phi = morphism thy' class;
       
   875     val base_sort = (#base_sort o the_class_data thy) class;
   805 
   876 
   806     val c' = Sign.full_name thy' c;
   877     val c' = Sign.full_name thy' c;
   807     val dict' = (map_types Logic.unvarifyT o Morphism.term phi) dict;
   878     val dict' = (map_types Logic.unvarifyT o Morphism.term phi) dict;
   808     val ty' = Term.fastype_of dict';
   879     val ty' = Term.fastype_of dict';
   809     val ty'' = Type.strip_sorts ty';
   880     val ty'' = Type.strip_sorts ty';
   815     |> Sign.hide_consts_i false [c''] (*FIXME*)
   886     |> Sign.hide_consts_i false [c''] (*FIXME*)
   816     |> Sign.declare_const pos (c, ty'', mx) |> snd
   887     |> Sign.declare_const pos (c, ty'', mx) |> snd
   817     |> Thm.add_def false (c, def_eq)
   888     |> Thm.add_def false (c, def_eq)
   818     |>> Thm.symmetric
   889     |>> Thm.symmetric
   819     |-> (fn def => class_interpretation class [def] [Thm.prop_of def]
   890     |-> (fn def => class_interpretation class [def] [Thm.prop_of def]
   820           #> register_operation class ((c', (dict, dict')), SOME (Thm.varifyT def)))
   891           #> register_operation class (c', ((dict, SOME dict'), SOME (Thm.varifyT def))))
   821     |> Sign.restore_naming thy
   892     |> Sign.restore_naming thy
   822     |> Sign.add_const_constraint (c', SOME ty')
   893     |> Sign.add_const_constraint (c', SOME ty')
   823   end;
   894   end;
   824 
   895 
   825 
   896 
   832     val phi = morphism thy class;
   903     val phi = morphism thy class;
   833 
   904 
   834     val c' = Sign.full_name thy' c;
   905     val c' = Sign.full_name thy' c;
   835     val rews = map (Logic.dest_equals o Thm.prop_of) (these_defs thy' [class])
   906     val rews = map (Logic.dest_equals o Thm.prop_of) (these_defs thy' [class])
   836     val rhs' = (Pattern.rewrite_term thy rews [] o Morphism.term phi) rhs;
   907     val rhs' = (Pattern.rewrite_term thy rews [] o Morphism.term phi) rhs;
   837     val rhs'' = map_types Logic.unvarifyT rhs';
   908     val ty' = (Logic.unvarifyT o Term.fastype_of) rhs';
   838     val ty' = Term.fastype_of rhs'';
       
   839 
   909 
   840     val c'' = NameSpace.full (Sign.naming_of thy' |> NameSpace.add_path prfx) c;
   910     val c'' = NameSpace.full (Sign.naming_of thy' |> NameSpace.add_path prfx) c;
   841     val ty'' = (Type.strip_sorts o Logic.unvarifyT) (Sign.the_const_constraint thy' c'');
   911     val ty'' = (Type.strip_sorts o Logic.unvarifyT) (Sign.the_const_constraint thy' c'');
   842   in
   912   in
   843     thy'
   913     thy'
   844     |> Sign.add_const_constraint (c'', SOME ty'') (*FIXME*)
   914     |> Sign.add_const_constraint (c'', SOME ty'') (*FIXME*)
   845     |> Sign.hide_consts_i false [c''] (*FIXME*)
   915     |> Sign.hide_consts_i false [c''] (*FIXME*)
   846     |> Sign.add_abbrev (#1 prmode) pos (c, map_types Type.strip_sorts rhs') |> snd
   916     |> Sign.add_abbrev (#1 prmode) pos (c, map_types Type.strip_sorts rhs') |> snd
   847     |> Sign.add_const_constraint (c', SOME ty')
   917     |> Sign.add_const_constraint (c', SOME ty')
   848     |> Sign.notation true prmode [(Const (c', ty'), mx)]
   918     |> Sign.notation true prmode [(Const (c', ty'), mx)]
   849     |> register_operation class ((c', (rhs, rhs'')), NONE)
   919     |> register_operation class (c', ((rhs, NONE), NONE))
   850     |> Sign.restore_naming thy
   920     |> Sign.restore_naming thy
   851   end;
   921   end;
   852 
   922 
   853 end;
   923 end;