module Infinite where
open import Relation.Nullary
open import Relation.Unary
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
open import Data.Product
open import Data.Star hiding (return)
open import Data.Function
open import Data.Empty
open import Data.Nat
open import Data.Unit
infixr 5 _◅∞_
codata Infinite {S : Set} (_⟶_ : Rel S) (x : S) : Set where
_◅∞_ : ∀ {y} (x⟶y : x ⟶ y) (y⟶∞ : Infinite _⟶_ y) → Infinite _⟶_ x
Infinite-ℕ⟶ : {S : Set} → Rel S → Pred S
Infinite-ℕ⟶ {S} _⟶_ x =
Σ (ℕ → S) λ step → x ≡ step 0 × (∀ n → step n ⟶ step (suc n))
codata MaybeInfinite {S : Set} (_⟶_ : Rel S) (x : S) (P : Pred S) : Set
where
ε : (x∈P : x ∈ P) → MaybeInfinite _⟶_ x P
_◅∞_ : ∀ {y} (x⟶y : x ⟶ y) (y⟶⋆∞z : MaybeInfinite _⟶_ y P) →
MaybeInfinite _⟶_ x P
∞⇒⋆∞ : ∀ {S} {_⟶_ : Rel S} {P x} →
Infinite _⟶_ x → MaybeInfinite _⟶_ x P
∞⇒⋆∞ (x⟶y ◅∞ y⟶∞) ~ x⟶y ◅∞ ∞⇒⋆∞ y⟶∞
⋆∞⇒∞ : ∀ {S} {_⟶_ : Rel S} {P x} →
MaybeInfinite _⟶_ x P →
∄ (λ y → Star _⟶_ x y × y ∈ P) →
Infinite _⟶_ x
⋆∞⇒∞ (ε x∈P) x↛⋆P = ⊥-elim (x↛⋆P (_ , ε , x∈P))
⋆∞⇒∞ {S} {_⟶_} {P} {x} (x⟶y ◅∞ y⟶∞z) x↛⋆P ~ x⟶y ◅∞ ⋆∞⇒∞ y⟶∞z (helper x⟶y)
where
helper : ∀ {y} → x ⟶ y → ∄ λ z → Star _⟶_ y z × z ∈ P
helper x⟶y (z , y⟶⋆z , z∈P) = x↛⋆P (z , x⟶y ◅ y⟶⋆z , z∈P)
⋆∞⇒∞′ : ∀ {S} {_⟶_ : Rel S} {P x} →
MaybeInfinite _⟶_ x P → Empty P → Infinite _⟶_ x
⋆∞⇒∞′ ⟶⋆∞ P=∅ = ⋆∞⇒∞ ⟶⋆∞ (λ x⟶y∈P → P=∅ _ (proj₂ (proj₂ x⟶y∈P)))
∞⇒∞ℕ⟶ : ∀ {S} {_⟶_ : Rel S} {x} →
Infinite _⟶_ x → Infinite-ℕ⟶ _⟶_ x
∞⇒∞ℕ⟶ {S} {_⟶_} x⟶∞ = (step x⟶∞ , ≡-refl , seq x⟶∞)
where
step : ∀ {x} → Infinite _⟶_ x → ℕ → S
step {x} _ zero = x
step (x⟶y ◅∞ y⟶∞) (suc n) = step y⟶∞ n
seq : ∀ {x} (x⟶∞ : Infinite _⟶_ x) (n : ℕ) →
step x⟶∞ n ⟶ step x⟶∞ (suc n)
seq (x⟶y ◅∞ y⟶∞) zero = x⟶y
seq (x⟶y ◅∞ y⟶∞) (suc n) = seq y⟶∞ n
∞ℕ⟶⇒∞ : ∀ {S} {_⟶_ : Rel S} {x} →
Infinite-ℕ⟶ _⟶_ x → Infinite _⟶_ x
∞ℕ⟶⇒∞ (step , ≡-refl , seq) ~
seq 0 ◅∞ ∞ℕ⟶⇒∞ (step ∘ suc , ≡-refl , seq ∘ suc)
map∞ : ∀ {S₁ S₂} {R₁ : Rel S₁} {R₂ : Rel S₂}
(F : S₁ → S₂) → R₁ =[ F ]⇒ R₂ →
∀ {x} → Infinite R₁ x → Infinite R₂ (F x)
map∞ F f (x⟶y ◅∞ y⟶∞) ~ f x⟶y ◅∞ map∞ F f y⟶∞
map-append⋆∞ :
∀ {S₁ S₂} {R₁ : Rel S₁} {R₂ : Rel S₂}
{P₁ : Pred S₁} {P₂ : Pred S₂}
(F : S₁ → S₂) → R₁ =[ F ]⇒ R₂ →
(∀ {x} → x ∈ P₁ → MaybeInfinite R₂ (F x) P₂) →
∀ {x} → MaybeInfinite R₁ x P₁ → MaybeInfinite R₂ (F x) P₂
map-append⋆∞ F f g (ε x∈P) = g x∈P
map-append⋆∞ F f g (x⟶y ◅∞ y⟶∞) ~ f x⟶y ◅∞ map-append⋆∞ F f g y⟶∞
map⋆∞ : ∀ {S₁ S₂} {R₁ : Rel S₁} {R₂ : Rel S₂}
{P₁ : Pred S₁} {P₂ : Pred S₂}
(F : S₁ → S₂) →
R₁ =[ F ]⇒ R₂ →
(∀ {x} → x ∈ P₁ → F x ∈ P₂) →
∀ {x} → MaybeInfinite R₁ x P₁ → MaybeInfinite R₂ (F x) P₂
map⋆∞ F f g x⟶∞ = map-append⋆∞ F f (λ x∈P₁ → ε (g x∈P₁)) x⟶∞
private
module Dummy {S} {_⟶_ : Rel S} where
infix 6 _loops
_loops : ∀ {x} → x ⟶ x → Infinite _⟶_ x
x⟶x loops ~ x⟶x ◅∞ x⟶x loops
append⋆∞ : ∀ {P Q x} → MaybeInfinite _⟶_ x P →
(∀ {y} → y ∈ P → MaybeInfinite _⟶_ y Q) →
MaybeInfinite _⟶_ x Q
append⋆∞ x⟶∞ hyp = map-append⋆∞ id id hyp x⟶∞
infixr 5 _◅◅⋆∞_
_◅◅⋆∞_ : ∀ {P x y} → Star _⟶_ x y → MaybeInfinite _⟶_ y P →
MaybeInfinite _⟶_ x P
ε ◅◅⋆∞ z⟶∞ = z⟶∞
(x⟶y ◅ y⟶⋆z) ◅◅⋆∞ z⟶∞ = x⟶y ◅∞ y⟶⋆z ◅◅⋆∞ z⟶∞
unbounded-loops : (∀ x → Dec (∃ λ y → x ⟶ y)) →
∀ x → ∄ (λ y → Star _⟶_ x y × ∄ λ z → y ⟶ z) →
Infinite _⟶_ x
unbounded-loops _⟶? x hyp with x ⟶?
unbounded-loops _⟶? x hyp | no x↛ = ⊥-elim (hyp (x , ε , x↛))
unbounded-loops _⟶? x hyp | yes (u , x⟶u) ~
x⟶u ◅∞ unbounded-loops _⟶? u hyp'
where
hyp' : ∄ (λ y → Star _⟶_ u y × ∄ λ z → y ⟶ z)
hyp' (y , u⟶⋆y , y↛) = hyp (y , x⟶u ◅ u⟶⋆y , y↛)
open Dummy public
data Guardedness : Set where
guarded : Guardedness
unguarded : Guardedness
codata Infiniteʳ {I S : Set} (R : I → Rel S) (P : I → Pred S) :
Guardedness → I → S → Set where
_◅∞_ : ∀ {g i x y}
(x⟶y : R i x y) (y⟶∞ : Infiniteʳ R P guarded i y) →
Infiniteʳ R P g i x
grec : ∀ {i j} (F : S → S) (f : R i =[ F ]⇒ R j)
{x} (p : P i x) → Infiniteʳ R P guarded j (F x)
return : ∀ {I S R g i x} {P : I → Pred S} →
Infinite (R i) x → Infiniteʳ R P g i x
return (x⟶y ◅∞ y⟶∞) ~ x⟶y ◅∞ return y⟶∞
rec : ∀ {I S R i x} {P : I → Pred S} →
P i x → Infiniteʳ R P guarded i x
rec = grec id id
map∞ʳ : ∀ {I S R P g x} {i j : I}
(F : S → S) → R i =[ F ]⇒ R j →
Infiniteʳ R P g i x → Infiniteʳ R P g j (F x)
map∞ʳ F f (x⟶y ◅∞ y⟶∞) ~ f x⟶y ◅∞ map∞ʳ F f y⟶∞
map∞ʳ F f (grec F' f' p) = grec (F ∘ F') (f ∘ f') p
Stepper : {I S : Set} → (I → Rel S) → (I → Pred S) → Guardedness → Set
Stepper R P g = ∀ {i x} → P i x → Infiniteʳ R P g i x
unfold1 : ∀ {I S R g i x} {P : I → Pred S} →
Stepper R P g →
Infiniteʳ R P guarded i x →
Infiniteʳ R P g i x
unfold1 step (x⟶y ◅∞ y⟶∞) = x⟶y ◅∞ y⟶∞
unfold1 step (grec F f p) = map∞ʳ F f (step p)
produce : ∀ {I S R i x} {P : I → Pred S} →
Stepper R P unguarded →
Infiniteʳ R P unguarded i x →
Infinite (R i) x
produce step (x⟶y ◅∞ y⟶∞) ~ x⟶y ◅∞ produce step (unfold1 step y⟶∞)
unfold : ∀ {I S R i x} {P : I → Pred S} →
Stepper R P unguarded →
P i x → Infinite (R i) x
unfold step p = produce step (step p)
lift : ∀ {I S R i j x y g} →
({P : I → Pred S} → Infiniteʳ R P g i x →
Infiniteʳ R P unguarded j y) →
(Infinite (R i) x → Infinite (R j) y)
lift f ⟶∞ = produce {P = λ _ _ → ⊥} ⊥-elim (f (return ⟶∞))
weaken : ∀ {I S R i x g} {P : I → Pred S} →
Infiniteʳ R P g i x →
Infiniteʳ R P guarded i x
weaken (x⟶y ◅∞ y⟶∞) = x⟶y ◅∞ y⟶∞
weaken (grec F f p) = grec F f p
infixr 5 _◅◅∞ʳ_
_◅◅∞ʳ_ : ∀ {I S R i x y g} {P : I → Pred S} →
Star (R i) x y → Infiniteʳ R P g i y →
Infiniteʳ R P g i x
ε ◅◅∞ʳ ⟶∞ = ⟶∞
(x ◅ xs) ◅◅∞ʳ ⟶∞ = x ◅∞ weaken (xs ◅◅∞ʳ ⟶∞)
infixr 5 _◅◅∞_
_◅◅∞_ : ∀ {S} {R : Rel S} {x y} →
Star R x y → Infinite R y → Infinite R x
_◅◅∞_ {R = R} ⟶⋆ ⟶∞ =
lift {I = ⊤} {R = λ _ → R} (λ ⟶∞ → ⟶⋆ ◅◅∞ʳ ⟶∞) ⟶∞
infixr 5 _◅◅∞′_
infix 4 ↓_
mutual
codata Infinite′ {S : Set} (R : Rel S) (x : S) : Set1 where
_◅∞_ : ∀ {y} (x⟶y : R x y) (y⟶∞ : Infinite″ R y) →
Infinite′ R x
data Infinite″ {S : Set} (R : Rel S) : S → Set1 where
↓_ : ∀ {x} (x⟶∞ : Infinite′ R x) → Infinite″ R x
_◅◅∞′_ : ∀ {x y} (x⟶⋆y : Star R x y) (y⟶∞ : Infinite″ R y) →
Infinite″ R x
map∞′ : ∀ {S' x} {R' : Rel S'}
(F : S' → S) (f : R' =[ F ]⇒ R)
(x⟶∞ : Infinite″ R' x) → Infinite″ R (F x)
∞″→∞′ : ∀ {S x} {R : Rel S} → Infinite″ R x → Infinite′ R x
∞″→∞′ (↓ x⟶∞) = x⟶∞
∞″→∞′ (ε ◅◅∞′ x⟶∞) = ∞″→∞′ x⟶∞
∞″→∞′ ((x⟶y ◅ y⟶⋆z) ◅◅∞′ z⟶∞) = x⟶y ◅∞ y⟶⋆z ◅◅∞′ z⟶∞
∞″→∞′ (map∞′ F f x⟶∞) with ∞″→∞′ x⟶∞
∞″→∞′ (map∞′ F f x⟶∞) | x⟶y ◅∞ y⟶∞ = f x⟶y ◅∞ map∞′ F f y⟶∞
mutual
∞′→∞ : ∀ {S x} {R : Rel S} → Infinite′ R x → Infinite R x
∞′→∞ (x⟶y ◅∞ y⟶∞) ~ x⟶y ◅∞ ∞″→∞ y⟶∞
∞″→∞ : ∀ {S x} {R : Rel S} → Infinite″ R x → Infinite R x
∞″→∞ x⟶∞ = ∞′→∞ (∞″→∞′ x⟶∞)
∞→∞′ : ∀ {S x} {R : Rel S} → Infinite R x → Infinite′ R x
∞→∞′ (x⟶y ◅∞ y⟶∞) ~ x⟶y ◅∞ (↓ ∞→∞′ y⟶∞)
mutual
infixr 4 _⇓_
infixr 4 _◅⟨_⟩_
infix 5 _∈⟨_⟩
infix 5 _∶⟨_⟩
codata MaybeInfinite′ {S : Set} (R : Rel S) : S → Pred S → Set1 where
_∈⟨_⟩ : ∀ x {P} (x∈P : x ∈ P) → MaybeInfinite′ R x P
_◅⟨_⟩_ : ∀ x {y P} (x⟶y : R x y) (y⟶∞ : MaybeInfinite″ R y P) →
MaybeInfinite′ R x P
data MaybeInfinite″ {S : Set} (R : Rel S) : S → Pred S → Set1 where
_⇓_ : ∀ {x P} (dummy : ⊤)
(x⟶∞ : MaybeInfinite′ R x P) → MaybeInfinite″ R x P
map-append⋆∞′ :
∀ {S′} {R′ : Rel S′} {P′ P}
(F : S′ → S) → R′ =[ F ]⇒ R →
(∀ {x} → x ∈ P′ → MaybeInfinite″ R (F x) P) →
∀ {x} → MaybeInfinite″ R′ x P′ → MaybeInfinite″ R (F x) P
_∶⟨_⟩ : ∀ x {P} (x⟶∞ : MaybeInfinite″ R x P) → MaybeInfinite″ R x P
⋆∞″→⋆∞′ : ∀ {S x P} {R : Rel S} →
MaybeInfinite″ R x P → MaybeInfinite′ R x P
⋆∞″→⋆∞′ (_ ⇓ x⟶∞) = x⟶∞
⋆∞″→⋆∞′ (map-append⋆∞′ F f g x⟶∞) with ⋆∞″→⋆∞′ x⟶∞
⋆∞″→⋆∞′ (map-append⋆∞′ F f g x⟶∞) | x ∈⟨ x∈P ⟩ = ⋆∞″→⋆∞′ (g x∈P)
⋆∞″→⋆∞′ (map-append⋆∞′ F f g x⟶∞) | x ◅⟨ x⟶y ⟩ y⟶∞ =
F x ◅⟨ f x⟶y ⟩ map-append⋆∞′ F f g y⟶∞
⋆∞″→⋆∞′ (x ∶⟨ x⟶∞ ⟩) = ⋆∞″→⋆∞′ x⟶∞
mutual
⋆∞′→⋆∞ : ∀ {S x P} {R : Rel S} →
MaybeInfinite′ R x P → MaybeInfinite R x P
⋆∞′→⋆∞ (x ∈⟨ x∈P ⟩) = ε x∈P
⋆∞′→⋆∞ (_ ◅⟨ x⟶y ⟩ y⟶∞) ~ x⟶y ◅∞ ⋆∞″→⋆∞ y⟶∞
⋆∞″→⋆∞ : ∀ {S x P} {R : Rel S} →
MaybeInfinite″ R x P → MaybeInfinite R x P
⋆∞″→⋆∞ x⟶∞ = ⋆∞′→⋆∞ (⋆∞″→⋆∞′ x⟶∞)
⋆∞→⋆∞′ : ∀ {S x P} {R : Rel S} →
MaybeInfinite R x P → MaybeInfinite′ R x P
⋆∞→⋆∞′ (ε x∈P) = _ ∈⟨ x∈P ⟩
⋆∞→⋆∞′ (x⟶y ◅∞ y⟶∞) ~ _ ◅⟨ x⟶y ⟩ _ ⇓ ⋆∞→⋆∞′ y⟶∞