open import Data.Nat as Nat
open import Data.Nat.Properties as NatProp
open import Data.Bool hiding (_≟_;_∨_;_≤_;_<_)
open import Data.Empty
open import Function.Equality hiding (cong)
open import Data.Sum hiding (map) renaming (_⊎_ to _∨_)
open import Data.Product renaming (Σ to Σₓ;map to mapₓ)
open import Relation.Nullary
open import Relation.Nullary.Decidable hiding (map)
open import Relation.Binary
open import Relation.Binary.PropositionalEquality as PropEq renaming ([_] to [_]ᵢ)
open import Data.List hiding (any) renaming (length to length')
open import Data.List.Properties
open import Data.List.Relation.Unary.Any as Any hiding (map)
open import Data.List.Relation.Unary.Any.Properties as AnyProp hiding (map⁺)
open import Data.List.Membership.Propositional
open import Data.List.Membership.Propositional.Properties
open import Data.List.Relation.Binary.Subset.Propositional
open import Data.List.Relation.Binary.Subset.Propositional.Properties
open import Algebra.Structures
open import Stoughton.Var
module Stoughton.Chi {𝒱 : Set} (to : 𝒱 → ℕ) (from : ℕ → 𝒱) (to∘from : ∀ x → to (from x) ≡ x) where
private
n+0≡n = IsCommutativeMonoid.identityˡ (IsCommutativeSemiring.*-isCommutativeMonoid +-*-isCommutativeSemiring)
total = IsTotalOrder.total (IsDecTotalOrder.isTotalOrder (DecTotalOrder.isDecTotalOrder ≤-decTotalOrder))
f<s : (x : ℕ)(xs : List ℕ) → x ∈ xs → ((y : ℕ) → y < x → y ∈ xs) → (y : ℕ) → y < (suc x) → y ∈ xs
f<s x xs x∈xs f< y sucy≤sucx with ≤⇒≤′ sucy≤sucx
f<s x xs x∈xs f< .x _ | ≤′-refl = x∈xs
f<s x xs x∈xs f< y _ | ≤′-step sucy<'sucx = f< y (≤′⇒≤ sucy<'sucx)
χaux : (n m k : ℕ) → n + m ≡ k → (xs : List ℕ) → ((y : ℕ) → y < n → y ∈ xs) →
∃ (λ v → (v ∉ xs ∨ v ≡ k) × ((y : ℕ) → y < v → y ∈ xs))
χaux x 0 k x+0≡k _ f< with trans (sym (n+0≡n x)) x+0≡k
χaux x 0 .x x+0≡k _ f< | refl
= x , inj₂ refl , f<
χaux x (suc n) k x+Sn≡k xs f<
with any? (_≟_ x) xs
... | no x∉xs = x , inj₁ x∉xs , f<
... | yes x∈xs = χaux (suc x) n k (trans (cong suc (+-comm x n)) (trans (+-comm (suc n) x) x+Sn≡k)) xs (f<s x xs x∈xs f<)
y<0⇒y∈xs : (xs : List ℕ)(y : ℕ) → y < 0 → y ∈ xs
y<0⇒y∈xs xs y ()
χ' : List ℕ → ℕ
χ' xs = proj₁ (χaux 0 (length' xs) (length' xs) refl xs (y<0⇒y∈xs xs))
sucn≡sucm→n≡m : {n m : ℕ} → suc n ≡ suc m → n ≡ m
sucn≡sucm→n≡m refl = refl
predn≡m→n≡sucm : {n m : ℕ} → n > 0 → pred n ≡ m → n ≡ suc m
predn≡m→n≡sucm {suc n} {m} (s≤s _) n≡m = cong suc n≡m
x∈xs→|xs|>0 : {n : ℕ}{x : ℕ}{xs : List ℕ} → x ∈ xs → n ≡ length' xs → n > 0
x∈xs→|xs|>0 .{suc (length' xs)} {x} {y ∷ xs} (here px) refl = s≤s z≤n
x∈xs→|xs|>0 .{suc (length' xs)} {x} {y ∷ xs} (there x∈xs) refl = s≤s z≤n
del : (n : ℕ)(x : ℕ)(xs : List ℕ) → n ≡ length' xs → x ∈ xs → Σₓ (List ℕ) (λ ys → pred n ≡ length' ys)
del .0 x [] refl ()
del 0 _ (x ∷ xs) () _
del (suc n) .x (x ∷ xs) n+1≡|xxs| (here refl)
= xs , sucn≡sucm→n≡m n+1≡|xxs|
del (suc n) x (y ∷ xs) n+1≡|yxs| (there x∈xs)
= y ∷ proj₁ (del n x xs n≡|xs| x∈xs) ,
predn≡m→n≡sucm (x∈xs→|xs|>0 x∈xs n≡|xs|) (proj₂ (del n x xs n≡|xs| x∈xs))
where n≡|xs| = sucn≡sucm→n≡m n+1≡|yxs|
<→≢ : {n m : ℕ} → n < m → n ≢ m
<→≢ (s≤s n<m) refl = ⊥-elim (aux n<m)
where
aux : {n : ℕ} → suc n ≤ n → ⊥
aux (s≤s sucn≤n) = aux sucn≤n
del∈ : (x : ℕ)(xs : List ℕ) → (x∈xs : x ∈ xs) → (y : ℕ) → y < x → y ∈ xs → y ∈ (proj₁ (del (length' xs) x xs refl x∈xs))
del∈ x [] () y y<x y∈xs
del∈ x (.x ∷ xs) (here refl) .x x<x (here refl) = ⊥-elim ((<→≢ x<x) refl)
del∈ x (.x ∷ xs) (here refl) y y<x (there y∈xs) = y∈xs
del∈ x (.y ∷ xs) (there x∈xs) y y<x (here refl) = here refl
del∈ x (z ∷ xs) (there x∈xs) y y<x (there y∈xs) = there (del∈ x xs x∈xs y y<x y∈xs)
palomar-aux : (n : ℕ)(xs : List ℕ) → ((y : ℕ) → y ≤ n → y ∈ xs) → n ≡ length' xs → ⊥
palomar-aux .0 [] f refl with f 0 z≤n
... | ()
palomar-aux 0 (x ∷ xs) f ()
palomar-aux (suc n) (x ∷ xs) f sucn≡suc|xs| with any? (_≟_ (length' (x ∷ xs))) (x ∷ xs)
palomar-aux (suc n) (x ∷ xs) f sucn≡suc|xs|
| no |x∷xs|∉x∷xs = ⊥-elim (|x∷xs|∉x∷xs (f (suc (length' xs)) (subst₂ _≤_ refl (sym sucn≡suc|xs|) (m≤n+m (suc (length' xs)) 0))))
palomar-aux (suc n) (x ∷ xs) f sucn≡suc|xs|
| yes |x∷xs|∈x∷xs
with proj₁ (del (length' (x ∷ xs)) (length' (x ∷ xs)) (x ∷ xs) refl |x∷xs|∈x∷xs) |
proj₂ (del (length' (x ∷ xs)) (length' (x ∷ xs)) (x ∷ xs) refl |x∷xs|∈x∷xs) |
del∈ (length' (x ∷ xs)) (x ∷ xs) |x∷xs|∈x∷xs
palomar-aux (suc n) (x ∷ xs) f sucn≡suc|xs|
| yes |x∷xs|∈x∷xs | ys | |xs|≡|ys| | f2
= palomar-aux n ys fys (trans (sucn≡sucm→n≡m sucn≡suc|xs|) |xs|≡|ys|)
where
fys : (y : ℕ) → y ≤ n → y ∈ ys
fys y y≤n = f2 y (s≤s (subst₂ _≤_ refl (sucn≡sucm→n≡m sucn≡suc|xs|) y≤n)) (f y (≤-step y≤n))
palomar : (n : ℕ)(xs : List ℕ) → ((y : ℕ) → y < n → y ∈ xs) → n ≡ length' xs → n ∉ xs
palomar .(length' xs) xs f refl |xs|∈xs = palomar-aux (length' xs) xs (faux (length' xs) xs |xs|∈xs f refl) refl
where
faux : (n : ℕ)(xs : List ℕ) → length' xs ∈ xs → ((y : ℕ) → y < n → y ∈ xs) → n ≡ length' xs → (y : ℕ) → y ≤ length' xs → y ∈ xs
faux .(length' xs) xs |xs|∈xs f refl y y≤|xs| with ≤⇒≤′ y≤|xs|
faux .0 [] |xs|∈xs f refl .0 y≤|xs|
| ≤′-refl = |xs|∈xs
faux .(suc (length' xs)) (x ∷ xs) |xs|∈xs f refl .(suc (length' xs)) y≤|xs|+1
| ≤′-refl = |xs|∈xs
faux .(suc (length' xs)) (x ∷ xs) |xs|∈xs f refl .0 z≤n
| ≤′-step _ = f 0 (s≤s z≤n)
faux .(suc (length' xs)) (x ∷ xs) |xs|∈xs f refl (suc y) (s≤s a)
| ≤′-step b = f (suc y) (s≤s (≤′⇒≤ b))
xpfresh : ∀ xs → χ' xs ∉ xs
xpfresh xs with χaux 0 (length' xs) (length' xs) refl xs (y<0⇒y∈xs xs)
... | v , inj₁ v∉xs , _ = v∉xs
... | .((length' xs)) , inj₂ refl , f = palomar (length' xs) xs f refl
≤→<∨≡ : (n m : ℕ) → n ≤ m → n < m ∨ m ≡ n
≤→<∨≡ .0 0 z≤n = inj₂ refl
≤→<∨≡ .0 (suc n) z≤n = inj₁ (s≤s z≤n)
≤→<∨≡ .(suc n) .(suc m) (s≤s {n} {m} n≤m) with ≤→<∨≡ n m n≤m
... | inj₁ n<m = inj₁ (s≤s n<m)
≤→<∨≡ .(suc n) .(suc n) (s≤s {n} {.n} n≤n)
| inj₂ refl = inj₂ refl
<≡ : (n m : ℕ) → n < m ∨ m < n ∨ n ≡ m
<≡ n m with total n m
... | inj₂ m≤n = inj₂ (≤→<∨≡ m n m≤n)
... | inj₁ n≤m with ≤→<∨≡ n m n≤m
... | inj₁ n<m = inj₁ n<m
... | inj₂ n≡m = inj₂ (inj₂ (sym n≡m))
lemmaχaux⊆ℕ : ∀ xs ys → xs ⊆ ys → ys ⊆ xs → χ' xs ≡ χ' ys
lemmaχaux⊆ℕ xs ys xs⊆ys ys⊆xs
with
proj₁ (χaux 0 (length' xs) (length' xs) refl xs (y<0⇒y∈xs xs)) |
proj₂ (χaux 0 (length' xs) (length' xs) refl xs (y<0⇒y∈xs xs)) |
xpfresh xs |
proj₁ (χaux 0 (length' ys) (length' ys) refl ys (y<0⇒y∈xs ys)) |
proj₂ (χaux 0 (length' ys) (length' ys) refl ys (y<0⇒y∈xs ys)) |
xpfresh ys
... | x | _ , fx | x∉xs | y | _ , fy | y∉ys
with <≡ x y
... | inj₁ x<y = ⊥-elim (x∉xs (ys⊆xs (fy x x<y)))
... | inj₂ (inj₁ y<x) = ⊥-elim (y∉ys (xs⊆ys (fx y y<x)))
... | inj₂ (inj₂ x≡y) = x≡y
X' : List 𝒱 → 𝒱
X' xs = from (χ' (map to xs))
Xpfresh : ∀ xs → X' xs ∉ xs
Xpfresh xs χxs∈xs = ⊥-elim (xpfresh (map to xs) aux2)
where
xs' : List ℕ
xs' = map to xs
aux1 : to (from (χ' xs')) ∈ xs'
aux1 = ∈-map⁺ to χxs∈xs
aux2 : χ' xs' ∈ xs'
aux2 = subst (λ t → t ∈ xs') (to∘from (χ' xs')) aux1
lemmaχaux⊆ : ∀ xs ys → xs ⊆ ys → ys ⊆ xs → X' xs ≡ X' ys
lemmaχaux⊆ xs ys xs⊆ys ys⊆xs = cong from (lemmaχaux⊆ℕ (map to xs) (map to ys) (map⁺ to xs⊆ys) (map⁺ to ys⊆xs))
where
xs' ys' : List ℕ
xs' = map to xs
ys' = map to ys