Isabelle locale copy without any new assumptions - isabelle

In https://www.isa-afp.org/theories/jacobson_basic_algebra/#Group_Theory
there is this interesting locale definition
text ‹p 38, l 4›
locale left_translations_of_monoid = monoid begin
... some stuff ...
end (* left_translations_of_monoid *)
context monoid begin
text ‹p 38, ll 1--2›
interpretation left_translations_of_monoid ..
end
What is the point of having a locale that is an exact copy of another?

Related

Definition of multiplicative group of a field in Isabelle

theory Scratch
imports
"HOL.Fields"
"HOL.Groups"
begin
locale Field_is_group=
fixes F :: "'a :: field"
begin
typedef 'a mul_group = "{x :: 'a set. x ≠ 0}"
end
end
I'm new to Isabelle, and I have learned something about proving in first-order logic but not about data structures. I tried to formalize the proof of the fact that a field has a multiplicative group, but I don't know how to define the multiplicative group. It is the set of the whole field except zero, and a field in Isabelle is defined as a type. By looking about the references, I know I need use typedef, but it fails:
Type unification failed: No type arity set :: zero
Failed to meet type constraint:
Term: λx. x ≠ 0 :: ??'b ⇒ bool
Type: 'a set ⇒ ??'a
The error(s) above occurred in typedef "mul_group"

Isabelle/Simpl: Type unification failed using hoarestate

I started using Isabelle/Simpl and write the following theory according to the user guide:
theory Scratch
imports Simpl.Simpl
begin
hoarestate newvars =
N :: nat
lemma (in newvars) "Γ ⊢ {} ´N :== ´N + 1 {}"
sorry
end
But Isabelle complains that type unification fails:
Type unification failed
Type error in application: operator not of function type
Operator: N_' :: 'a
Operand: s :: ??'a
Simpl itself (including its user guide) successfully compiles.
How can I make it pass?
As Javier Díaz pointed out, importing only Simpl.Vcg instead of Simpl.Simpl does the trick.
The cause of the error seems a name collision against a record defined in Simpl.SyntaxTest. It contains the following record definition:
record 'g vars = "'g state" +
A_' :: "nat list"
AA_' :: "nat list list"
I_' :: nat
M_' :: nat
N_' :: nat
R_' :: int
S_' :: int
B_' :: bool
Abr_':: string
p_' :: ref
q_' :: ref
Isabelle seems to prefer N_' in the record to N in the hoarestate, although the hoarestate is defined later😥. I don't know why this is the case.

Applicative vs Generative functors

I have recently been learning SML, when I came to know the terms - applicative and generative functors. I also know that SML uses generative functors.
I tried to Google the terms but couldn't find any compelling resources that explains what these terms mean and what are the differences between the two.
So, I just wanted to know the actual meaning of these terms in some practically understable way and how this relates to SML being generative.
It has to do with equality of abstract types in the module resulting from functor application.
Generative means that two invocations of a functor will produce modules containing non-equal abstract types.
Applicative means that two invocations of a functor will produce modules containing equal abstract types if the arguments are equal in some sense (such as being syntactically identical).
I'll give an example in OCaml, since it happens to support both:
module App (M : sig end) : sig
type t
val zero : t
end = struct
type t = int
let zero = 0
end
(* A () argument signifies a generative functor in OCaml. *)
module Gen (M : sig end) () : sig
type t
val zero : t
end = struct
type t = int
let zero = 0
end
module Empty = struct end
module A = App (Empty)
module B = App (Empty)
module C = App (struct end) (* The argument is syntactically different. *)
module D = Gen (Empty) ()
module E = Gen (Empty) ()
let _ = begin
(* A.t and B.t are compatible. *)
ignore (A.zero = B.zero); (* OK *)
(* A.t and C.t are not compatible because the functor arguments
* are not syntactically equal. *)
ignore (A.zero = C.zero); (* type error *)
(* D.t and C.t are not compatible because they are produced
* from generative functors. *)
ignore (D.zero = E.zero); (* type error *)
end

Exporting code from locales with multiple parameters

