Conversation
New pages
Changed pages
|
There was a problem hiding this comment.
Thanks so much for the contribution! I'll split up the review a bit to not make it too overwhelming :)
First round is focused on some big-picture design questions, proof cleanup, some automation tips. I totally agree that packaging up both the strict and non-strict orders is a good idea, but I'm a bit unsure about bisimulations as a bespoke definition.
| ``` | ||
| --> | ||
| ```agda | ||
| ≃ₒ→≡ : {α β : Ordinal ℓ} → α ≃ₒ β → α ≡ β |
There was a problem hiding this comment.
We should be able to simplify this proof quite a bit by using Poset-path from https://1lab.dev/Order.Univalent.html#516
src/Data/Ordinal/Base.lagda.md
Outdated
| restriction : (x : α.Ob) → ⌞ Subordinal α x ⌟ → ⌞ Subordinal β (f x) ⌟ | ||
| restriction x (y , y<x) = f y , pres-< y<x | ||
| field | ||
| restriction-is-equiv : ∀ {x} → is-equiv (restriction x) |
There was a problem hiding this comment.
I think the following API might be easier to use, as we don't need Equiv.to and Equiv.from everywhere, and we don't have to unpack pairs.
record is-simulation
(α : Ordinal ℓ₁) (β : Ordinal ℓ₂)
(f : ⌞ α ⌟ → ⌞ β ⌟) : Type (ℓ₁ ⊔ ℓ₂) where
no-eta-equality
private
module α = Ordinal α
module β = Ordinal β
field
pres-< : ∀ {x y} → x α.< y → f x β.< f y
sim : ∀ {x y} → y β.< f x → ⌞ α ⌟
simulates : ∀ {x y} → (y<fx : y β.< f x) → f (sim y<fx) ≡ y
sim-< : ∀ {x y} → (y<fx : y β.< f x) → sim y<fx α.< x
reflect-≤ : ∀ {x y} → f x β.≤ f y → x α.≤ y
reflect-≤ {x} {y} fx≤fy = go (α.<-wf x) (α.<-wf y) fx≤fy where
go : ∀ {x y} → Acc α._<_ x → Acc α._<_ y → f x β.≤ f y → x α.≤ y
go {x} {y} (acc hx) (acc hy) fx≤fy =
Equiv.from α.≤-transforms-< λ {z} z<x →
let fz<fy : f z β.< f y
fz<fy = β.<-≤-trans (pres-< z<x) fx≤fy
fy* : ⌞ α ⌟
fy* = sim fz<fy
fy*<y : fy* α.< y
fy*<y = sim-< fz<fy
fy*≡z : sim fz<fy ≡ z
fy*≡z =
α.≤-antisym
(go (hy fy* fy*<y) (hx z z<x) (β.≤-refl' (simulates fz<fy)))
(go (hx z z<x) (hy fy* fy*<y) (β.≤-refl' (sym (simulates fz<fy))))
in subst (α._< y) fy*≡z fy*<y
has-injective : injective f
has-injective p = α.≤-antisym
(reflect-≤ (β.≤-refl' p))
(reflect-≤ (β.≤-refl' (sym p)))
segment : (x : α.Ob) → ⌞ Subordinal α x ⌟ → ⌞ Subordinal β (f x) ⌟
segment x (y , y<x) = f y , pres-< y<x
segment-is-equiv : ∀ {x} → is-equiv (segment x)
segment-is-equiv {x = x} .is-eqv (y , y<fx) .centre =
(sim y<fx , sim-< y<fx) , Σ-prop-path! (simulates y<fx)
segment-is-equiv {x = x} .is-eqv (y , y<fx) .paths ((z , z<x) , fz=y) =
Σ-prop-path! $ Σ-prop-path! $ has-injective (simulates y<fx ∙ sym (ap fst fz=y))| Induction over this ordering is known as **transfinite induction**. | ||
|
|
||
| ```agda | ||
| _<ₒ_ : Ordinal ℓ₁ → Ordinal ℓ₂ → Type (ℓ₁ ⊔ ℓ₂) |
There was a problem hiding this comment.
Seems like this could be nicer if we defined the strict order on ordinals using something like
record is-bounded-simulation
(α : Ordinal ℓ₁) (β : Ordinal ℓ₂)
(f : ⌞ α ⌟ → ⌞ β ⌟) : Type (ℓ₁ ⊔ ℓ₂)
where
no-eta-equality
private
module α = Ordinal α
module β = Ordinal β
field
has-simulation : is-simulation α β f
open is-simulation has-simulation public
field
bound : ⌞ β ⌟
reflect : ∀ (x : ⌞ β ⌟) → x β.< bound → ⌞ α ⌟
reflect-simulation : is-simulation (Subordinal β bound) α (uncurry reflect)This gives us a bit more control over <ₒ→≤ₒ, as we are just dropping the bound.
|
Thank you! I've followed most of your advice. The exceptions are as follows:
This is what I tried originally. I got stuck on proving that if an equivalence is a simulation, then its inverse is also a simulation. It's provable, of course, but it felt like I was being forced to do too much at once, so I broke it up with this definition of Also, the definition of
I tried that. The form in which Poset-path asks for the data was inconvenient enough that I went back to this method.
Thanks for the suggestion, but when I tried it, I didn't like the resulting code.
I'm not convinced. Since I've already set up a decent API for working with Finally, you mention that you like the decision to package both the strict and non-strict orders into the definition of When we define ordinal arithmetic, the strict order on If we did not bundle the non-strict order into |
|
Thanks for making the changes! That makes sense WRT I can hack together something that uses I still do think that breaking up For the Lex order, Favonia has a trick that we used in agda-mugen that we can use. The idea is that you can extend an order on a poset with a conditional bit of data like so: _≤[_]_ : ∀ (x : Ob) (K : Type r') (y : Ob) → Type (o ⊔ r ⊔ r')
x ≤[ K ] y = (x ≤ y) × (x ≡ y → K)The non-strict lex order can neatly be defined using this: _≤_ : ∀ (x y : ⌞ A ⌟ × ⌞ B ⌟) → Type (o ⊔ r ⊔ r')
(a1, b1) ≤ (a2, b2) = a1 A.≤[ b1 B.≤ b2 ] a2 |
|
Responding to your comment about the lex order: Theorem: If the strict order Proof: Observe that propositions form an ordinal, where Now, for any proposition |
|
@finegeometer Have you taken a look at @LuuBluum 's formalization of ordinals in the cubical library? I noticed they define the strict order on the product a bit differently than you did. Regarding |
I got nerd-sniped into implementing ordinals. I hope this is useful!
This is my first time contributing to a project, so please tell me if I'm doing anything wrong.
There are a few things that bother me.
is-well-orderpredicate, since the underlying type is bundled deeply into theOrdinalstructure.Poset. I don't know which choice is better.