src/Pure/Isar/class.ML
changeset 60345 592806806494
parent 60344 a40369ea3ba5
child 60346 90d0103af558
equal deleted inserted replaced
60344:a40369ea3ba5 60345:592806806494
   323 
   323 
   324 (* class target *)
   324 (* class target *)
   325 
   325 
   326 val class_prefix = Logic.const_of_class o Long_Name.base_name;
   326 val class_prefix = Logic.const_of_class o Long_Name.base_name;
   327 
   327 
   328 local
       
   329 
       
   330 fun guess_morphism_identity (b, rhs) phi1 phi2 =
   328 fun guess_morphism_identity (b, rhs) phi1 phi2 =
   331   let
   329   let
   332     (*FIXME proper concept to identify morphism instead of educated guess*)
   330     (*FIXME proper concept to identify morphism instead of educated guess*)
   333     val name_of_binding = Name_Space.full_name Name_Space.global_naming;
   331     val name_of_binding = Name_Space.full_name Name_Space.global_naming;
   334     val n1 = (name_of_binding o Morphism.binding phi1) b;
   332     val n1 = (name_of_binding o Morphism.binding phi1) b;
   335     val n2 = (name_of_binding o Morphism.binding phi2) b;
   333     val n2 = (name_of_binding o Morphism.binding phi2) b;
   336     val rhs1 = Morphism.term phi1 rhs;
   334     val rhs1 = Morphism.term phi1 rhs;
   337     val rhs2 = Morphism.term phi2 rhs;
   335     val rhs2 = Morphism.term phi2 rhs;
   338   in n1 = n2 andalso Term.aconv_untyped (rhs1, rhs2) end;
   336   in n1 = n2 andalso Term.aconv_untyped (rhs1, rhs2) end;
   339 
   337 
   340 fun target_const class phi0 prmode (b, rhs) =
   338 fun target_const class phi0 prmode (b, rhs) lthy =
   341   let
   339   let
   342     val guess_identity = guess_morphism_identity (b, rhs) Morphism.identity;
   340     val export = Variable.export_morphism lthy (Local_Theory.target_of lthy);
   343     val guess_canonical = guess_morphism_identity (b, rhs) phi0;
   341     val guess_identity = guess_morphism_identity (b, rhs) export;
   344   in
   342     val guess_canonical = guess_morphism_identity (b, rhs) (export $> phi0);
   345     Generic_Target.locale_target_const class
   343   in
       
   344     lthy
       
   345     |> Generic_Target.locale_target_const class
   346       (not o (guess_identity orf guess_canonical)) prmode ((b, NoSyn), rhs)
   346       (not o (guess_identity orf guess_canonical)) prmode ((b, NoSyn), rhs)
   347   end;
   347   end;
       
   348 
       
   349 local
   348 
   350 
   349 fun dangling_params_for lthy class (type_params, term_params) =
   351 fun dangling_params_for lthy class (type_params, term_params) =
   350   let
   352   let
   351     val class_param_names =
   353     val class_param_names =
   352       map fst (these_params (Proof_Context.theory_of lthy) [class]);
   354       map fst (these_params (Proof_Context.theory_of lthy) [class]);
   377     |-> (fn def_thm => register_def class def_thm)
   379     |-> (fn def_thm => register_def class def_thm)
   378     |> null dangling_params ? register_operation class (c, rhs)
   380     |> null dangling_params ? register_operation class (c, rhs)
   379     |> Sign.add_const_constraint (c, SOME ty)
   381     |> Sign.add_const_constraint (c, SOME ty)
   380   end;
   382   end;
   381 
   383 
   382 fun canonical_abbrev class phi prmode dangling_term_params ((b, mx), rhs) thy =
       
   383   let
       
   384     val unchecks = these_unchecks thy [class];
       
   385     val rhs' = Pattern.rewrite_term thy unchecks [] rhs;
       
   386     val c' = Sign.full_name thy b;
       
   387     val ty' = map Term.fastype_of dangling_term_params ---> Term.fastype_of rhs';
       
   388     val ty'' = Morphism.typ phi ty';
       
   389     val rhs'' = map_types (Morphism.typ phi) (fold lambda dangling_term_params rhs');
       
   390   in
       
   391     thy
       
   392     |> Sign.add_abbrev (#1 prmode) (b, Logic.varify_types_global rhs'')
       
   393     |> snd
       
   394     |> Sign.notation true prmode [(Const (c', ty''), mx)]
       
   395     |> (null dangling_term_params andalso not (#1 prmode = Print_Mode.input))
       
   396       ? register_operation class (c', rhs')
       
   397     |> Sign.add_const_constraint (c', SOME ty')
       
   398   end;
       
   399 
       
   400 in
   384 in
   401 
   385 
   402 fun const class ((b, mx), lhs) params lthy =
   386 fun const class ((b, mx), lhs) params lthy =
   403   let
   387   let
   404     val phi = morphism (Proof_Context.theory_of lthy) class;
   388     val phi = morphism (Proof_Context.theory_of lthy) class;
   411     |> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other)
   395     |> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other)
   412          Syntax.mode_default ((b, if null dangling_params then NoSyn else mx), lhs)
   396          Syntax.mode_default ((b, if null dangling_params then NoSyn else mx), lhs)
   413     |> synchronize_class_syntax_target class
   397     |> synchronize_class_syntax_target class
   414   end;
   398   end;
   415 
   399 
   416 fun target_abbrev class prmode ((b, mx), lhs) rhs' params lthy =
   400 end;
   417   let
   401 
   418     val phi = morphism (Proof_Context.theory_of lthy) class;
   402 local
   419     val dangling_term_params = map (Morphism.term phi) (snd (dangling_params_for lthy class params));
   403 
       
   404 fun canonical_abbrev class phi prmode with_syntax ((b, mx), rhs) thy =
       
   405   let
       
   406     val c = Sign.full_name thy b;
       
   407     val constrain = map_atyps (fn T as TFree (v, _) =>
       
   408       if v = Name.aT then TFree (v, [class]) else T | T => T);
       
   409     val rhs' = map_types constrain rhs;
       
   410   in
       
   411     thy
       
   412     |> Sign.add_abbrev (#1 prmode) (b, Logic.varify_types_global rhs')
       
   413     |> snd
       
   414     |> with_syntax ? Sign.notation true prmode [(Const (c, fastype_of rhs), mx)]
       
   415     |> with_syntax ? register_operation class (c, rhs)
       
   416         (*FIXME input syntax!?*)
       
   417     |> Sign.add_const_constraint (c, SOME (fastype_of rhs'))
       
   418   end;
       
   419 
       
   420 fun canonical_abbrev_target class phi prmode ((b, mx), rhs) lthy =
       
   421   let
       
   422     val thy = Proof_Context.theory_of lthy;
       
   423     val preprocess = perhaps (try (Pattern.rewrite_term thy (these_unchecks thy [class]) []));
       
   424     val (global_rhs, (extra_tfrees, (type_params, term_params))) =
       
   425       Generic_Target.export_abbrev lthy preprocess rhs;
       
   426     val mx' = Generic_Target.check_mixfix_global (b, null term_params) mx;
   420   in
   427   in
   421     lthy
   428     lthy
   422     |> target_const class phi prmode (b, lhs)
   429     |> Local_Theory.raw_theory (canonical_abbrev class phi prmode (null term_params)
   423     |> Local_Theory.raw_theory (canonical_abbrev class phi prmode dangling_term_params
   430         ((Morphism.binding phi b, mx'), Logic.unvarify_types_global global_rhs))
   424          ((Morphism.binding phi b, if null dangling_term_params then mx else NoSyn), rhs'))
   431   end;
   425     |> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other)
   432 
   426          prmode ((b, if null dangling_term_params then NoSyn else mx), lhs)
   433 fun further_abbrev_target class phi prmode (b, mx) rhs params =
   427     |> synchronize_class_syntax_target class
   434   Generic_Target.background_abbrev (b, rhs) (snd params)
   428   end;
   435   #-> (fn (lhs, _) => target_const class phi prmode (b, lhs)
   429 
   436     #> Generic_Target.standard_const (fn (this, other) => other <> 0 andalso this <> other) prmode ((b, mx), lhs))
   430 fun abbrev class = Generic_Target.abbrev (fn prmode => fn (b, mx) => fn global_rhs => fn params =>
   437 
   431   Generic_Target.background_abbrev (b, global_rhs) (snd params)
   438 in
   432   #-> (fn (lhs, rhs) => target_abbrev class prmode ((b, mx), lhs) rhs params));
   439 
       
   440 fun abbrev class prmode ((b, mx), rhs) lthy =
       
   441   let
       
   442     val thy = Proof_Context.theory_of lthy;
       
   443     val phi = morphism thy class;
       
   444     val rhs_generic =
       
   445       perhaps (try (Pattern.rewrite_term thy (map swap (these_unchecks thy [class])) [])) rhs;
       
   446   in
       
   447     lthy
       
   448     |> canonical_abbrev_target class phi prmode ((b, mx), rhs)
       
   449     |> Generic_Target.abbrev (further_abbrev_target class phi) prmode ((b, mx), rhs_generic)
       
   450     ||> synchronize_class_syntax_target class
       
   451   end;
   433 
   452 
   434 end;
   453 end;
   435 
   454 
   436 
   455 
   437 (* subclasses *)
   456 (* subclasses *)