according to the codegen documentation section "7.3 Locales and interpretation", exporting code from locales is a bit tricky but achievable. The following example works fine:
locale localTest =
fixes A :: "string"
begin
fun concatA :: "string ⇒ string" where "concatA x = x#A"
definition concatAA :: "string ⇒ string" where "concatAA x = x#A#A"
end
definition localtest_concatA :: "string ⇒ string " where
[code del]: "localtest_concatA = localTest.concatA ''a''"
definition localtest_concatAA :: "string ⇒ string " where
[code del]: "localtest_concatAA = localTest.concatAA ''a''"
interpretation localTest "''a''"
where "localTest.concatA ''a'' = localtest_concatA"
and "localTest.concatAA ''a'' = localtest_concatAA"
apply unfold_locales
apply(simp_all add: localtest_concatA_def localtest_concatAA_def)
done
export_code localtest_concatA localtest_concatAA in Scala file -
How can I export code for locales with multiple parameters? Given the following locale:
locale localTest =
fixes A :: "string"
fixes B :: "string"
begin
fun concatA :: "string ⇒ string" where "concatA x = x#A"
definition concatB :: "string ⇒ string" where "concatB x = x#B"
end
I can interpret it with
interpretation localTest "''a''" "''b''" .
But I canot use this interpretation in a definition
definition localtest_concatA :: "string ⇒ string " where
[code del]: "localtest_concatA = localTest.concatA ''a'' ''b''"
It fails with
Type unification failed: Clash of types "_ list" and "_ ⇒ _"
Type error in application: incompatible operand type
Operator: op = localtest_concatA :: (char list ⇒ char list) ⇒ bool
Operand: localTest.concatA ''a'' ''b'' :: char list
Look at your introduced constants, e.g., by the term command. We have
term localTest.concatA
with output
"localTest.concatA" :: "char list ⇒ char list ⇒ char list"
You see that in addition to the single parameter that you gave in the original definition (inside the locale), there is an additional one (but only 1 not 2, since the definition does not rely on B).
Now, after your interpretation (since you did not explicitly provide a name, the constants of localTest will be in scope without qualifier) we have
term concatA
with output
"localTest.concatA ''a''" :: "char list ⇒ char list"
That is, localTest.concatA ''a'' is already of type string => string. You additionally add ''b'' and obtain type string, but your type annotation says string => string. So there is really a clash of types and the reason was that you gave too many arguments to localTest.concatA. Try using
definition localtest_concatA :: "string ⇒ string " where
[code del]: "localtest_concatA = concatA
instead.

How do I abstractly work with theorems and terms using locale assumptions and variables in ML?

Consider the following locale definition:
locale my_locale =
fixes a :: nat
assumes "a > 0"
begin
definition "f n ≡ a + n"
lemma f_pos: "f x > 0"
sorry
end
In Isar, if I attempt to work with the definition of f or the lemma f_pos, the locale assumptions and fixed variables are hidden from me. For example, thm f_def f_pos returns:
f ?n ≡ a + ?n
0 < f ?x
as expected.
If, however, I try to reason about these terms in ML, the "hidden" fixed variables are suddenly exposed. ML {* #{thm f_def} |> prop_of *}, for instance, returns:
Const ("==", "nat ⇒ nat ⇒ prop") $
(Const ("TestSimple.my_locale.f", "nat ⇒ nat ⇒ nat") $
Free ("a", "nat") $ Var (("n", 0), "nat")) $
(Const ("Groups.plus_class.plus", "nat ⇒ nat ⇒ nat") $
Free ("a", "nat") $ Var (("n", 0), "nat"))
where the fixed variable a becomes a parameter to the function f.
Is there a way to be able to work inside a locales in ML so that I am not exposed to such locale variables?
It appears that the version of f which doesn't have the parameter a is simply an abbreviation generated by the locale command. In particular, typing print_abbrevs shows:
local.f ≡ My_Theory.my_locale.f a
This means that from the user's perspective, f doesn't appear to have any locale parameters, as they are hidden behind the abbreviation. Behind the scenes, however, f will always have the locale parameter attached to it, and thus ML code must be coded to explicitly handle it.

Resources