2022-03-23 16:33:13 +03:00
|
|
|
||| This module contains stuff that may use functions from `Data.List`.
|
|
|
|
||| This separation is needed because `Data.List` uses `List1` type inside it,
|
|
|
|
||| thus the core of `List1` must not import `Data.List`.
|
|
|
|
module Data.List1.Properties
|
|
|
|
|
|
|
|
import Control.Function
|
|
|
|
|
|
|
|
import public Data.Maybe
|
|
|
|
import Data.List
|
|
|
|
import Data.List1
|
|
|
|
|
|
|
|
%default total
|
|
|
|
|
|
|
|
export
|
2022-05-19 22:32:22 +03:00
|
|
|
-- %deprecate -- deprecated in favor of Biinjective interface
|
2022-03-23 16:33:13 +03:00
|
|
|
consInjective : (x ::: xs) === (y ::: ys) -> (x === y, xs === ys)
|
|
|
|
consInjective Refl = (Refl, Refl)
|
|
|
|
|
2022-05-19 22:32:22 +03:00
|
|
|
export
|
|
|
|
Biinjective (:::) where
|
|
|
|
biinjective Refl = (Refl, Refl)
|
|
|
|
|
2022-03-23 16:33:13 +03:00
|
|
|
export
|
|
|
|
{x : a} -> Injective (x :::) where
|
|
|
|
injective Refl = Refl
|
|
|
|
|
|
|
|
export
|
|
|
|
{ys : List a} -> Injective (::: ys) where
|
|
|
|
injective Refl = Refl
|
|
|
|
|
|
|
|
||| Proof that the length of a List1 is the same as the length
|
|
|
|
||| of the List it represents.
|
|
|
|
export
|
|
|
|
listLength : (xs : List1 a) -> length xs = length (forget xs)
|
|
|
|
listLength (head ::: tail) = Refl
|
|
|
|
|
|
|
|
------------------------------------------------------------------------
|
|
|
|
-- Properties of append involving usual `List`'s append
|
|
|
|
|
|
|
|
export
|
|
|
|
appendlNilRightNeutral : (l : List1 a) -> l `appendl` [] = l
|
|
|
|
appendlNilRightNeutral (_:::xs) = rewrite appendNilRightNeutral xs in Refl
|
|
|
|
|
|
|
|
export
|
|
|
|
lappendNilLeftNeutral : (l : List1 a) -> [] `lappend` l = l
|
|
|
|
lappendNilLeftNeutral l = Refl
|
|
|
|
|
|
|
|
export
|
|
|
|
appendAssociative : (l, c, r : List1 a) -> l ++ (c ++ r) = (l ++ c) ++ r
|
|
|
|
appendAssociative (l:::ls) (c:::cs) (r:::rs) = rewrite appendAssociative ls (c::cs) (r::rs) in Refl
|
|
|
|
|
|
|
|
export
|
|
|
|
toListAppendl : (xs : List1 a) -> (ys : List a) -> toList (xs `appendl` ys) = forget xs ++ ys
|
|
|
|
toListAppendl (x:::xs) ys = Refl
|
|
|
|
|
|
|
|
export
|
|
|
|
toListLappend : (xs : List a) -> (ys : List1 a) -> toList (xs `lappend` ys) = xs ++ forget ys
|
|
|
|
toListLappend [] ys = Refl
|
|
|
|
toListLappend (x::xs) ys = Refl
|
|
|
|
|
|
|
|
export
|
|
|
|
toListAppend : (xs, ys : List1 a) -> toList (xs ++ ys) = toList xs ++ toList ys
|
|
|
|
toListAppend (x:::xs) (y:::ys) = Refl
|
|
|
|
|
|
|
|
export
|
|
|
|
fromListAppend : (xs, ys : List a) -> fromList (xs ++ ys) = (fromList xs <+> fromList ys) @{Deep}
|
|
|
|
fromListAppend [] ys with (fromList ys)
|
|
|
|
_ | Nothing = Refl
|
|
|
|
_ | (Just _) = Refl
|
|
|
|
fromListAppend (x::xs) ys with (fromList ys) proof prf
|
|
|
|
fromListAppend (x::xs) [] | Nothing = rewrite appendNilRightNeutral xs in Refl
|
2022-05-19 22:32:22 +03:00
|
|
|
fromListAppend (x::xs) (y::ys) | (Just $ l:::ls) =
|
|
|
|
let (Refl, Refl) = biinjective $ injective prf in Refl
|