-
Notifications
You must be signed in to change notification settings - Fork 247
Some work on formalizing Suffix (re: #517) #551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ec73266
d5094db
5731194
efc1a07
2d374ec
f724ee4
21d26d2
9ea7330
16a631a
429edb8
fdf7001
d81576d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
------------------------------------------------------------------------ | ||
-- The Agda standard library | ||
-- | ||
-- An inductive definition of the heterogeneous suffix relation | ||
------------------------------------------------------------------------ | ||
|
||
module Data.List.Relation.Suffix.Heterogeneous where | ||
|
||
open import Level | ||
open import Relation.Binary using (REL; _⇒_) | ||
open import Data.List.Base as List using (List; []; _∷_) | ||
open import Data.List.Relation.Pointwise as Pointwise using (Pointwise; []; _∷_) | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} (R : REL A B r) where | ||
|
||
data Suffix : REL (List A) (List B) (a ⊔ b ⊔ r) where | ||
here : ∀ {as bs} → Pointwise R as bs → Suffix as bs | ||
there : ∀ {b as bs} → Suffix as bs → Suffix as (b ∷ bs) | ||
|
||
data SuffixView (as : List A) : List B → Set (a ⊔ b ⊔ r) where | ||
_++_ : ∀ cs {ds} → Pointwise R as ds → SuffixView as (cs List.++ ds) | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where | ||
|
||
tail : ∀ {a as bs} → Suffix R (a ∷ as) bs → Suffix R as bs | ||
tail (here (_ ∷ rs)) = there (here rs) | ||
tail (there x) = there (tail x) | ||
|
||
module _ {a b r s} {A : Set a} {B : Set b} {R : REL A B r} {S : REL A B s} where | ||
|
||
map : R ⇒ S → Suffix R ⇒ Suffix S | ||
map R⇒S (here rs) = here (Pointwise.map R⇒S rs) | ||
map R⇒S (there suf) = there (map R⇒S suf) | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where | ||
|
||
toView : ∀ {as bs} → Suffix R as bs → SuffixView R as bs | ||
toView (here rs) = [] ++ rs | ||
toView (there {c} suf) with toView suf | ||
... | cs ++ rs = (c ∷ cs) ++ rs | ||
|
||
fromView : ∀ {as bs} → SuffixView R as bs → Suffix R as bs | ||
fromView ([] ++ rs) = here rs | ||
fromView ((c ∷ cs) ++ rs) = there (fromView (cs ++ rs)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
------------------------------------------------------------------------ | ||
-- The Agda standard library | ||
-- | ||
-- Properties of the heterogeneous suffix relation | ||
------------------------------------------------------------------------ | ||
|
||
module Data.List.Relation.Suffix.Heterogeneous.Properties where | ||
|
||
open import Function using (_$_; flip) | ||
open import Relation.Nullary using (Dec; yes; no) | ||
import Relation.Nullary.Decidable as Dec | ||
open import Relation.Unary as U using (Pred) | ||
open import Relation.Nullary.Negation using (contradiction) | ||
open import Relation.Binary as B using (REL; Rel; Trans; Antisym; Irrelevant; _⇒_) | ||
open import Relation.Binary.PropositionalEquality as P using (_≡_; refl; sym; subst) | ||
open import Data.Nat as N using (suc; _+_; _≤_; _<_) | ||
open import Data.List as List | ||
using (List; []; _∷_; _++_; length; filter; replicate; reverse; reverseAcc) | ||
open import Data.List.Relation.Pointwise as Pw using (Pointwise; []; _∷_; Pointwise-length) | ||
open import Data.List.Relation.Suffix.Heterogeneous as Suffix using (Suffix; here; there; tail) | ||
open import Data.List.Relation.Prefix.Heterogeneous as Prefix using (Prefix) | ||
import Data.Nat.Properties as ℕₚ | ||
import Data.List.Properties as Listₚ | ||
import Data.List.Relation.Prefix.Heterogeneous.Properties as Prefixₚ | ||
|
||
------------------------------------------------------------------------ | ||
-- reverse (convert to and from Prefix) | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where | ||
|
||
fromPrefix⁺ : ∀ {as bs} → Prefix R as bs → Suffix R (reverse as) (reverse bs) | ||
fromPrefix⁺ {as} {bs} p with Prefix.toView p | ||
... | Prefix._++_ {cs} rs ds = subst (Suffix R (reverse as)) | ||
(sym (Listₚ.reverse-++-commute cs ds)) | ||
$ Suffix.fromView (reverse ds Suffix.++ Pw.reverse⁺ rs) | ||
|
||
fromPrefix⁻ : ∀ {as bs} → Prefix R (reverse as) (reverse bs) → Suffix R as bs | ||
fromPrefix⁻ pre = P.subst₂ (Suffix R) (Listₚ.reverse-involutive _) (Listₚ.reverse-involutive _) | ||
$ fromPrefix⁺ pre | ||
|
||
toPrefix⁺ : ∀ {as bs} → Suffix R as bs → Prefix R (reverse as) (reverse bs) | ||
toPrefix⁺ {as} {bs} s with Suffix.toView s | ||
... | Suffix._++_ cs {ds} rs = subst (Prefix R (reverse as)) | ||
(sym (Listₚ.reverse-++-commute cs ds)) | ||
$ Prefix.fromView (Pw.reverse⁺ rs Prefix.++ reverse cs) | ||
|
||
toPrefix⁻ : ∀ {as bs} → Suffix R (reverse as) (reverse bs) → Prefix R as bs | ||
toPrefix⁻ suf = P.subst₂ (Prefix R) (Listₚ.reverse-involutive _) (Listₚ.reverse-involutive _) | ||
$ toPrefix⁺ suf | ||
|
||
------------------------------------------------------------------------ | ||
-- length | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} {as} where | ||
|
||
length-mono-Suffix-≤ : ∀ {bs} → Suffix R as bs → length as ≤ length bs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this could just be called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm to blame for this one: https://agda.github.io/agda-stdlib/Data.List.Relation.Prefix.Heterogeneous.Properties.html#2512 (and I have a similar one for the upcoming Sublist in #562) Should we change all of these to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes please, I think we probably should. I think the convention is not to reference the data type within the properties file. |
||
length-mono-Suffix-≤ (here rs) = ℕₚ.≤-reflexive (Pointwise-length rs) | ||
length-mono-Suffix-≤ (there suf) = ℕₚ.≤-step (length-mono-Suffix-≤ suf) | ||
|
||
------------------------------------------------------------------------ | ||
-- Pointwise conversion | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where | ||
|
||
fromPointwise : Pointwise R ⇒ Suffix R | ||
fromPointwise = here | ||
|
||
toPointwise : ∀ {as bs} → length as ≡ length bs → Suffix R as bs → Pointwise R as bs | ||
toPointwise eq (here rs) = rs | ||
toPointwise eq (there suf) = | ||
let as≤bs = length-mono-Suffix-≤ suf | ||
as>bs = ℕₚ.≤-reflexive (sym eq) | ||
in contradiction as≤bs (ℕₚ.<⇒≱ as>bs) | ||
|
||
------------------------------------------------------------------------ | ||
-- Suffix as a partial order | ||
|
||
module _ {a b c r s t} {A : Set a} {B : Set b} {C : Set c} | ||
{R : REL A B r} {S : REL B C s} {T : REL A C t} where | ||
|
||
trans : Trans R S T → Trans (Suffix R) (Suffix S) (Suffix T) | ||
trans rs⇒t (here rs) (here ss) = here (Pw.transitive rs⇒t rs ss) | ||
trans rs⇒t (here rs) (there ssuf) = there (trans rs⇒t (here rs) ssuf) | ||
trans rs⇒t (there rsuf) ssuf = trans rs⇒t rsuf (tail ssuf) | ||
|
||
module _ {a b e r s} {A : Set a} {B : Set b} | ||
{R : REL A B r} {S : REL B A s} {E : REL A B e} where | ||
|
||
antisym : Antisym R S E → Antisym (Suffix R) (Suffix S) (Pointwise E) | ||
antisym rs⇒e rsuf ssuf = Pw.antisymmetric | ||
rs⇒e | ||
(toPointwise eq rsuf) | ||
(toPointwise (sym eq) ssuf) | ||
where eq = ℕₚ.≤-antisym (length-mono-Suffix-≤ rsuf) (length-mono-Suffix-≤ ssuf) | ||
|
||
------------------------------------------------------------------------ | ||
-- _++_ | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where | ||
|
||
++⁺ : ∀ {as bs cs ds} → Suffix R as bs → Pointwise R cs ds → | ||
Suffix R (as ++ cs) (bs ++ ds) | ||
++⁺ (here rs) rs′ = here (Pw.++⁺ rs rs′) | ||
++⁺ (there suf) rs′ = there (++⁺ suf rs′) | ||
|
||
++⁻ : ∀ {as bs cs ds} → length cs ≡ length ds → | ||
Suffix R (as ++ cs) (bs ++ ds) → Pointwise R cs ds | ||
++⁻ {_ ∷ _} {_} eq suf = ++⁻ eq (tail suf) | ||
++⁻ {[]} {[]} eq suf = toPointwise eq suf | ||
++⁻ {[]} {b ∷ bs} eq (there suf) = ++⁻ eq suf | ||
++⁻ {[]} {b ∷ bs} {cs} {ds} eq (here rs) = contradiction (sym eq) (ℕₚ.<⇒≢ ds<cs) | ||
where | ||
open ℕₚ.≤-Reasoning | ||
ds<cs : length ds < length cs | ||
ds<cs = begin suc (length ds) ≤⟨ N.s≤s (ℕₚ.n≤m+n (length bs) (length ds)) ⟩ | ||
suc (length bs + length ds) ≡⟨ sym $ Listₚ.length-++ (b ∷ bs) ⟩ | ||
length (b ∷ bs ++ ds) ≡⟨ sym $ Pointwise-length rs ⟩ | ||
length cs ∎ | ||
|
||
------------------------------------------------------------------------ | ||
-- map | ||
|
||
module _ {a b c d r} {A : Set a} {B : Set b} {C : Set c} {D : Set d} | ||
{R : REL C D r} where | ||
|
||
map⁺ : ∀ {as bs} (f : A → C) (g : B → D) → | ||
Suffix (λ a b → R (f a) (g b)) as bs → | ||
Suffix R (List.map f as) (List.map g bs) | ||
map⁺ f g (here rs) = here (Pw.map⁺ f g rs) | ||
map⁺ f g (there suf) = there (map⁺ f g suf) | ||
|
||
map⁻ : ∀ {as bs} (f : A → C) (g : B → D) → | ||
Suffix R (List.map f as) (List.map g bs) → | ||
Suffix (λ a b → R (f a) (g b)) as bs | ||
map⁻ {as} {b ∷ bs} f g (here rs) = here (Pw.map⁻ f g rs) | ||
map⁻ {as} {b ∷ bs} f g (there suf) = there (map⁻ f g suf) | ||
map⁻ {x ∷ as} {[]} f g suf with length-mono-Suffix-≤ suf | ||
... | () | ||
map⁻ {[]} {[]} f g suf = here [] | ||
|
||
------------------------------------------------------------------------ | ||
-- filter | ||
|
||
module _ {a b r p q} {A : Set a} {B : Set b} {R : REL A B r} | ||
{P : Pred A p} {Q : Pred B q} (P? : U.Decidable P) (Q? : U.Decidable Q) | ||
(P⇒Q : ∀ {a b} → R a b → P a → Q b) (Q⇒P : ∀ {a b} → R a b → Q b → P a) | ||
where | ||
|
||
filter⁺ : ∀ {as bs} → Suffix R as bs → Suffix R (filter P? as) (filter Q? bs) | ||
filter⁺ (here rs) = here (Pw.filter⁺ P? Q? P⇒Q Q⇒P rs) | ||
filter⁺ (there {a} suf) with Q? a | ||
... | yes q = there (filter⁺ suf) | ||
... | no ¬q = filter⁺ suf | ||
|
||
------------------------------------------------------------------------ | ||
-- replicate | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where | ||
|
||
replicate⁺ : ∀ {m n a b} → m ≤ n → R a b → Suffix R (replicate m a) (replicate n b) | ||
replicate⁺ {a = a} {b = b} m≤n r = repl (ℕₚ.≤⇒≤′ m≤n) | ||
where | ||
repl : ∀ {m n} → m N.≤′ n → Suffix R (replicate m a) (replicate n b) | ||
repl N.≤′-refl = here (Pw.replicate⁺ r _) | ||
repl (N.≤′-step m≤n) = there (repl m≤n) | ||
|
||
------------------------------------------------------------------------ | ||
-- Irrelevant | ||
|
||
module _ {a b r} {A : Set a} {B : Set b} {R : REL A B r} where | ||
|
||
irrelevant : Irrelevant R → Irrelevant (Suffix R) | ||
irrelevant R-irr (here rs) (here rs₁) = P.cong here $ Pw.irrelevant R-irr rs rs₁ | ||
irrelevant R-irr (here rs) (there rsuf) = contradiction (length-mono-Suffix-≤ rsuf) | ||
(ℕₚ.<⇒≱ (ℕₚ.≤-reflexive (sym (Pointwise-length rs)))) | ||
irrelevant R-irr (there rsuf) (here rs) = contradiction (length-mono-Suffix-≤ rsuf) | ||
(ℕₚ.<⇒≱ (ℕₚ.≤-reflexive (sym (Pointwise-length rs)))) | ||
irrelevant R-irr (there rsuf) (there rsuf₁) = P.cong there $ irrelevant R-irr rsuf rsuf₁ | ||
|
||
------------------------------------------------------------------------ | ||
-- Decidability | ||
|
||
suffix? : B.Decidable R → B.Decidable (Suffix R) | ||
suffix? R? as bs = Dec.map′ fromPrefix⁻ toPrefix⁺ | ||
$ Prefixₚ.prefix? R? (reverse as) (reverse bs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like
fromPrefix
to me (no need for the⁺
as the conclusiondoes not mention a function called
fromPrefix
).It should probably go in
Suffix.Heterogeneous
proper rather thanX.Properties
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see. The problem is that
toPrefix⁻
is eerily similar. Hmm.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I agree with @gallais that these names don't obey the conventions used elsewhere. I think better names for these lemmas might be
fromPrefix
,fromPrefix-rev
,toPrefix-rev
andtoPrefix
respectively...