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 *) |