view Paper/src/agda/_Fresh.agda.replaced @ 5:339fb67b4375

INIT rbt.agda
author soto <soto@cr.ie.u-ryukyu.ac.jp>
date Sun, 07 Nov 2021 00:51:16 +0900
parents 9176dff8f38a
children
line wrap: on
line source

------------------------------------------------------------------------
-- The Agda standard library
--
-- Fresh lists, a proof relevant variant of Catarina Coquand!$\prime$!s contexts in
-- "A Formalised Proof of the Soundness and Completeness of a Simply Typed
-- Lambda-Calculus with Explicit Substitutions"
------------------------------------------------------------------------

-- See README.Data.List.Fresh and README.Data.Trie.NonDependent for
-- examples of how to use fresh lists.

{-!$\#$! OPTIONS --without-K --safe !$\#$!-}

module Data.List.Fresh where

open import Level using (Level; _!$\sqcup$!_)
open import Data.Bool.Base using (true; false)
open import Data.Unit.Polymorphic.Base using (!$\top$!)
open import Data.Product using (∃; _!$\times$!_; _,_; -,_; proj!$\_{1}$!; proj!$\_{2}$!)
open import Data.List.Relation.Unary.All using (All; []; _!$\text{::}$!_)
open import Data.List.Relation.Unary.AllPairs using (AllPairs; []; _!$\text{::}$!_)
open import Data.Maybe.Base as Maybe using (Maybe; just; nothing)
open import Data.Nat.Base using (!$\mathbb{N}$!; zero; suc)
open import Function using (_∘′_; flip; id; _on_)
open import Relation.Nullary      using (does)
open import Relation.Unary   as U using (Pred)
open import Relation.Binary  as B using (Rel)
open import Relation.Nary

private
  variable
    a b p r s : Level
    A : Set a
    B : Set b

------------------------------------------------------------------------
-- Basic type

-- If we pick an R such that (R a b) means that a is different from b
-- then we have a list of distinct values.

module _ {a} (A : Set a) (R : Rel A r) where

  data List!$\#$! : Set (a !$\sqcup$! r)
  fresh : (a : A) (as : List!$\#$!) !$\rightarrow$! Set r

  data List!$\#$! where
    []   : List!$\#$!
    cons : (a : A) (as : List!$\#$!) !$\rightarrow$! fresh a as !$\rightarrow$! List!$\#$!

  -- Whenever R can be reconstructed by η-expansion (e.g. because it is
  -- the erasure ⌊_⌋ of a decidable predicate, cf. Relation.Nary) or we
  -- do not care about the proof, it is convenient to get back list syntax.

  -- We use a different symbol to avoid conflict when importing both Data.List
  -- and Data.List.Fresh.
  infixr 5 _!$\text{::}$!!$\#$!_
  pattern _!$\text{::}$!!$\#$!_ x xs = cons x xs _

  fresh a []        = !$\top$!
  fresh a (x !$\text{::}$!!$\#$! xs) = R a x !$\times$! fresh a xs

-- Convenient notation for freshness making A and R implicit parameters
infix 5 _!$\#$!_
_!$\#$!_ : {R : Rel A r} (a : A) (as : List!$\#$! A R) !$\rightarrow$! Set r
_!$\#$!_ = fresh _ _

------------------------------------------------------------------------
-- Operations for modifying fresh lists

module _ {R : Rel A r} {S : Rel B s} (f : A !$\rightarrow$! B) (R!$\Rightarrow$!S : !$\forall$![ R !$\Rightarrow$! (S on f) ]) where

  map   : List!$\#$! A R !$\rightarrow$! List!$\#$! B S
  map-!$\#$! : !$\forall$! {a} as !$\rightarrow$! a !$\#$! as !$\rightarrow$! f a !$\#$! map as

  map []             = []
  map (cons a as ps) = cons (f a) (map as) (map-!$\#$! as ps)

  map-!$\#$! []        _        = _
  map-!$\#$! (a !$\text{::}$!!$\#$! as) (p , ps) = R!$\Rightarrow$!S p , map-!$\#$! as ps

module _ {R : Rel B r} (f : A !$\rightarrow$! B) where

  map!$\_{1}$! : List!$\#$! A (R on f) !$\rightarrow$! List!$\#$! B R
  map!$\_{1}$! = map f id

module _ {R : Rel A r} {S : Rel A s} (R!$\Rightarrow$!S : !$\forall$![ R !$\Rightarrow$! S ]) where

  map!$\_{2}$! : List!$\#$! A R !$\rightarrow$! List!$\#$! A S
  map!$\_{2}$! = map id R!$\Rightarrow$!S

------------------------------------------------------------------------
-- Views

data Empty {A : Set a} {R : Rel A r} : List!$\#$! A R !$\rightarrow$! Set (a !$\sqcup$! r) where
  [] : Empty []

data NonEmpty {A : Set a} {R : Rel A r} : List!$\#$! A R !$\rightarrow$! Set (a !$\sqcup$! r) where
  cons : !$\forall$! x xs pr !$\rightarrow$! NonEmpty (cons x xs pr)

------------------------------------------------------------------------
-- Operations for reducing fresh lists

length : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! !$\mathbb{N}$!
length []        = 0
length (_ !$\text{::}$!!$\#$! xs) = suc (length xs)

------------------------------------------------------------------------
-- Operations for constructing fresh lists

pattern [_] a = a !$\text{::}$!!$\#$! []

fromMaybe : {R : Rel A r} !$\rightarrow$! Maybe A !$\rightarrow$! List!$\#$! A R
fromMaybe nothing  = []
fromMaybe (just a) = [ a ]

module _ {R : Rel A r} (R-refl : B.Reflexive R) where

  replicate   : !$\mathbb{N}$! !$\rightarrow$! A !$\rightarrow$! List!$\#$! A R
  replicate-!$\#$! : (n : !$\mathbb{N}$!) (a : A) !$\rightarrow$! a !$\#$! replicate n a

  replicate zero    a = []
  replicate (suc n) a = cons a (replicate n a) (replicate-!$\#$! n a)

  replicate-!$\#$! zero    a = _
  replicate-!$\#$! (suc n) a = R-refl , replicate-!$\#$! n a

------------------------------------------------------------------------
-- Operations for deconstructing fresh lists

uncons : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! Maybe (A !$\times$! List!$\#$! A R)
uncons []        = nothing
uncons (a !$\text{::}$!!$\#$! as) = just (a , as)

head : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! Maybe A
head = Maybe.map proj!$\_{1}$! ∘′ uncons

tail : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! Maybe (List!$\#$! A R)
tail = Maybe.map proj!$\_{2}$! ∘′ uncons

take   : {R : Rel A r} !$\rightarrow$! !$\mathbb{N}$! !$\rightarrow$! List!$\#$! A R !$\rightarrow$! List!$\#$! A R
take-!$\#$! : {R : Rel A r} !$\rightarrow$! !$\forall$! n a (as : List!$\#$! A R) !$\rightarrow$! a !$\#$! as !$\rightarrow$! a !$\#$! take n as

take zero    xs             = []
take (suc n) []             = []
take (suc n) (cons a as ps) = cons a (take n as) (take-!$\#$! n a as ps)

take-!$\#$! zero    a xs        _        = _
take-!$\#$! (suc n) a []        ps       = _
take-!$\#$! (suc n) a (x !$\text{::}$!!$\#$! xs) (p , ps) = p , take-!$\#$! n a xs ps

drop : {R : Rel A r} !$\rightarrow$! !$\mathbb{N}$! !$\rightarrow$! List!$\#$! A R !$\rightarrow$! List!$\#$! A R
drop zero    as        = as
drop (suc n) []        = []
drop (suc n) (a !$\text{::}$!!$\#$! as) = drop n as

module _ {P : Pred A p} (P? : U.Decidable P) where

  takeWhile   : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! List!$\#$! A R
  takeWhile-!$\#$! : !$\forall$! {R : Rel A r} a (as : List!$\#$! A R) !$\rightarrow$! a !$\#$! as !$\rightarrow$! a !$\#$! takeWhile as

  takeWhile []             = []
  takeWhile (cons a as ps) with does (P? a)
  ... | true  = cons a (takeWhile as) (takeWhile-!$\#$! a as ps)
  ... | false = []

  takeWhile-!$\#$! a []        _        = _
  takeWhile-!$\#$! a (x !$\text{::}$!!$\#$! xs) (p , ps) with does (P? x)
  ... | true  = p , takeWhile-!$\#$! a xs ps
  ... | false = _

  dropWhile : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! List!$\#$! A R
  dropWhile []            = []
  dropWhile aas@(a !$\text{::}$!!$\#$! as) with does (P? a)
  ... | true  = dropWhile as
  ... | false = aas

  filter   : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! List!$\#$! A R
  filter-!$\#$! : !$\forall$! {R : Rel A r} a (as : List!$\#$! A R) !$\rightarrow$! a !$\#$! as !$\rightarrow$! a !$\#$! filter as

  filter []             = []
  filter (cons a as ps) with does (P? a)
  ... | true  = cons a (filter as) (filter-!$\#$! a as ps)
  ... | false = filter as

  filter-!$\#$! a []        _        = _
  filter-!$\#$! a (x !$\text{::}$!!$\#$! xs) (p , ps) with does (P? x)
  ... | true  = p , filter-!$\#$! a xs ps
  ... | false = filter-!$\#$! a xs ps

------------------------------------------------------------------------
-- Relationship to List and AllPairs

toList : {R : Rel A r} !$\rightarrow$! List!$\#$! A R !$\rightarrow$! ∃ (AllPairs R)
toAll  : !$\forall$! {R : Rel A r} {a} as !$\rightarrow$! fresh A R a as !$\rightarrow$! All (R a) (proj!$\_{1}$! (toList as))

toList []             = -, []
toList (cons x xs ps) = -, toAll xs ps !$\text{::}$! proj!$\_{2}$! (toList xs)

toAll []        ps       = []
toAll (a !$\text{::}$!!$\#$! as) (p , ps) = p !$\text{::}$! toAll as ps

fromList   : !$\forall$! {R : Rel A r} {xs} !$\rightarrow$! AllPairs R xs !$\rightarrow$! List!$\#$! A R
fromList-!$\#$! : !$\forall$! {R : Rel A r} {x xs} (ps : AllPairs R xs) !$\rightarrow$!
             All (R x) xs !$\rightarrow$! x !$\#$! fromList ps

fromList []       = []
fromList (r !$\text{::}$! rs) = cons _ (fromList rs) (fromList-!$\#$! rs r)

fromList-!$\#$! []       _        = _
fromList-!$\#$! (p !$\text{::}$! ps) (r !$\text{::}$! rs) = r , fromList-!$\#$! ps rs