theory Scratch imports Main begin locale Endo = fixes f :: \'a \ 'a\ assumes \f=f\ begin definition ff where \ff \ f\f\ end locale EndoCopy = fixes h :: \'a \ 'a\ assumes \h=h\ begin definition hh where \hh \ h\h\ end locale CommutingEndos = Endo f for f :: \'a \ 'a\ + fixes g :: \'a \ 'a\ assumes \f \ g = g \ f\ begin definition gg :: \'a \ 'a\ where \gg = g \ g\ end definition p1 :: \nat \ nat\ where \p1 \ (+) 1\ definition p2 :: \nat \ nat\ where \p2 \ (+) 2\ definition p3 :: \nat \ nat\ where \p3 \ (+) 3\ sublocale CommutingEndos \ EndoCopy \ff \ gg\ by (simp add: EndoCopy.intro) global_interpretation I0: Endo \p1\ defines x = \I0.ff\ by (simp add: Endo.intro p1_def) thm I0.ff_def (* OK: x \ p1 \ p1 *) global_interpretation I1: CommutingEndos p1 p2 rewrites \Endo.ff p1 = x\ defines y = \I1.hh\ and z = \I1.gg\ apply (simp add: CommutingEndos_axioms.intro CommutingEndos_def Endo.intro o_def p1_def p2_def) apply (simp only: flip: x_def) done thm I1.gg_def (* OK: z = p2 \ p2 *) thm z_def (* z \ CommutingEndos.gg p2 *) term \EndoCopy.hh (x \ z)\ ML_val \\<^term>\I1.hh\\ thm I1.hh_def (* BAD: I1.hh \ Endo.ff p1 \ z \ (Endo.ff p1 \ z) *) thm y_def (* BAD: y \ EndoCopy.hh (Endo.ff p1 \ CommutingEndos.gg p2) *) export_code y in OCaml (* No code equation for y *) (* Can force it manually, but I thought the point of global_interpretation is that this manual fiddling is not necessary: *) thm y_def[folded z_def, simplified I1.hh_def, folded x_def] (* y \ x \ z \ (x \ z) *) declare y_def[folded z_def, simplified I1.hh_def, folded x_def, code] export_code y in OCaml (* OK *) (* Manually adding a `rewrites` clause does not help either, unfortunately: *) global_interpretation I2: CommutingEndos p1 p3 rewrites \Endo.ff p1 = x\ defines y' = \I2.hh\ and z' = \I2.gg\ by (auto simp add: CommutingEndos_axioms.intro CommutingEndos_def Endo.intro o_def p1_def p3_def x_def) thm I2.gg_def (* OK: z' = p3 \ p3 *) thm z'_def (* z \ CommutingEndos.gg p3 *) thm I2.hh_def (* Better, but still not expected: I1.gg \ x \ z' \ (x \ z') Need LHS to be folded into y'! *) thm y'_def (* BAD: y \ EndoCopy.hh (Endo.ff p1 \ CommutingEndos.gg p3) *) export_code y' in OCaml (* No code equation for y *) (* Similar hacking still needed *) thm y'_def[folded x_def z'_def, simplified I2.hh_def] (* y' \ x \ z' \ (x \ z') *) lemmas y'_def[folded x_def z'_def, simplified I2.hh_def, code] export_code y' in OCaml (* OK *) end