module Examples.List.Vec where
open import Prelude.Function
open import Prelude.InverseImage
open import Prelude.Product
open import Refinement
open import Description
open import Ornament
open import Ornament.RefinementSemantics
open import Examples.Nat
open import Examples.List
open import Function using (_∘_; flip)
open import Data.Unit using (⊤; tt)
open import Data.Product using (Σ; Σ-syntax; _,_; proj₁; proj₂)
open import Relation.Binary.PropositionalEquality using (_≡_; refl; cong; proof-irrelevance)
VecD : (A : Set) → Desc (! ⋈ proj₁)
VecD A = OptPD ⌈ ListOD A ⌉
Vec : Set → Nat → Set
Vec A n = μ (VecD A) (ok tt , ok (tt , n))
VecO : (A : Set) → Orn π₁ ⌊ ListOD A ⌋ (VecD A)
VecO A = OptPO ⌈ ListOD A ⌉
vnil : {A : Set} → Vec A zero
vnil = con tt
vcons : {A : Set} → A → {n : Nat} → Vec A n → Vec A (suc n)
vcons x xs = con (x , xs , tt)
Length : Nat → {A : Set} → List A → Set
Length n {A} xs = OptP (VecO A) (ok (ok tt , ok (tt , n))) xs
Length-FSwap : (A : Set) → FSwap (RSem' (VecO A))
Length-FSwap A =
wrap λ { {._} (ok (ok _ , ok (_ , n))) →
record
{ Q = λ { xs → length xs ≡ n }
; s = λ { xs →
record
{ to = to n xs
; from = from n xs
; to-from-inverse = λ _ → proof-irrelevance _ _
; from-to-inverse = λ _ → ULP n xs } } } }
where to : ∀ n (xs : List A) → Length n xs → length xs ≡ n
to (con (`nil , _)) (con (`nil , _)) l = refl
to (con (`nil , _)) (con (`cons , x , xs , _)) (con (() , _))
to (con (`cons , n , _)) (con (`nil , _)) (con (() , _))
to (con (`cons , n , _)) (con (`cons , x , xs , _)) (con (refl , l , _)) = cong suc (to n xs l)
from : ∀ n (xs : List A) → length xs ≡ n → Length n xs
from (con (`nil , _)) (con (`nil , _)) eq = con (refl , tt)
from (con (`nil , _)) (con (`cons , x , xs , _)) ()
from (con (`cons , n , _)) (con (`nil , _)) ()
from (con (`cons , n , _)) (con (`cons , x , xs , _)) eq = con (refl , from n xs (cong proj₁ (cong-proj₂ (cong decon eq))) , tt)
ULP : ∀ n (xs : List A) {l l' : Length n xs} → l ≡ l'
ULP (con (`nil , _)) (con (`nil , _)) {con (refl , _)} {con (refl , _)} = refl
ULP (con (`nil , _)) (con (`cons , x , xs , _)) {con (() , _)}
ULP (con (`cons , n , _)) (con (`nil , _)) {con (() , _)}
ULP (con (`cons , n , _)) (con (`cons , x , xs , _)) {con (refl , l , _)} {con (refl , l' , _)} with ULP n xs {l} {l'}
ULP (con (`cons , n , _)) (con (`cons , x , xs , _)) {con (refl , l , _)} {con (refl , .l , _)} | refl = refl