{-# OPTIONS --safe --cubical #-}
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Function
open import Cubical.Data.Sigma
open import Cubical.Data.Empty
open import Cubical.Data.List renaming (rev to listrev)
open import Cubical.Data.Unit
open import Cubical.Data.Sum
open import Cubical.Data.Nat
open import Cubical.Induction.WellFounded
renaming (WellFounded to isWellFounded;
Acc to isAcc;
Rel to BinRel)
open import Cubical.Data.List.Base hiding (rev)
open import Cubical.Data.List.Properties
open import Cubical.Relation.Nullary.Base
open import squier.accessibility
open import squier.listextension
open import squier.graphclosures
open import squier.polygraphs
open import squier.cancelInverses
open import squier.newman
open import squier.homotopybasis
module squier.noethercycle {ℓ₀ ℓ₁ ℓ₂₃ : Level}
(A : Type ℓ₀) (_↝_ : BinRel A ℓ₁) where
_↝*_ = TransReflClosure _↝_
_↭*_ = TransReflClosure (SymClosure _↝_)
_↝⁺_ = TransClosure _↝_
module _ (noether : isWellFounded (λ y x → x ↝ y))
(localConf : ∀ {y x z} (s : x ↝ y) (t : x ↝ z) →
Σ[ w ∈ A ] (y ↝* w) × (z ↝* w))
(P : ∀ {x} → (x ↭* x) → Type ℓ₂₃) where
EmptyFill = {x : A} {u : x ↭* x} → lengthᵗ u ≡ 0 → P u
InverseCancel = ∀ {x y} (u : x ↭* y) → P (u ++ᵗ (reverse u))
RotationClosed = ∀ {x y} (u : x ↭* y) (v : y ↭* x) → P (u ++ᵗ v) → P (v ++ᵗ u)
PastingClosed = ∀ {x y} (u v w : x ↭* y)
→ P (u ++ᵗ (reverse v))
→ P (v ++ᵗ (reverse w))
→ P (u ++ᵗ (reverse w))
SymClosed = ∀ {x} (u : x ↭* x) → P u → P (reverse u)
ConfluenceFill = ∀ {y x z} (s : x ↝ y) (t : x ↝ z) →
P (rev s ∷ᵗ inj t ∷ᵗ
(embed⁺ (snd (snd (localConf s t))) ++ᵗ
embed⁻ (fst (snd (localConf s t)))))
module _ (ef : EmptyFill) (ic : InverseCancel) (rc : RotationClosed)
(pc : PastingClosed) (sc : SymClosed) (cf : ConfluenceFill) where
ConcatClosed = ∀ {x} (u v : x ↭* x) → P u → P v → P (u ++ᵗ v)
cc : ConcatClosed
cc u v pu pv =
let
pu₁ : P (u ++ᵗ (reverse []ᵗ))
pu₁ = subst P (sym ++ᵗ[]ᵗ) pu
pv₁ : P (reverse []ᵗ ++ᵗ (reverse (reverse v)))
pv₁ = subst P (sym (reverse-reverse v)) pv
puv₁ : P (u ++ᵗ (reverse (reverse v)))
puv₁ = pc u []ᵗ (reverse v) pu₁ pv₁
puv₂ : P (u ++ᵗ v)
puv₂ = subst P (cong (u ++ᵗ_) (reverse-reverse v)) puv₁
in
puv₂
poly : 2-polygraph
poly .2-polygraph.Σ₀ = A
poly .2-polygraph._↝_ = _↝_
poly .2-polygraph._⇒_ u v = P (u ++ᵗ reverse v)
open polygraph-properties poly hiding (_↝_ ; _↭*_ ; _↝*_)
⇔-to-⇒ : ∀ {x y} {u v : x ↭* y} → (u ⇔ v) → (u ⇒ v)
⇔-to-⇒ (inj u⇒v) = u⇒v
⇔-to-⇒ {u = u} {v = v} (rev u⇐v) = p⟨uv⁻¹⟩ where
p⟨⟨vu⁻¹⟩⁻¹⟩ : P (reverse (v ++ᵗ reverse u))
p⟨⟨vu⁻¹⟩⁻¹⟩ = sc (v ++ᵗ (reverse u)) u⇐v
p⟨u⁻¹⁻¹v⁻¹⟩ : P (reverse (reverse u) ++ᵗ reverse v)
p⟨u⁻¹⁻¹v⁻¹⟩ = subst P (reverse-++ᵗ v (reverse u)) p⟨⟨vu⁻¹⟩⁻¹⟩
p⟨uv⁻¹⟩ : P (u ++ᵗ reverse v)
p⟨uv⁻¹⟩ = subst P (cong (λ w → w ++ᵗ (reverse v)) (reverse-reverse _)) p⟨u⁻¹⁻¹v⁻¹⟩
⇔*-to-⇒ : ∀ {x y} {u v : x ↭* y} → (u ⇔* v) → (u ⇒ v)
⇔*-to-⇒ {u = u} []ᵗ = ic u
⇔*-to-⇒ (_∷ᵗ_ {a = u} {b = u₁} {c = v} u⇔u₁ u₁⇔*v) = pc u u₁ v p₁ p₂
where
p₁ : P (u ++ᵗ (reverse u₁))
p₁ = ⇔-to-⇒ u⇔u₁
p₂ : P (u₁ ++ᵗ (reverse v))
p₂ = ⇔*-to-⇒ u₁⇔*v
ord : hasOrder
ord = _↝⁺_ , _++⁺_ , [_]⁺
ord-is-noether : isWellFounded _
ord-is-noether = (transitive-Noetherian _ _ noether)
diamond-is-below-top : ∀ {x y z w} (s : x ↝⁺ y) (t : x ↝⁺ z)
(u : y ↝* w) (v : z ↝* w) →
forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (object-list (mkValley u v))
diamond-is-below-top s t []ᵗ []ᵗ = t , tt*
diamond-is-below-top s t (u₀ ∷ᵗ u) v = s , diamond-is-below-top (s ++⁺ [ u₀ ]⁺) t u v
diamond-is-below-top {x} s t []ᵗ (_∷ᵗ_ {z} {z₁} {w} v₀ v) = goal where
Goal = forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (object-list (mkValley []ᵗ (v₀ ∷ᵗ v)))
Goal₂ = forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (listrev (object-list (embed⁺ v)) ++ [ z ])
calc₁ = object-list (mkValley []ᵗ (v₀ ∷ᵗ v))
≡⟨ obj-emb-rev (v₀ ∷ᵗ v) ⟩
listrev (object-list (embed⁺ (v₀ ∷ᵗ v)))
∎
calc₂ = Goal
≡⟨ refl ⟩
forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (object-list (mkValley []ᵗ (v₀ ∷ᵗ v)))
≡⟨ cong (λ l → forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) l) calc₁ ⟩
forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (listrev (object-list (embed⁺ (v₀ ∷ᵗ v))))
≡⟨ refl ⟩
forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (listrev (object-list (embed⁺ v)) ++ [ z ])
≡⟨ refl ⟩
Goal₂
∎
IH = forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (object-list (mkValley []ᵗ v))
ih : IH
ih = diamond-is-below-top s (t ++⁺ [ v₀ ]⁺) []ᵗ v
IH₂ = forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (listrev (object-list (embed⁺ v)))
calc₃ = object-list (mkValley []ᵗ v)
≡⟨ obj-emb-rev v ⟩
listrev (object-list (embed⁺ v))
∎
calc₄ = IH
≡⟨ refl ⟩
forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (object-list (mkValley []ᵗ v))
≡⟨ cong (λ l → forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) l) calc₃ ⟩
forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_) (listrev (object-list (embed⁺ v)))
≡⟨ refl ⟩
IH₂
∎
ih₂ : IH₂
ih₂ = subst (λ X → X) calc₄ ih
goal₂ : Goal₂
goal₂ = forall-++ {ℓ₀ = ℓ₀} (x ↝⁺_) (listrev (object-list (embed⁺ v))) [ z ] ih₂ (t , tt*)
goal : Goal
goal = subst (λ X → X) (sym calc₂) goal₂
lower-diamond-is-below-top : ∀ {x y z w} (s : x ↝ y) (t : x ↝ z)
(u : y ↝* w) (v : z ↝* w) →
forall-in-list {ℓ₀ = ℓ₀} (x ↝⁺_)
(safe-middle (object-list (mkValley u v)))
lower-diamond-is-below-top {x} s t u v =
restrict-forall-list (x ↝⁺_) (object-list (mkValley u v))
(diamond-is-below-top [ s ]⁺ [ t ]⁺ u v)
ord-has-WB : hasWB poly ord
ord-has-WB s t =
let
s⁺ = fst (snd (localConf s t))
t⁺ = snd (snd (localConf s t))
in
(mkValley s⁺ t⁺) ,
lower-diamond-is-below-top s t s⁺ t⁺ ,
inj (subst P (cong (λ w → mkLocalPeak s t ++ᵗ w)
(aux-lemma s⁺ t⁺)) (cf s t))
∷ᵗ []ᵗ
where
aux-lemma : ∀ {y w z} (u : y ↝* w) (v : z ↝* w) →
((embed⁺ v) ++ᵗ (embed⁻ u)) ≡ reverse (mkValley u v)
aux-lemma u v =
(embed⁺ v) ++ᵗ (embed⁻ u)
≡⟨ cong (λ w → w ++ᵗ (embed⁻ u)) (rewrite-embed⁺ v) ⟩
(reverse (embed⁻ v)) ++ᵗ (embed⁻ u)
≡⟨ cong (reverse (embed⁻ v) ++ᵗ_) (rewrite-embed⁻ u) ⟩
reverse (embed⁻ v) ++ᵗ reverse (embed⁺ u)
≡⟨ sym (reverse-++ᵗ (embed⁺ u) (embed⁻ v)) ⟩
reverse (mkValley u v)
∎
module congClosedPreparation {x₀ x y y₀} (w₀ : x₀ ↭* x) (u v : x ↭* y)
(w₁ : y ↭* y₀) (α : u ⇔* v) where
p₀ : P (u ++ᵗ (reverse v))
p₀ = ⇔*-to-⇒ α
p₁ : P ((u ++ᵗ (reverse v)) ++ᵗ (reverse w₀ ++ᵗ (reverse (reverse w₀))))
p₁ = cc (u ++ᵗ (reverse v)) (reverse w₀ ++ᵗ (reverse (reverse w₀)))
p₀ (ic (reverse w₀))
p₂ : P ((u ++ᵗ (reverse v)) ++ᵗ (reverse w₀ ++ᵗ w₀))
p₂ = subst (λ w → P ((u ++ᵗ (reverse v)) ++ᵗ (reverse w₀ ++ᵗ w)))
(reverse-reverse w₀)
p₁
p₃ : P (u ++ᵗ (reverse v) ++ᵗ reverse w₀ ++ᵗ w₀)
p₃ = subst P (++ᵗ-assoc u (reverse v) _) p₂
p₄ : P (((reverse v) ++ᵗ reverse w₀ ++ᵗ w₀) ++ᵗ u)
p₄ = rc u _ p₃
p₅ : P ((((reverse v) ++ᵗ reverse w₀ ++ᵗ w₀) ++ᵗ u) ++ᵗ (w₁ ++ᵗ reverse w₁))
p₅ = cc (((reverse v) ++ᵗ reverse w₀ ++ᵗ w₀) ++ᵗ u)
(w₁ ++ᵗ reverse w₁)
p₄
(ic w₁)
calc₁ = (reverse v ++ᵗ reverse w₀ ++ᵗ w₀) ++ᵗ u
≡⟨ cong (λ t → t ++ᵗ u) (sym (++ᵗ-assoc (reverse v) _ w₀)) ⟩
((reverse v ++ᵗ reverse w₀) ++ᵗ w₀) ++ᵗ u
≡⟨ ++ᵗ-assoc _ w₀ u ⟩
(reverse v ++ᵗ reverse w₀) ++ᵗ (w₀ ++ᵗ u)
∎
calc₂ = ((reverse v ++ᵗ reverse w₀ ++ᵗ w₀) ++ᵗ u) ++ᵗ w₁ ++ᵗ reverse w₁
≡⟨ cong (λ w → w ++ᵗ w₁ ++ᵗ (reverse w₁)) calc₁ ⟩
((reverse v ++ᵗ reverse w₀) ++ᵗ (w₀ ++ᵗ u)) ++ᵗ w₁ ++ᵗ reverse w₁
≡⟨ ++ᵗ-assoc (reverse v ++ᵗ reverse w₀) (w₀ ++ᵗ u) (w₁ ++ᵗ reverse w₁) ⟩
(reverse v ++ᵗ reverse w₀) ++ᵗ (w₀ ++ᵗ u) ++ᵗ w₁ ++ᵗ reverse w₁
∎
p₆ : P ((reverse v ++ᵗ reverse w₀) ++ᵗ ((w₀ ++ᵗ u) ++ᵗ w₁ ++ᵗ reverse w₁))
p₆ = subst P calc₂ p₅
p₇ : P (((w₀ ++ᵗ u) ++ᵗ w₁ ++ᵗ reverse w₁) ++ᵗ reverse v ++ᵗ reverse w₀)
p₇ = rc (reverse v ++ᵗ reverse w₀) _ p₆
calc₃ = reverse w₁ ++ᵗ reverse v ++ᵗ reverse w₀
≡⟨ cong (reverse w₁ ++ᵗ_) (sym (reverse-++ᵗ w₀ v)) ⟩
reverse w₁ ++ᵗ reverse (w₀ ++ᵗ v)
≡⟨ sym (reverse-++ᵗ (w₀ ++ᵗ v) w₁) ⟩
reverse ((w₀ ++ᵗ v) ++ᵗ w₁)
≡⟨ cong reverse (++ᵗ-assoc w₀ v w₁) ⟩
reverse (w₀ ++ᵗ v ++ᵗ w₁)
∎
calc₄ = ((w₀ ++ᵗ u) ++ᵗ w₁ ++ᵗ reverse w₁) ++ᵗ reverse v ++ᵗ reverse w₀
≡⟨ cong (λ t → t ++ᵗ reverse v ++ᵗ reverse w₀)
(sym (++ᵗ-assoc (w₀ ++ᵗ u) w₁ (reverse w₁))) ⟩
(((w₀ ++ᵗ u) ++ᵗ w₁) ++ᵗ reverse w₁) ++ᵗ reverse v ++ᵗ reverse w₀
≡⟨ ++ᵗ-assoc ((w₀ ++ᵗ u) ++ᵗ w₁) (reverse w₁) _ ⟩
((w₀ ++ᵗ u) ++ᵗ w₁) ++ᵗ reverse w₁ ++ᵗ reverse v ++ᵗ reverse w₀
≡⟨ cong (λ t → t ++ᵗ _) (++ᵗ-assoc w₀ u w₁) ⟩
(w₀ ++ᵗ u ++ᵗ w₁) ++ᵗ (reverse w₁ ++ᵗ reverse v ++ᵗ reverse w₀)
≡⟨ cong ((w₀ ++ᵗ u ++ᵗ w₁) ++ᵗ_) calc₃ ⟩
(w₀ ++ᵗ u ++ᵗ w₁) ++ᵗ reverse (w₀ ++ᵗ v ++ᵗ w₁)
∎
p₈ : P ((w₀ ++ᵗ u ++ᵗ w₁) ++ᵗ reverse (w₀ ++ᵗ v ++ᵗ w₁))
p₈ = subst P calc₄ p₇
congr-closed : ⇔*isCongrClosed
congr-closed w₀ u v w₁ α = (inj (congClosedPreparation.p₈ w₀ u v w₁ α)) ∷ᵗ []ᵗ
cancels-empty : cancelsEmpty poly
cancels-empty u u≡0 = inj (subst P (sym ++ᵗ[]ᵗ) (ef u≡0)) ∷ᵗ []ᵗ
cancels-rinv : cancels*RInv poly
cancels-rinv u = inj (subst P (sym ++ᵗ[]ᵗ) (ic u)) ∷ᵗ []ᵗ
basis : hasHomotopyBasis poly
basis = Noeth×WB×Congr×Cancel⇒Basis poly
ord
ord-is-noether
ord-has-WB
congr-closed
cancels-empty
cancels-rinv
induction-for-closed-zigzags : ∀ {x} (u : x ↭* x) → P u
induction-for-closed-zigzags u = p⟨u⟩ where
p⟨revrev⟨u⟫ : P (reverse (reverse u))
p⟨revrev⟨u⟫ = ⇔*-to-⇒ (basis []ᵗ (reverse u))
p⟨u⟩ : P u
p⟨u⟩ = subst P (reverse-reverse u) p⟨revrev⟨u⟫