module Utils.List where
This module contains definitions, functions and properties for different kinds lists, such as backwards lists, indexed lists, and lists indexed over indexed lists.
open import Data.Nat using (ℕ;zero;suc) open import Data.List using (List;[];_∷_;_++_;map;foldr;length;head) public open import Data.List.Properties using (foldr-++;++-cancelʳ;∷-injective) open import Relation.Binary.PropositionalEquality using (_≡_;refl;sym;cong;trans;subst;subst-subst) open import Data.Empty using (⊥;⊥-elim) open import Data.Product using (Σ;_×_;_,_;proj₂) open import Relation.Nullary using (¬_) open import Utils using (≡-subst-removable)
data Bwd (A : Set) : Set where [] : Bwd A _:<_ : Bwd A → A → Bwd A infixl 5 _:<_ bwd-length : ∀{A} → Bwd A → ℕ bwd-length [] = 0 bwd-length (az :< a) = suc (bwd-length az) bwd-foldr : ∀{A B : Set} → (A → B → B) → B → Bwd A → B bwd-foldr f e [] = e bwd-foldr f e (bs :< x) = bwd-foldr f (f x e) bs
Fish (<><) and chips (<») are two operators to concatenate a backwards list and a list together, either by consing every snoc and obtaining a list, or by snoc-ing every cons and obtaining a backwards list.
_<>>_ : ∀{A} → Bwd A → List A → List A [] <>> as = as (az :< a) <>> as = az <>> (a ∷ as) _<><_ : ∀{A} → Bwd A → List A → Bwd A az <>< [] = az az <>< (a ∷ as) = (az :< a) <>< as
Snoc for lists and cons for backwards lists.
_:<L_ : ∀{A : Set} → List A → A → List A as :<L a = as ++ (a ∷ []) _∷B_ : ∀{A : Set} → A → Bwd A → Bwd A a ∷B [] = [] :< a a ∷B (as' :< a') = (a ∷B as') :< a'
Useful lemmas
lemma<>1 : ∀{A}(xs : Bwd A)(ys : List A) → (xs <>< ys) <>> [] ≡ xs <>> ys lemma<>1 xs [] = refl lemma<>1 xs (x ∷ ys) = lemma<>1 (xs :< x) ys lemma<>1' : ∀{A}(xs : Bwd A)(ys : List A) → xs ≡ [] <>< ys → xs <>> [] ≡ ys lemma<>1' xs ys refl = lemma<>1 [] ys lemma<>2 : ∀{A}(xs : Bwd A)(ys : List A) → ([] <>< (xs <>> ys)) ≡ xs <>< ys lemma<>2 [] ys = refl lemma<>2 (xs :< x) ys = lemma<>2 xs (x ∷ ys) lemma<>2' : ∀{A}(xs : Bwd A)(ys : List A) → xs <>> [] ≡ ys → [] <>< ys ≡ xs lemma<>2' xs ys refl = lemma<>2 xs [] lemma-<>>-++ : ∀{A : Set} bs (as as' : List A) → bs <>> (as ++ as') ≡ (bs <>> as) ++ as' lemma-<>>-++ [] as as' = refl lemma-<>>-++ (bs :< x) as as' = lemma-<>>-++ bs (x ∷ as) as' lemma-bwd-foldr : ∀{A B}(f : A → B → B)(e : B)(bs : Bwd A) → foldr f e (bs <>> []) ≡ bwd-foldr f e bs lemma-bwd-foldr f e [] = refl lemma-bwd-foldr f e (bs :< b) = trans (trans ((cong (foldr f e) (lemma-<>>-++ bs [] (b ∷ [])))) (foldr-++ f e (bs <>> []) (b ∷ []))) (lemma-bwd-foldr f (f b e) bs)
Some cancellation lemmas
<><-cancelʳ : ∀{A : Set} (bs bs' : Bwd A) xs → bs <>< xs ≡ bs' <>< xs → bs ≡ bs' <><-cancelʳ bs bs' [] p = p <><-cancelʳ bs bs' (x ∷ xs) p with <><-cancelʳ (bs :< x) (bs' :< x) xs p ... | refl = refl <>>[]-cancelʳ : ∀{A : Set} (bs bs' : Bwd A) → bs <>> [] ≡ bs' <>> [] → bs ≡ bs' <>>[]-cancelʳ bs bs' p = trans (sym (lemma<>2' bs (bs' <>> []) p)) (lemma<>2 bs' []) <>>-cancelʳ : ∀{A : Set} (bs bs' : Bwd A) xs → bs <>> xs ≡ bs' <>> xs → bs ≡ bs' <>>-cancelʳ bs bs' xs p = <>>[]-cancelʳ bs bs' (++-cancelʳ xs (bs <>> []) (bs' <>> []) (trans (sym (lemma-<>>-++ bs [] xs)) (trans p (lemma-<>>-++ bs' [] xs)) ) ) <>>-cancelˡ : ∀{A : Set} (bs : Bwd A) xs xs' → bs <>> xs ≡ bs <>> xs' → xs ≡ xs' <>>-cancelˡ [] xs xs' p = p <>>-cancelˡ (bs :< x) xs xs' p with <>>-cancelˡ bs (x ∷ xs) (x ∷ xs') p ... | refl = refl
Indexed lists IList
are lists of elements of an indexed set.
They are indexed by the list of all indices which index its elements.
data IList {A : Set}(B : A → Set) : List A → Set where [] : IList B [] _∷_ : ∀{ty ts} → B ty → IList B ts → IList B (ty ∷ ts) -- Concatenation for Indexed Lists _++I_ : ∀{A : Set}{B : A → Set}{ts ts' : List A} → IList B ts → IList B ts' → IList B (ts ++ ts') [] ++I bs = bs (x ∷ as) ++I bs = x ∷ (as ++I bs) lengthT : ∀{A : Set}{ts : List A}{B : A → Set} → IList B ts → ℕ lengthT {ts = ts} _ = length ts iGetIdx : ∀{A : Set}{ts : List A}{B : A → Set} → IList B ts → List A iGetIdx {ts = ts} ils = ts -- snoc for Indexed Lists. _:<I_ : ∀{A : Set}{B : A → Set}{t}{ts : List A} → IList B ts → B t → IList B (ts :<L t) as :<I a = as ++I (a ∷ []) -- Injectivity of cons ∷-injectiveI : ∀ {A : Set}{B : A → Set}{t : A}{ts ts' : List A} {X Y : B t}{Xs : IList B ts}{Ys : IList B ts'} → (p : t ∷ ts' ≡ t ∷ ts) → _≡_ {_} {IList B (t ∷ ts)} (X ∷ Xs) (subst (IList B) p (Y ∷ Ys)) → X ≡ Y × Xs ≡ subst (IList B) (proj₂ (∷-injective p)) Ys ∷-injectiveI refl refl = refl , refl
data IBwd {A : Set}(B : A → Set) : Bwd A → Set where [] : IBwd B [] _:<_ : ∀{ty ts} → IBwd B ts → B ty → IBwd B (ts :< ty) -- Chip for indexed lists _<>>I_ : ∀{A : Set}{B : A → Set}{bs : Bwd A}{ts : List A} → IBwd B bs → IList B ts → IList B (bs <>> ts) [] <>>I tls = tls (tbs :< x) <>>I tls = tbs <>>I (x ∷ tls) _<><I_ : ∀{A : Set}{B : A → Set}{bs : Bwd A}{ts : List A} → IBwd B bs → IList B ts → IBwd B (bs <>< ts) ibs <><I [] = ibs ibs <><I (x ∷ its) = (ibs :< x) <><I its lemma<>I1 : ∀{A}{B : A → Set}{xs : Bwd A}{ys : List A} → (ixs : IBwd B xs) → (iys : IList B ys) → (subst (IList B) (lemma<>1 xs ys) ((ixs <><I iys) <>>I [])) ≡ ixs <>>I iys lemma<>I1 ixs [] = refl lemma<>I1 ixs (iy ∷ iys) = lemma<>I1 (ixs :< iy) iys lemma<>I2 : ∀{A}{B : A → Set}{xs : Bwd A}{ys : List A}(ixs : IBwd B xs)(iys : IList B ys) → subst (IBwd B) (lemma<>2 xs ys) ([] <><I (ixs <>>I iys)) ≡ ixs <><I iys lemma<>I2 [] iys = refl lemma<>I2 (ixs :< ix) iys = lemma<>I2 ixs (ix ∷ iys) lemma<>I2' : ∀{A}{B : A → Set}{xs : Bwd A}{ys : List A}(ixs : IBwd B xs)(iys : IList B ys) → ([] <><I (ixs <>>I iys)) ≡ subst (IBwd B) (sym (lemma<>2 xs ys)) (ixs <><I iys) lemma<>I2' [] iys = refl lemma<>I2' (ixs :< ix) iys = lemma<>I2' ixs (ix ∷ iys) IBwd2IList' : ∀{A}{B : A → Set}{bs}{ts} → (bs ≡ [] <>< ts) → IBwd B bs → IList B ts IBwd2IList' {ts = ts} p tbs = subst (IList _) (trans (cong (_<>> []) p) (lemma<>1 [] ts)) (tbs <>>I []) IBwd2IList : ∀{A}{B : A → Set}{bs}{ts} → (bs <>> [] ≡ ts) → IBwd B bs → IList B ts IBwd2IList p tbs = subst (IList _) p (tbs <>>I []) IList2IBwd : ∀{A}{B : A → Set}{ts}{bs} → ([] <>< ts ≡ bs) → IList B ts → IBwd B bs IList2IBwd {ts = ts} p tbs = subst (IBwd _) p ([] <><I tbs) IBwd<>IList : ∀{A}{B : A → Set}{bs}{ts} → (p : bs <>> [] ≡ ts) → {ibs : IBwd B bs} → {its : IList B ts} → IBwd2IList p ibs ≡ its → ibs ≡ IList2IBwd (lemma<>2' _ _ p) its IBwd<>IList refl {ibs} refl rewrite lemma<>I2 ibs [] = refl split : ∀{A : Set} bs (ts : List A){B : A → Set} → IList B (bs <>> ts) → IBwd B bs × IList B ts split [] ts vs = [] , vs split (bs :< x) ts vs with split bs (x ∷ ts) vs ... | ls , (x ∷ rs) = ls :< x , rs bsplit : ∀{A : Set} bs (ts : List A){B : A → Set} → IBwd B (bs <>< ts) → IBwd B bs × IList B ts bsplit bs [] vs = vs , [] bsplit bs (x ∷ ts) vs with bsplit (bs :< x) ts vs ... | ls :< x , rs = ls , (x ∷ rs) inj-IBwd2IList : ∀{A}{B : A → Set}{Bs}{As : List A}{ts ts' : IBwd B Bs} → (p : Bs <>> [] ≡ As) → IBwd2IList {ts = As} p ts ≡ IBwd2IList p ts' → ts ≡ ts' inj-IBwd2IList refl q = trans (trans (sym (lemma<>I2 _ [])) (cong (IList2IBwd (lemma<>2' _ _ refl)) q)) (lemma<>I2 _ [])
The following datatype allow us to index zippers of indexed lists.
data _≣_<>>_ {A : Set} : (as : List A) → Bwd A → List A → Set where start : ∀{as} → as ≣ [] <>> as bubble : ∀{as}{vs : Bwd A}{t}{ts : List A} → as ≣ vs <>> (t ∷ ts) --------------------------- → as ≣ (vs :< t) <>> ts lem-≣-<>> : ∀{A : Set}{tot vs}{ts : List A} → tot ≣ vs <>> ts → tot ≡ vs <>> ts lem-≣-<>> start = refl lem-≣-<>> (bubble x) = lem-≣-<>> x lem-≣-<>>' : ∀{A : Set}{tot vs}{ts : List A} → tot ≡ vs <>> ts → tot ≣ vs <>> ts lem-≣-<>>' {vs = []} refl = start lem-≣-<>>' {vs = vs :< x}{ts} refl = bubble (lem-≣-<>>' refl) done-≣-<>> : ∀{A : Set}{tot : List A} → tot ≣ ([] <>< tot) <>> [] done-≣-<>> = lem-≣-<>>' (sym (lemma<>1 [] _)) no-empty-≣-<>> : ∀{A : Set}{vs}{h : A}{ts} → [] ≣ vs <>> (h ∷ ts) → ⊥ no-empty-≣-<>> (bubble r) = no-empty-≣-<>> r unique-≣-<>> : ∀{A : Set}{tot vs}{ts : List A}(p q : tot ≣ vs <>> ts) → p ≡ q unique-≣-<>> start start = refl unique-≣-<>> (bubble p) (bubble q) with unique-≣-<>> p q ... | refl = refl lemma-≣-<>>-refl : ∀{A}(xs : Bwd A)(ys : List A) → (xs <>> ys) ≣ xs <>> ys lemma-≣-<>>-refl [] ys = start lemma-≣-<>>-refl (xs :< x) ys = bubble (lemma-≣-<>>-refl xs (x ∷ ys))
data IIList {A : Set}{B : A → Set}(C : ∀{a : A}(b : B a) → Set) : ∀{is} → IList B is → Set where [] : IIList C [] _∷_ : ∀{a as}{i : B a}{is : IList B as} → C i → IIList C is → IIList C (i ∷ is) data IIBwd {A : Set}{B : A → Set}(C : ∀{a : A}→ B a → Set) : ∀{is} → IBwd B is → Set where [] : IIBwd C [] _:<_ : ∀{a as}{i : B a}{is : IBwd B as} → IIBwd C is → C i → IIBwd C (is :< i) -- Chip for double indexed lists _<>>II_ : ∀{A : Set}{B : A → Set}{C : ∀{a : A}(b : B a) → Set}{bs : Bwd A}{ts : List A} {ibs : IBwd B bs}{its : IList B ts} → IIBwd C ibs → IIList C its → IIList C (ibs <>>I its) [] <>>II tls = tls (tbs :< x) <>>II tls = tbs <>>II (x ∷ tls) -- Convert an IIBwd into an IIList IIBwd2IIList : ∀{A}{B : A → Set}{C : ∀{a : A}(b : B a) → Set}{bs}{ts : List A} {ibs : IBwd B bs}{its : IList B ts} → (p : bs <>> [] ≡ ts) → (q : subst (IList B) p (ibs <>>I []) ≡ its) → IIBwd C ibs → IIList C its IIBwd2IIList refl refl tbs = tbs <>>II [] -- Split an IIList splitI : ∀{A : Set}{bs}{ts : List A}{B : A → Set}{C : ∀{a : A}(b : B a) → Set} (ibs : IBwd B bs)(its : IList B ts) → IIList C (ibs <>>I its) → IIBwd C ibs × IIList C its splitI [] its xs = [] , xs splitI (ibs :< x) its xs with splitI ibs (x ∷ its) xs ... | ls , (y ∷ rs) = (ls :< y) , rs -- Split an IIBwd bsplitI : ∀{A : Set}{bs}{ts : List A}{B : A → Set}{C : ∀{a : A}(b : B a) → Set} (ibs : IBwd B bs)(its : IList B ts) → IIBwd C (ibs <><I its) → IIBwd C ibs × IIList C its bsplitI ibs [] vs = vs , [] bsplitI ibs (x ∷ its) vs with bsplitI (ibs :< x) its vs ... | ls :< x , rs = ls , (x ∷ rs) -- project from an IIList proj-IIList : ∀{A : Set}{B : A → Set}{C : ∀{a : A}(b : B a) → Set} {a} (b : B a) {Bs}{Fs} (bs : IBwd B Bs) (fs : IList B Fs) → IIList C (bs <>>I (b ∷ fs)) → C b proj-IIList b bs fs xs with splitI bs (b ∷ fs) xs ... | _ , (Cb ∷ _) = Cb -- project from an IIBwd proj-IIBwd : ∀{A : Set}{B : A → Set}{C : ∀{a : A}(b : B a) → Set} {a} (b : B a) {Bs}{Fs} (bs : IBwd B Bs) (fs : IList B Fs) → IIBwd C (bs <><I (b ∷ fs)) → C b proj-IIBwd b bs fs xs with bsplitI bs (b ∷ fs) xs ... | _ , (Cb ∷ _) = Cb
Index for IIList zippers
data _≣I_<>>_ {A : Set}{B : A → Set}{tot}(itot : IList B tot) : ∀{bs ts} → IBwd B bs → IList B ts → (tot ≣ bs <>> ts) → Set where start : (itot ≣I [] <>> itot) start bubble : ∀{bs}{ibs : IBwd B bs}{t}{it : B t}{ts}{ils : IList B ts}{idx} → (itot ≣I ibs <>> (it ∷ ils)) idx ------------------------------------------ → (itot ≣I (ibs :< it) <>> ils) (bubble idx) lem-≣I-<>>1 : ∀{A : Set}{B : A → Set}{tot : List A}{itot : IList B tot}{bs} {ibs : IBwd B bs}{ls}{ils : IList B ls} {idx : tot ≣ bs <>> ls} → (itot ≣I ibs <>> ils) idx → subst (IList B) (lem-≣-<>> idx) itot ≡ (ibs <>>I ils) lem-≣I-<>>1 start = refl lem-≣I-<>>1 (bubble x) = lem-≣I-<>>1 x lem-≣I-<>>1' : ∀{A : Set}{B : A → Set}{tot : List A}{itot : IList B tot}{bs} {ibs : IBwd B bs}{ls}{ils : IList B ls} {idx : tot ≣ bs <>> ls} → (itot ≣I ibs <>> ils) idx → itot ≡ subst (IList B) (sym (lem-≣-<>> idx)) (ibs <>>I ils) lem-≣I-<>>1' start = refl lem-≣I-<>>1' (bubble r) = lem-≣I-<>>1' r lem-≣I-<>>2 : ∀{A : Set}{B : A → Set}{tot : List A}{itot : IList B tot}{bs} {ibs : IBwd B bs}{ls}{ils : IList B ls} (eq : bs <>> ls ≡ tot) → itot ≡ subst (IList B) eq ((ibs <>>I ils)) → (itot ≣I ibs <>> ils) (lem-≣-<>>' (sym eq)) lem-≣I-<>>2 {ibs = []} refl refl = start lem-≣I-<>>2 {ibs = ibs :< x} refl refl = bubble (lem-≣I-<>>2 refl refl) lem-≣I-<>>2' : ∀{A : Set}{B : A → Set}{tot : List A}{itot : IList B tot}{bs} {ibs : IBwd B bs}{ls}{ils : IList B ls} (eq : tot ≡ bs <>> ls) → (subst (IList B) eq itot) ≡ ((ibs <>>I ils)) → (itot ≣I ibs <>> ils) (lem-≣-<>>' eq) lem-≣I-<>>2' {ibs = []} refl refl = start lem-≣I-<>>2' {ibs = ibs :< x} refl refl = bubble (lem-≣I-<>>2' refl refl) done-≣I-<>> : ∀{A : Set}{B : A → Set}{tot : List A}(itot : IList B tot) → (itot ≣I ([] <><I itot) <>> []) done-≣-<>> done-≣I-<>> itot = lem-≣I-<>>2 (lemma<>1 [] _) (sym (lemma<>I1 [] itot)) lemma<>I3 : ∀{A}{B : A → Set}{bs : Bwd A} → (ibs : IBwd B bs)(iys : IList B (bs <>> [])) → ibs <>>I [] ≡ iys → subst (IBwd B) (lemma<>2 bs []) ([] <><I iys) ≡ ibs lemma<>I3 xs ys refl = lemma<>I2 xs [] lem-<><I-subst : ∀{A : Set}{B : A → Set}{tot tot' : List A}{itot : IList B tot} → (p : tot ≡ tot') → ([] <><I subst (IList B) p itot) ≡ subst (IBwd B) (cong ([] <><_) p) ([] <><I itot) lem-<><I-subst refl = refl lemma-<>>I-++I : ∀{A : Set}{B : A → Set}{bs}{as as' : List A} → (ibs : IBwd B bs)(ias : IList B as)(ias' : IList B as') → ibs <>>I (ias ++I ias') ≡ subst (IList B) (sym (lemma-<>>-++ bs as as')) ((ibs <>>I ias) ++I ias') lemma-<>>I-++I [] ias ias' = refl lemma-<>>I-++I (ibs :< x) ias ias' = lemma-<>>I-++I ibs (x ∷ ias) ias'
Cancellation law for <»I
<>>I[]-cancelʳ : ∀{A : Set}{B : A → Set}{bs : Bwd A}(ibs ibs' : IBwd B bs) → ibs <>>I [] ≡ ibs' <>>I [] → ibs ≡ ibs' <>>I[]-cancelʳ ibs ibs' p = trans (sym (lemma<>I3 ibs (ibs' <>>I []) p)) (lemma<>I2 ibs' []) <>>I-cancelˡ : ∀{A : Set}{B : A → Set}{bs : Bwd A}{xs} (ibs : IBwd B bs) → (ixs ixs' : IList B xs) → ibs <>>I ixs ≡ ibs <>>I ixs' → ixs ≡ ixs' <>>I-cancelˡ [] ixs ixs' p = p <>>I-cancelˡ (ibs :< x) ixs ixs' p with <>>I-cancelˡ ibs (x ∷ ixs) (x ∷ ixs') p ... | refl = refl
We may have that Bs <»I (H :: Fs) ≡ Bs’ <»I (H’ :: Fs’). We cannot conclude that Bs ≡ Bs’, H ≡ H’ and Fs ≡ Fs’, because the focus could be at different places of the same indexed list. However, if there is a predicate P such that P holds for every element of Bs and Bs’, but ¬(P H) and ¬(P H’), then this determines where the focus is and we may conclude that Bs ≡ Bs’, H ≡ H’ and Fs ≡ Fs’.
equalbyPredicate++ : ∀{A : Set} (P : A → Set) {bs bs' : List A}{fs fs'} {tot : List A} {h h' : A} → (p : tot ≡ bs ++ (h ∷ fs)) → (p' : tot ≡ bs' ++ (h' ∷ fs')) → (IList P bs) → (IList P bs') → (¬Ph : ¬(P h)) → (¬Ph' : ¬(P h')) → bs ≡ bs' equalbyPredicate++ P p p' [] [] ¬Ph ¬Ph' = refl equalbyPredicate++ P refl refl [] (x ∷ ps') ¬Ph ¬Ph' = ⊥-elim (¬Ph x) equalbyPredicate++ P refl refl (x ∷ ps) [] ¬Ph ¬Ph' = ⊥-elim (¬Ph' x) equalbyPredicate++ P {a ∷ as} refl p' (x ∷ ps) (x₁ ∷ ps') ¬Ph ¬Ph' with ∷-injective p' ... | refl , q = cong (a ∷_) (equalbyPredicate++ P {as} refl q ps ps' ¬Ph ¬Ph') equalbyPredicate : ∀{A : Set} (P : A → Set) {bs bs' : Bwd A}{fs fs'}{tot} {h h' : A} → (p : tot ≡ bs <>> (h ∷ fs)) → (p' : tot ≡ bs' <>> (h' ∷ fs')) → (IBwd P bs) → (IBwd P bs') → (¬Ph : ¬(P h)) → (¬Ph' : ¬(P h')) → bs ≡ bs' equalbyPredicate P {bs} {bs'} {fs} {fs'} {tot} {h} {h'} p p' ps ps' ¬Ph ¬Ph' = <>>[]-cancelʳ _ _ (equalbyPredicate++ P (trans p (lemma-<>>-++ bs [] (h ∷ fs))) (trans p' (lemma-<>>-++ bs' [] (h' ∷ fs'))) (IBwd2IList refl ps) (IBwd2IList refl ps') ¬Ph ¬Ph') equalbyPredicate++I : ∀{A : Set}{B : A → Set}{bs bs' : List A}{fs fs'}{tot} (TOT : IList B tot) {Bs : IList B bs}{Bs' : IList B bs'} {Fs : IList B fs}{Fs' : IList B fs'} {h h' : A} {H : B h}{H' : B h'} → (P : {a : A} → B a → Set) → (p : tot ≡ bs ++ (h ∷ fs)) → (p' : tot ≡ bs' ++ (h' ∷ fs')) → (q : TOT ≡ subst (IList B) (sym p) (Bs ++I (H ∷ Fs))) → (q' : TOT ≡ subst (IList B) (sym p') (Bs' ++I (H' ∷ Fs'))) → (ps : IIList P Bs) → (ps' : IIList P Bs') → (¬PH : ¬(P H)) → (¬PH' : ¬(P H')) → Σ (bs ≡ bs') (λ { refl → Σ (h ≡ h') (λ { refl → Σ (fs ≡ fs') (λ { refl → Bs ≡ Bs' }) }) }) equalbyPredicate++I TOT P p p' q q' [] [] ¬PH ¬PH' with ∷-injective (trans (sym p) p') ... | refl , refl = refl , (refl , (refl , refl)) equalbyPredicate++I TOT P refl refl refl refl [] (x ∷ ps') ¬PH ¬PH' = ⊥-elim (¬PH x) equalbyPredicate++I TOT P refl refl refl refl (x ∷ ps) [] ¬PH ¬PH' = ⊥-elim (¬PH' x) equalbyPredicate++I TOT P refl p' refl q' (x ∷ ps) (x₁ ∷ ps') ¬PH ¬PH' with ∷-injective p' ... | refl , pt with ∷-injectiveI (sym p') q' ... | refl , qt with equalbyPredicate++I _ P refl pt refl (trans qt (≡-subst-removable (IList _) (proj₂ (∷-injective (sym p'))) (sym pt) _)) ps ps' ¬PH ¬PH' ... | refl , refl , refl , refl = refl , (refl , (refl , refl)) equalbyPredicateI : ∀{A : Set}{B : A → Set}{bs bs' : Bwd A}{fs fs'}{tot} (TOT : IList B tot) {Bs : IBwd B bs}{Bs' : IBwd B bs'} {Fs : IList B fs}{Fs' : IList B fs'} {h h' : A} {H : B h}{H' : B h'} → (P : {a : A} → B a → Set) → (p : tot ≡ bs <>> (h ∷ fs)) → (p' : tot ≡ bs' <>> (h' ∷ fs')) → (q : TOT ≡ subst (IList B) (sym p) (Bs <>>I (H ∷ Fs))) → (q' : TOT ≡ subst (IList B) (sym p') (Bs' <>>I (H' ∷ Fs'))) → (ps : IIBwd P Bs) → (ps' : IIBwd P Bs') → (¬PH : ¬(P H)) → (¬PH' : ¬(P H')) → Σ (bs ≡ bs') (λ { refl → Σ (h ≡ h') (λ { refl → Σ (fs ≡ fs') (λ { refl → Bs ≡ Bs' }) }) }) equalbyPredicateI {bs = bs}{bs'}{fs}{fs'}{tot} TOT {Bs} {Bs'} {Fs} {Fs'} {h} {h'} {H} {H'} P refl p' refl q' ps ps' ¬PH ¬PH' with equalbyPredicate++I TOT P (lemma-<>>-++ bs [] (h ∷ fs)) (trans p' (lemma-<>>-++ bs' [] (h' ∷ fs'))) ((lemma-<>>I-++I Bs [] (H ∷ Fs))) (trans q' (trans (cong (subst (IList _) (sym p')) (lemma-<>>I-++I Bs' [] (H' ∷ Fs'))) (trans (subst-subst {P = IList _} (sym (lemma-<>>-++ bs' [] (h' ∷ fs'))) {sym p'} {(Bs' <>>I []) ++I (H' ∷ Fs')}) (≡-subst-removable (IList _) (trans (sym (lemma-<>>-++ bs' [] (h' ∷ fs'))) (sym p')) (sym (trans p' (lemma-<>>-++ bs' [] (h' ∷ fs')))) _)))) (IIBwd2IIList refl refl ps) (IIBwd2IIList refl refl ps') ¬PH ¬PH' ... | pbs , snd with <>>[]-cancelʳ bs bs' pbs equalbyPredicateI TOT {Bs} {Bs'} P p p' q q' ps ps' ¬PH ¬PH' | refl , refl , refl , pBs | refl with <>>I[]-cancelʳ Bs Bs' pBs ... | refl = refl , refl , refl , refl