src/Pure/Isar/locale.ML
changeset 37104 3877a6c45d57
parent 37103 6ea25bb157e1
child 37105 e464f84f3680
equal deleted inserted replaced
37103:6ea25bb157e1 37104:3877a6c45d57
   328 
   328 
   329 (*** Registrations: interpretations in theories ***)
   329 (*** Registrations: interpretations in theories ***)
   330 
   330 
   331 structure Registrations = Theory_Data
   331 structure Registrations = Theory_Data
   332 (
   332 (
   333   type T = ((string * (morphism * morphism)) * serial) list *
   333   type T = (((string * term list) * (morphism * morphism)) * serial) list *
   334     (* registrations, in reverse order of declaration;
   334     (* registrations, in reverse order of declaration;
   335        serial points to mixin list *)
   335        serial points to mixin list *)
   336     (serial * ((morphism * bool) * serial) list) list;
   336     (serial * ((morphism * bool) * serial) list) list;
   337     (* alist of mixin lists, per list mixins in reverse order of declaration;
   337     (* alist of mixin lists, per list mixins in reverse order of declaration;
   338        lists indexed by registration serial,
   338        lists indexed by registration serial,
   346 );
   346 );
   347 
   347 
   348 
   348 
   349 (* Primitive operations *)
   349 (* Primitive operations *)
   350 
   350 
   351 fun add_reg export (dep, morph) =
   351 fun add_reg thy export (name, morph) =
   352   Registrations.map (apfst (cons ((dep, (morph, export)), serial ())));
   352   Registrations.map (apfst (cons (((name, instance_of thy name (morph $> export)), (morph, export)), serial ())));
   353 
   353 
   354 fun add_mixin serial' mixin =
   354 fun add_mixin serial' mixin =
   355   (* registration to be amended identified by its serial id *)
   355   (* registration to be amended identified by its serial id *)
   356   Registrations.map (apsnd (AList.map_default (op =) (serial', []) (cons (mixin, serial ()))));
   356   Registrations.map (apsnd (AList.map_default (op =) (serial', []) (cons (mixin, serial ()))));
   357 
   357 
   358 fun get_mixins thy (name, morph) =
   358 fun get_mixins thy (name, morph) =
   359   let
   359   let
   360     val (regs, mixins) = Registrations.get thy;
   360     val (regs, mixins) = Registrations.get thy;
   361   in
   361   in
   362     case find_first (fn ((name', (morph', export')), _) => ident_eq
   362     case find_first (fn (((name', inst'), (morph', export')), _) => ident_eq
   363       ((name', instance_of thy name' (morph' $> export')), (name, instance_of thy name morph))) (rev regs) of
   363       ((name', inst'), (name, instance_of thy name morph))) (rev regs) of
   364       NONE => []
   364       NONE => []
   365     | SOME (_, serial) => the_default [] (AList.lookup (op =) mixins serial)
   365     | SOME (_, serial) => the_default [] (AList.lookup (op =) mixins serial)
   366   end;
   366   end;
   367 
   367 
   368 fun collect_mixins thy (name, morph) =
   368 fun collect_mixins thy (name, morph) =
   377 fun reg_morph mixins ((name, (base, export)), serial) =
   377 fun reg_morph mixins ((name, (base, export)), serial) =
   378   let val mix = the_default [] (AList.lookup (op =) mixins serial) |> compose_mixins;
   378   let val mix = the_default [] (AList.lookup (op =) mixins serial) |> compose_mixins;
   379   in (name, base $> mix $> export) end;
   379   in (name, base $> mix $> export) end;
   380 
   380 
   381 fun these_registrations thy name = Registrations.get thy
   381 fun these_registrations thy name = Registrations.get thy
   382   |>> filter (curry (op =) name o fst o fst)
   382   |>> filter (curry (op =) name o fst o fst o fst)
   383   (* with inherited mixins *)
   383   (* with inherited mixins *)
   384   |-> (fn regs => fn _ => map (fn ((name, (base, export)) ,_) =>
   384   |-> (fn regs => fn _ => map (fn (((name, _), (base, export)) ,_) =>
   385     (name, base $> (collect_mixins thy (name, base $> export) |> compose_mixins) $> export)) regs);
   385     (name, base $> (collect_mixins thy (name, base $> export) |> compose_mixins) $> export)) regs);
   386 
   386 
   387 fun all_registrations thy = Registrations.get thy (* FIXME clone *)
   387 fun all_registrations thy = Registrations.get thy (* FIXME clone *)
   388   (* with inherited mixins *)
   388   (* with inherited mixins *)
   389   |-> (fn regs => fn _ => map (fn ((name, (base, export)) ,_) =>
   389   |-> (fn regs => fn _ => map (fn (((name, _), (base, export)) ,_) =>
   390     (name, base $> (collect_mixins thy (name, base $> export) |> compose_mixins) $> export)) regs);
   390     (name, base $> (collect_mixins thy (name, base $> export) |> compose_mixins) $> export)) regs);
   391 
   391 
   392 fun activate_notes' activ_elem transfer thy export (name, morph) input =
   392 fun activate_notes' activ_elem transfer thy export (name, morph) input =
   393   let
   393   let
   394     val {notes, ...} = the_locale thy name;
   394     val {notes, ...} = the_locale thy name;
   444 
   444 
   445 fun amend_registration (name, morph) mixin export thy =
   445 fun amend_registration (name, morph) mixin export thy =
   446   let
   446   let
   447     val regs = Registrations.get thy |> fst;
   447     val regs = Registrations.get thy |> fst;
   448     val base = instance_of thy name (morph $> export);
   448     val base = instance_of thy name (morph $> export);
   449     fun match ((name', (morph', export')), _) =
   449     fun match (((name', inst'), _), _) = ident_eq ((name, base), (name', inst'));
   450       ident_eq ((name, base), (name', instance_of thy name' (morph' $> export)));
       
   451   in
   450   in
   452     case find_first match (rev regs) of
   451     case find_first match (rev regs) of
   453         NONE => error ("No interpretation of locale " ^
   452         NONE => error ("No interpretation of locale " ^
   454           quote (extern thy name) ^ " and\nparameter instantiation " ^
   453           quote (extern thy name) ^ " and\nparameter instantiation " ^
   455           space_implode " " (map (quote o Syntax.string_of_term_global thy) base) ^
   454           space_implode " " (map (quote o Syntax.string_of_term_global thy) base) ^
   470     if member (ident_le thy) (get_idents (Context.Theory thy)) (name, inst)
   469     if member (ident_le thy) (get_idents (Context.Theory thy)) (name, inst)
   471     then thy
   470     then thy
   472     else
   471     else
   473       (get_idents (Context.Theory thy), thy)
   472       (get_idents (Context.Theory thy), thy)
   474       (* add new registrations with inherited mixins *)
   473       (* add new registrations with inherited mixins *)
   475       |> roundup thy (add_reg export) export (name, morph)
   474       |> roundup thy (add_reg thy export) export (name, morph)
   476       |> snd
   475       |> snd
   477       (* add mixin *)
   476       (* add mixin *)
   478       |> (case mixin of NONE => I
   477       |> (case mixin of NONE => I
   479            | SOME mixin => amend_registration (name, morph) mixin export)
   478            | SOME mixin => amend_registration (name, morph) mixin export)
   480       (* activate import hierarchy as far as not already active *)
   479       (* activate import hierarchy as far as not already active *)