m1-internship/ListUtil.agda

161 lines
6.2 KiB
Agda
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{-# OPTIONS --prop #-}
module ListUtil where
infixr 5 _∷_
data List : (T : Set) Set where
[] : {T : Set} List T
_∷_ : {T : Set} T List T List T
{-# BUILTIN LIST List #-}
private
variable
T : Set
L : List T
L' : List T
L'' : List T
A : T
B : T
-- Definition of list appartenance
-- The definition uses reflexivity and never any kind of equality
infix 3 _∈_
data _∈_ : T List T Prop where
zero∈ : A A L
next∈ : A L A B L
{- RELATIONS BETWEEN LISTS -}
-- We have the following relations
-- ↗ ⊂⁰ ↘
-- ⊆ → ⊂ → ⊂⁺ → ∈*
infix 4 _⊆_ _⊂_ _⊂⁺_ _⊂⁰_ _∈*_
{- ⊆ : We can remove elements but only from the head of the list -}
-- Similar definition : {L L' : List T} → L ⊆ L' ++ L
data _⊆_ : List T List T Prop where
zero⊆ : L L
next⊆ : L L' L (A L')
-- One useful lemma
retro⊆ : {L L' : List T} {A : T} (A L) L' L L'
retro⊆ {L' = []} () -- Impossible to have «A∷L ⊆ []»
retro⊆ {L' = B L'} zero⊆ = next⊆ zero⊆
retro⊆ {L' = B L'} (next⊆ h) = next⊆ (retro⊆ h)
refl⊆ : L L
refl⊆ = zero⊆
tran⊆ : L L' L' L'' L L''
tran⊆ zero⊆ h2 = h2
tran⊆ (next⊆ h1) h2 = tran⊆ h1 (retro⊆ h2)
{- ⊂ : We can remove elements anywhere on the list, no duplicates, no reordering -}
data _⊂_ : List T List T Prop where
zero⊂ : [] L
both⊂ : L L' (A L) (A L')
next⊂ : L L' L (A L')
⊆→⊂ : L L' L L'
refl⊂ : L L
⊆→⊂ {L = []} h = zero⊂
⊆→⊂ {L = x L} zero⊆ = both⊂ (refl⊂)
⊆→⊂ {L = x L} (next⊆ h) = next⊂ (⊆→⊂ h)
refl⊂ = ⊆→⊂ refl⊆
tran⊂ : L L' L' L'' L L''
tran⊂ zero⊂ h2 = zero⊂
tran⊂ (both⊂ h1) (both⊂ h2) = both⊂ (tran⊂ h1 h2)
tran⊂ (both⊂ h1) (next⊂ h2) = next⊂ (tran⊂ (both⊂ h1) h2)
tran⊂ (next⊂ h1) (both⊂ h2) = next⊂ (tran⊂ h1 h2)
tran⊂ (next⊂ h1) (next⊂ h2) = next⊂ (tran⊂ (next⊂ h1) h2)
{- ⊂⁰ : We can remove elements and reorder the list, as long as we don't duplicate the elements -}
-----> We do not have unicity of derivation ([A,A] ⊂⁰ [A,A] can be prove by identity or by swapping its two elements
--> We could do with some counting function, but ... it would not be nice, would it ?
data _⊂⁰_ : List T List T Prop where
zero⊂⁰ : _⊂⁰_ {T} [] []
next⊂⁰ : L ⊂⁰ L' L ⊂⁰ A L'
both⊂⁰ : L ⊂⁰ L' A L ⊂⁰ A L'
swap⊂⁰ : L ⊂⁰ A B L' L ⊂⁰ B A L'
error : L ⊂⁰ L'
-- TODOTODOTODOTODO Fix this definition
{- ⊂⁺ : We can remove and duplicate elements, as long as we don't change the order -}
data _⊂⁺_ : List T List T Prop where
zero⊂⁺ : _⊂⁺_ {T} [] []
next⊂⁺ : L ⊂⁺ L' L ⊂⁺ A L'
dup⊂⁺ : L ⊂⁺ A L' A L ⊂⁺ A L'
⊂→⊂⁺ : L L' L ⊂⁺ L'
⊂→⊂⁺ {L' = []} zero⊂ = zero⊂⁺
⊂→⊂⁺ {L' = x L'} zero⊂ = next⊂⁺ (⊂→⊂⁺ zero⊂)
⊂→⊂⁺ (both⊂ h) = dup⊂⁺ (next⊂⁺ (⊂→⊂⁺ h))
⊂→⊂⁺ (next⊂ h) = next⊂⁺ (⊂→⊂⁺ h)
refl⊂⁺ : L ⊂⁺ L
refl⊂⁺ = ⊂→⊂⁺ refl⊂
tran⊂⁺ : L ⊂⁺ L' L' ⊂⁺ L'' L ⊂⁺ L''
tran⊂⁺ zero⊂⁺ zero⊂⁺ = zero⊂⁺
tran⊂⁺ zero⊂⁺ (next⊂⁺ h2) = next⊂⁺ h2
tran⊂⁺ (next⊂⁺ h1) (next⊂⁺ h2) = next⊂⁺ (tran⊂⁺ (next⊂⁺ h1) h2)
tran⊂⁺ (next⊂⁺ h1) (dup⊂⁺ h2) = tran⊂⁺ h1 h2
tran⊂⁺ (dup⊂⁺ h1) (next⊂⁺ h2) = next⊂⁺ (tran⊂⁺ (dup⊂⁺ h1) h2)
tran⊂⁺ (dup⊂⁺ h1) (dup⊂⁺ h2) = dup⊂⁺ (tran⊂⁺ h1 (dup⊂⁺ h2))
retro⊂⁺ : A L ⊂⁺ L' L ⊂⁺ L'
retro⊂⁺ (next⊂⁺ h) = next⊂⁺ (retro⊂⁺ h)
retro⊂⁺ (dup⊂⁺ h) = h
{- ∈* : We can remove or duplicate elements and we can change their order -}
-- The weakest of all relations on lists
-- L ∈* L' if all elements of L exists in L' (no consideration for order nor duplication)
data _∈*_ : List T List T Prop where
zero∈* : [] ∈* L
next∈* : A L L' ∈* L (A L') ∈* L
-- Founding principle
mon∈∈* : A L L ∈* L' A L'
mon∈∈* zero∈ (next∈* x hl) = x
mon∈∈* (next∈ ha) (next∈* x hl) = mon∈∈* ha hl
-- We show that the relation is reflexive and is implied by ⊆
refl∈* : L ∈* L
⊂⁺→∈* : L ⊂⁺ L' L ∈* L'
refl∈* {L = []} = zero∈*
refl∈* {L = x L} = next∈* zero∈ (⊂⁺→∈* (next⊂⁺ refl⊂⁺))
⊂⁺→∈* zero⊂⁺ = refl∈*
⊂⁺→∈* {L = []} (next⊂⁺ h) = zero∈*
⊂⁺→∈* {L = x L} (next⊂⁺ h) = next∈* (next∈ (mon∈∈* zero∈ (⊂⁺→∈* h))) (⊂⁺→∈* (retro⊂⁺ (next⊂⁺ h)))
⊂⁺→∈* (dup⊂⁺ h) = next∈* zero∈ (⊂⁺→∈* h)
-- Allows to grow ∈* to the right
right∈* : L ∈* L' L ∈* (A L')
right∈* zero∈* = zero∈*
right∈* (next∈* x h) = next∈* (next∈ x) (right∈* h)
both∈* : L ∈* L' (A L) ∈* (A L')
both∈* zero∈* = next∈* zero∈ zero∈*
both∈* (next∈* x h) = next∈* zero∈ (next∈* (next∈ x) (right∈* h))
tran∈* : L ∈* L' L' ∈* L'' L ∈* L''
tran∈* {L = []} = λ x x₁ zero∈*
tran∈* {L = x L} (next∈* x₁ h1) h2 = next∈* (mon∈∈* x₁ h2) (tran∈* h1 h2)
⊆→∈* : L L' L ∈* L'
⊆→∈* h = ⊂⁺→∈* (⊂→⊂⁺ (⊆→⊂ h))
open import PropUtil using (Nat; zero; succ)
open import Agda.Primitive
variable
: Level
data Array (T : Set ) : Nat Set where
zero : Array T zero
next : {n : Nat} T Array T n Array T (succ n)
map : {T U : Set } (T U) {n : Nat} Array T n Array U n
map f zero = zero
map f (next t a) = next (f t) (map f a)