Stream: Beginner Questions

Topic: Oddity with records and locales


view this post on Zulip John Hughes (Jul 28 2025 at 17:30):

Hoping to duplicate the structure of HOL/Algebra for using records as part of defining locales for algebraic objects (see also #Beginner Questions > Should I always bundle the data in a locale into a record? ), I've copied and slightly simplified the setup for a monoid:

record 'a monoid =
  carrier :: "'a set"
  mult    :: "['a, 'a] ⇒ 'a" (infixl ‹⊗ı› 70)
  one     :: 'a (‹𝟭ı›)

locale monoid =
  fixes G (structure)
  assumes m_closed [intro, simp]:
         "⟦x ∈ carrier G; y ∈ carrier G⟧ ⟹ x ⊗ y ∈ carrier G"
      and m_assoc:
         "⟦x ∈ carrier G; y ∈ carrier G; z ∈ carrier G⟧
          ⟹ (x ⊗ y) ⊗ z = x ⊗ (y ⊗ z)"
      and one_closed [intro, simp]: "𝟭 ∈ carrier G"
      and l_one [simp]: "x ∈ carrier G ⟹ 𝟭 ⊗ x = x"
      and r_one [simp]: "x ∈ carrier G ⟹ x ⊗ 𝟭 = x"
begin
end

Here the simplification was simply folding the "partial object" record into the monoid record. When I look at this in jEdit, the G in fixes G (structure) is shown in blue:
image.png

When I try to replicate that approach, albeit with different names, like this:

record ('p, 'l) affine_plane_r =
  Points :: "'p set"
  Lines :: "'l set"
  incid :: "'p ⇒ 'l ⇒ bool" (infix "⊲" 60)

locale affine_plane_data =
  fixes AP (structure)
  assumes contains:
    "⟦ k ∈ Lines AP ; P ∈ Points AP⟧ ⟹ (P ⊲ k)"
(*  fixes join:: "'p ⇒ 'p ⇒ 'l"
  fixes find_parallel:: "'l ⇒ 'p ⇒ 'l" *)
begin
end

the fixes AP (Structure) shows AP in black instead:
image.png

It also seems unhappy about my use of as an infix operator, even though in the monoid example, the use of as an infix operator works fine.

I suppose that my problem could be that I have two types, 'p and 'l, while monoids have only 'a, but I'm hoping it's something simpler/stupider, and that I've made some sort of copy-paste error that'll be obvious to a trained eye.

Can anyone explain what's going on here?

view this post on Zulip John Hughes (Jul 28 2025 at 17:50):

...wait. I think I've partly answered my own question. When I simplify to this:

locale affine_plane_data =
  fixes AP (structure)
  assumes nonempty: "Lines AP ≠ {}"
begin
end

then the AP turns blue. So perhaps the black vs blue problem is a symptom of the second problem: the fact my my contains assumption is generating a syntax error is causing the color problem as well.

I'm still puzzled, however, about the problem with , and why it doesn't work the way that multiplication seems to for monoids.

view this post on Zulip Christian Pardillo Laursen (Jul 28 2025 at 17:51):

Adding the ı character to the infix definition seems to do the trick, though I'm not entirely sure why that might be - perhaps it hints at an implicit argument?

record ('p, 'l) affine_plane_r =
  Points :: "'p set"
  Lines :: "'l set"
  incid :: "'p ⇒ 'l ⇒ bool" (infix ‹◃ı› 60)

locale affine_plane_data =
  fixes AP (structure)
  assumes contains:
    "⟦ k ∈ Lines AP ; P ∈ Points AP⟧ ⟹ (k ◃ P)"
(*  fixes join:: "'p ⇒ 'p ⇒ 'l"
  fixes find_parallel:: "'l ⇒ 'p ⇒ 'l" *)

The original works if we pass AP as an argument to ◃:

record ('p, 'l) affine_plane_r =
  Points :: "'p set"
  Lines :: "'l set"
  incid :: "'p ⇒ 'l ⇒ bool" (infix ‹◃› 60)

locale affine_plane_data =
  fixes AP (structure)
  assumes contains:
    "⟦ k ∈ Lines AP ; P ∈ Points AP⟧ ⟹ ((◃) AP k P)"

In both cases AP returns to blue - that only happens because of the error

view this post on Zulip John Hughes (Jul 28 2025 at 17:56):

Wow. I have no idea what that character means, and figured it had something to do with writing a subscript of G on later uses of , which I didn't need. As usual, I guess (a) that this takes me past this stumbling block, but (b) I've got more reading to do.

Thanks!


Last updated: Aug 13 2025 at 08:30 UTC