Type = Set
data Bool : Type where
False True : Bool
if_then_else_ : {A : Type} → Bool → A → A → A
if False then x else y = y
if True then x else y = x
Bool-induction : {P : Bool → Type}
→ P False
→ P True
→ (b : Bool) → P b
Bool-induction x y False = x
Bool-induction x y True = y
data Maybe (A : Type) : Type where
Nothing : Maybe A
Just : A → Maybe A
Maybe-induction : {A : Type} {P : Maybe A → Type}
→ P Nothing
→ ((x : A) → P(Just x))
→ (m : Maybe A) → P m
Maybe-induction p f Nothing = p
Maybe-induction p f (Just x) = f x
data _+_ (A B : Type) : Type where
inl : A → A + B
inr : B → A + B
+-induction : {A B : Type} {P : A + B → Type}
→ ((x : A) → P(inl x))
→ ((y : B) → P(inr y))
→ ((z : A + B) → P z)
+-induction f g (inl x) = f x
+-induction f g (inr y) = g y
data 𝟙 : Type where
₀ : 𝟙
data ∅ : Type where
∅-induction : {A : ∅ → Type} → (e : ∅) → A e
∅-induction ()
∅-elim : {A : Type} → ∅ → A
∅-elim {A} = ∅-induction {λ _ → A}
data List (A : Type) : Type where
[] : List A
_∷_ : A → List A → List A
singleton : {A : Type} → A → List A
singleton x = x ∷ []
_++_ : {A : Type} → List A → List A → List A
[] ++ ys = ys
(x ∷ xs) ++ ys = x ∷ (xs ++ ys)
List-induction : {A : Type} {P : List A → Type}
→ P []
→ ((x : A) (xs : List A) → P xs → P(x ∷ xs))
→ (xs : List A) → P xs
List-induction base step [] = base
List-induction base step (x ∷ xs) = step x xs (List-induction base step xs)
foldr : {A B : Type} → (A → B → B) → B → List A → B
foldr {A} {B} f y = List-induction {A} {P} base step
where
P : List A → Type
P _ = B
base : B
base = y
step : (x : A) (xs : List A) → P xs → P(x ∷ xs)
step x _ y = f x y
data _≡_ {A : Type} : A → A → Type where
refl : (x : A) → x ≡ x
≡-induction : {A : Type} {P : {x y : A} → x ≡ y → Type}
→ ((x : A) → P(refl x))
→ (x y : A) (p : x ≡ y) → P p
≡-induction r x .x (refl .x) = r x
trans : {A : Type} {x y z : A} → x ≡ y → y ≡ z → x ≡ z
trans (refl x) (refl .x) = refl x
sym : {A : Type} {x y : A} → x ≡ y → y ≡ x
sym (refl x) = refl x
ap : {A B : Type} (f : A → B) {x y : A} → x ≡ y → f x ≡ f y
ap f (refl x) = refl (f x)
transport : {A : Type} (P : A → Type) {x y : A} → x ≡ y → P x → P y
transport P (refl x) p = p
foldr-base : {A B : Type} (f : A → B → B) (y : B)
→ foldr f y [] ≡ y
foldr-base f y = refl y
foldr-step : {A B : Type} (f : A → B → B) (y : B) (x : A) (xs : List A)
→ foldr f y (x ∷ xs) ≡ f x (foldr f y xs)
foldr-step f y x xs = refl _
++assoc : {A : Type} (xs ys zs : List A)
→ (xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs)
++assoc [] ys zs = refl (ys ++ zs)
++assoc (x ∷ xs) ys zs = conclusion
where
IH : xs ++ ys ++ zs ≡ xs ++ (ys ++ zs)
IH = ++assoc xs ys zs
conclusion' : x ∷ (xs ++ ys ++ zs) ≡ x ∷ (xs ++ (ys ++ zs))
conclusion' = ap (x ∷_) IH
conclusion : ((x ∷ xs) ++ ys) ++ zs ≡ (x ∷ xs) ++ (ys ++ zs)
conclusion = conclusion'
id : {A : Type} → A → A
id {A} x = x
syntax id {A} x = x ∶ A
have : {A B : Type} → A → B → B
have _ y = y
++assoc' : {A : Type} (xs ys zs : List A)
→ (xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs)
++assoc' [] ys zs = refl (ys ++ zs)
∶ ([] ++ ys) ++ zs ≡ [] ++ (ys ++ zs)
++assoc' (x ∷ xs) ys zs = (have(++assoc' xs ys zs ∶ (xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs)))
ap (x ∷_) (++assoc' xs ys zs)
∶ x ∷ ((xs ++ ys) ++ zs) ≡ x ∷ (xs ++ (ys ++ zs))
∶ ((x ∷ xs) ++ ys) ++ zs ≡ (x ∷ xs) ++ (ys ++ zs)
++assoc'' : {A : Type} (xs ys zs : List A) → (xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs)
++assoc'' [] ys zs = refl _
++assoc'' (x ∷ xs) ys zs = ap (x ∷_) (++assoc'' xs ys zs)
[]-right-neutral : {X : Type} (xs : List X) → xs ++ [] ≡ xs
[]-right-neutral [] = refl []
[]-right-neutral (x ∷ xs) = ap (x ∷_) ([]-right-neutral xs)
rev : {A : Type} → List A → List A
rev [] = []
rev (x ∷ xs) = rev xs ++ (x ∷ [])
rev-++ : {A : Type} (xs ys : List A) → rev (xs ++ ys) ≡ rev ys ++ rev xs
rev-++ [] ys = sym ([]-right-neutral (rev ys))
rev-++ (x ∷ xs) ys = conclusion
where
IH : rev (xs ++ ys) ≡ rev ys ++ rev xs
IH = rev-++ xs ys
a : rev (xs ++ ys) ++ (x ∷ []) ≡ (rev ys ++ rev xs) ++ (x ∷ [])
a = ap (_++ (x ∷ [])) IH
b : (rev ys ++ rev xs) ++ (x ∷ []) ≡ rev ys ++ (rev xs ++ (x ∷ []))
b = ++assoc (rev ys) (rev xs) (x ∷ [])
conclusion : rev (xs ++ ys) ++ (x ∷ []) ≡ rev ys ++ (rev xs ++ (x ∷ []))
conclusion = trans a b
rev-involutive : {A : Type} (xs : List A) → rev (rev xs) ≡ xs
rev-involutive [] = refl (rev (rev []))
rev-involutive (x ∷ xs) = conclusion
where
IH : rev (rev xs) ≡ xs
IH = rev-involutive xs
a : rev (rev (x ∷ xs)) ≡ rev (rev xs ++ (x ∷ []))
a = refl _
b : rev (rev xs ++ (x ∷ [])) ≡ rev (x ∷ []) ++ rev (rev xs)
b = rev-++ (rev xs) (x ∷ [])
c : rev (x ∷ []) ++ rev (rev xs) ≡ rev (x ∷ []) ++ xs
c = ap (rev (x ∷ []) ++_) IH
conclusion : rev (rev (x ∷ xs)) ≡ (x ∷ xs)
conclusion = trans a (trans b c)
rev-append : {A : Type} → List A → List A → List A
rev-append [] ys = ys
rev-append (x ∷ xs) ys = rev-append xs (x ∷ ys)
rev-linear : {A : Type} → List A → List A
rev-linear xs = rev-append xs []
rev-append-spec : {A : Type}
(xs ys : List A)
→ rev-append xs ys ≡ rev xs ++ ys
rev-append-spec [] ys = refl ys
rev-append-spec (x ∷ xs) ys = conclusion
where
IH : rev-append xs (x ∷ ys) ≡ rev xs ++ (x ∷ ys)
IH = rev-append-spec xs (x ∷ ys)
a : rev xs ++ ((x ∷ []) ++ ys) ≡ (rev xs ++ (x ∷ [])) ++ ys
a = sym (++assoc (rev xs) (x ∷ []) ys)
conclusion : rev-append (x ∷ xs) ys ≡ rev (x ∷ xs) ++ ys
conclusion = trans IH a
rev-linear-correct : {A : Type}
(xs : List A)
→ rev-linear xs ≡ rev xs
rev-linear-correct xs = trans (rev-append-spec xs []) ([]-right-neutral (rev xs))
map' : {A B : Type} → (A → B) → List A → List B
map' f [] = []
map' f (x ∷ xs) = f x ∷ map' f xs
map'' : {A B : Type} → (A → B) → List A → List B
map'' f = foldr (λ x ys → f x ∷ ys) []
maps-agreement : {A B : Type}
(f : A → B)
(xs : List A)
→ map' f xs ≡ map'' f xs
maps-agreement f [] = refl []
maps-agreement f (x ∷ xs) = conclusion
where
IH : map' f xs ≡ map'' f xs
IH = maps-agreement f xs
conclusion : f x ∷ map' f xs ≡ f x ∷ map'' f xs
conclusion = ap (f x ∷_) IH
map : {A B : Type} → (A → B) → List A → List B
map = map'
map-id : {A : Type}
(xs : List A)
→ map id xs ≡ xs
map-id [] = refl []
map-id (x ∷ xs) = ap (x ∷_) (map-id xs)
_∘_ : {A B C : Type} → (B → C) → (A → B) → (A → C)
g ∘ f = λ x → g (f x)
map-∘ : {A B C : Type}
(g : B → C)
(f : A → B)
(xs : List A)
→ map (g ∘ f) xs ≡ map g (map f xs)
map-∘ g f [] = refl []
map-∘ g f (x ∷ xs) = conclusion
where
IH : map (g ∘ f) xs ≡ map g (map f xs)
IH = map-∘ g f xs
conclusion : g (f x) ∷ map (g ∘ f) xs ≡ g (f x) ∷ map g (map f xs)
conclusion = ap (g (f x) ∷_) IH
data BT (A : Type) : Type where
Empty : BT A
Fork : A → BT A → BT A → BT A
BT-induction : {A : Type} {P : BT A → Type}
→ P Empty
→ ((x : A) (l r : BT A) → P l → P r → P(Fork x l r))
→ (t : BT A) → P t
BT-induction {A} {P} base step Empty = base ∶ P Empty
BT-induction {A} {P} base step (Fork x l r) = step x l r (BT-induction base step l ∶ P l)
(BT-induction base step r ∶ P r)
∶ P(Fork x l r)
data Direction : Type where
L R : Direction
Address : Type
Address = List Direction
subtree : {A : Type} → Address → BT A → Maybe(BT A)
subtree [] t = Just t
subtree (_ ∷ _) Empty = Nothing
subtree (L ∷ ds) (Fork _ l _) = subtree ds l
subtree (R ∷ ds) (Fork _ _ r) = subtree ds r
isValid : {A : Type} → Address → BT A → Bool
isValid [] _ = True
isValid (_ ∷ _) Empty = False
isValid (L ∷ ds) (Fork _ l _) = isValid ds l
isValid (R ∷ ds) (Fork _ _ r) = isValid ds r
false-premise : {P : Type} → True ≡ False → P
false-premise ()
invalid-gives-Nothing : {A : Type} (ds : Address) (t : BT A)
→ isValid ds t ≡ False → subtree ds t ≡ Nothing
invalid-gives-Nothing {A} [] Empty p
= false-premise(p ∶ isValid {A} [] Empty ≡ False)
invalid-gives-Nothing (d ∷ ds) Empty (refl False)
= refl Nothing
∶ Nothing ≡ Nothing
∶ subtree (d ∷ ds) Empty ≡ Nothing
invalid-gives-Nothing [] (Fork x l r) p
= false-premise(p ∶ isValid [] (Fork x l r) ≡ False)
invalid-gives-Nothing (L ∷ ds) (Fork x l r) p
= invalid-gives-Nothing ds l (p ∶ isValid (L ∷ ds) (Fork x l r) ≡ False)
∶ subtree ds l ≡ Nothing
∶ subtree (L ∷ ds) (Fork x l r) ≡ Nothing
invalid-gives-Nothing (R ∷ ds) (Fork x l r) p
= invalid-gives-Nothing ds r (p ∶ isValid (R ∷ ds) (Fork x l r) ≡ False)
∶ subtree ds r ≡ Nothing
∶ subtree (R ∷ ds) (Fork x l r) ≡ Nothing
invalid-gives-Nothing' : {A : Type} (ds : Address) (t : BT A)
→ isValid ds t ≡ False → subtree ds t ≡ Nothing
invalid-gives-Nothing' [] Empty ()
invalid-gives-Nothing' (d ∷ ds) Empty (refl False) = refl Nothing
invalid-gives-Nothing' [] (Fork x l r) ()
invalid-gives-Nothing' (L ∷ ds) (Fork x l r) p = invalid-gives-Nothing' ds l p
invalid-gives-Nothing' (R ∷ ds) (Fork x l r) p = invalid-gives-Nothing' ds r p
record Σ (A : Type) (B : A → Type) : Type where
constructor
_,_
field
x : A
y : B x
syntax Σ A (λ x → y) = Σ x ꞉ A , y
pr₁ : {A : Type} {B : A → Type} → (Σ x ꞉ A , B x) → A
pr₁ (x , y) = x
pr₂ : {A : Type} {B : A → Type} → ((x , y) : Σ x ꞉ A , B x) → B x
pr₂ (x , y) = y
Σ-induction : {A : Type} {B : A → Type} {P : Σ A B → Type}
→ ((x : A) (y : B x) → P(x , y))
→ (z : Σ A B) → P z
Σ-induction f (x , y) = f x y
pr₁' : {A : Type} {B : A → Type} → Σ A B → A
pr₁' {A} {B} = Σ-induction {A} {B} {λ _ → A} (λ x y → x)
pr₂' : {A : Type} {B : A → Type} → (z : Σ A B) → B(pr₁ z)
pr₂' {A} {B} = Σ-induction {A} {B} {λ z → B (pr₁ z)} (λ x y → y)
_×_ : Type → Type → Type
A × B = Σ x ꞉ A , B
false-premise' : {P : Type} → False ≡ True → P
false-premise' ()
valid-gives-just : {A : Type} (ds : Address) (t : BT A)
→ isValid ds t ≡ True
→ Σ t' ꞉ BT A , (subtree ds t ≡ Just t')
valid-gives-just {A} [] Empty p
= (have(p ∶ isValid {A} [] Empty ≡ True))
(Empty , (refl _ ∶ subtree [] Empty ≡ Just Empty))
valid-gives-just {A} (d ∷ ds) Empty p
= false-premise'(p ∶ isValid {A} (d ∷ ds) Empty ≡ True)
valid-gives-just {A} [] (Fork x l r) p
= Fork x l r , (refl _ ∶ subtree [] (Fork x l r) ≡ Just (Fork x l r))
∶ Σ t' ꞉ BT A , (subtree [] (Fork x l r) ≡ Just t')
valid-gives-just {A} (L ∷ ds) (Fork x l r) p
= valid-gives-just ds l (p ∶ isValid (L ∷ ds) (Fork x l r) ≡ True
∶ isValid ds l ≡ True)
∶ (Σ t' ꞉ BT A , (subtree (L ∷ ds) (Fork x l r) ≡ Just t'))
∶ Σ t' ꞉ BT A , (subtree ds l ≡ Just t')
valid-gives-just {A} (R ∷ ds) (Fork x l r) p
= valid-gives-just ds r (p ∶ isValid (R ∷ ds) (Fork x l r) ≡ True
∶ isValid ds r ≡ True)
∶ (Σ t' ꞉ BT A , (subtree (R ∷ ds) (Fork x l r) ≡ Just t'))
∶ Σ t' ꞉ BT A , (subtree ds r ≡ Just t')
valid-gives-Just' : {A : Type} (ds : Address) (t : BT A)
→ isValid ds t ≡ True → Σ t' ꞉ BT A , (subtree ds t ≡ Just t')
valid-gives-Just' [] Empty p = Empty , (refl _)
valid-gives-Just' (d ∷ ds) Empty ()
valid-gives-Just' [] (Fork x l r) p = Fork x l r , (refl _)
valid-gives-Just' (L ∷ ds) (Fork x l r) p = valid-gives-Just' ds l p
valid-gives-Just' (R ∷ ds) (Fork x l r) p = valid-gives-Just' ds r p
validAddresses : {A : Type} → BT A → List Address
validAddresses Empty = singleton []
validAddresses (Fork _ l r) = (singleton [])
++ (map (L ∷_) (validAddresses l))
++ (map (R ∷_) (validAddresses r))
data _∈_ {A : Type} : A → List A → Type where
inHead : (x : A) (xs : List A) → x ∈ x ∷ xs
inTail : (x y : A) (xs : List A) → y ∈ xs → y ∈ x ∷ xs
mapIsIn : {A B : Type} (f : A → B) {x : A} {xs : List A}
→ x ∈ xs → f x ∈ map f xs
mapIsIn f (inHead x xs) = inHead (f x) (map f xs)
∶ f x ∈ f x ∷ map f xs
∶ f x ∈ map f (x ∷ xs)
mapIsIn f (inTail x y xs i) = (have(i ∶ y ∈ xs))
(have(mapIsIn f i ∶ f y ∈ map f xs))
inTail (f x) (f y) (map f xs) (mapIsIn f i)
∶ f y ∈ f x ∷ map f xs
∶ f y ∈ map f (x ∷ xs)
mapIsIn' : {A B : Type} (f : A → B) {x : A} {xs : List A}
→ x ∈ xs → f x ∈ map f xs
mapIsIn' f (inHead x xs) = inHead (f x) (map f xs)
mapIsIn' f (inTail x y xs i) = inTail (f x) (f y) (map f xs) (mapIsIn' f i)
mapIsIn'' : {A B : Type} (f : A → B) {x : A} {xs : List A}
→ x ∈ xs → f x ∈ map f xs
mapIsIn'' _ (inHead _ _) = inHead _ _
mapIsIn'' _ (inTail _ _ x_ i) = inTail _ _ _ (mapIsIn'' _ i)
equal-heads : {A : Type} {x y : A} {xs ys : List A} → (x ∷ xs) ≡ (y ∷ ys) → x ≡ y
equal-heads {A} {x} {.x} {xs} {.xs} (refl .(x ∷ xs)) = refl x
equal-tails : {A : Type} {x y : A} {xs ys : List A} → (x ∷ xs) ≡ (y ∷ ys) → xs ≡ ys
equal-tails {A} {x} {.x} {xs} {.xs} (refl .(x ∷ xs)) = refl xs
isInjective : {A B : Type} → (A → B) → Type
isInjective f = {x y : _} → f x ≡ f y → x ≡ y
cons-injective : {A : Type} {x : A} → isInjective(x ∷_)
cons-injective {A} {x} = equal-tails {A} {x}
mapIsIn-converse : {A B : Type} {f : A → B} {x : A} {xs : List A}
→ isInjective f → f x ∈ map f xs → x ∈ xs
mapIsIn-converse {A} {B} {f} {x} {xs} inj = g xs (map f xs) (refl _)
where
g : (xs : List A) (ys : List B) → ys ≡ map f xs → f x ∈ ys → x ∈ xs
g [] .(f x ∷ xs) () (inHead .(f x) xs)
g [] .(x' ∷ xs) () (inTail x' .(f x) xs i)
g (x' ∷ xs) .(f x ∷ ys) e (inHead .(f x) ys) = conclusion
where
a : f x ≡ f x'
a = have(e ∶ f x ∷ ys ≡ map f (x' ∷ xs)
∶ f x ∷ ys ≡ f x' ∷ map f xs)
equal-heads e
b : x ≡ x'
b = inj a
c : x ∈ x ∷ xs
c = inHead x xs
conclusion : x ∈ x' ∷ xs
conclusion = transport (λ x' → x ∈ x' ∷ xs) b c
g (x' ∷ xs) .(y ∷ ys) e (inTail y .(f x) ys i) = conclusion
where
et : ys ≡ map f xs
et = have(e ∶ y ∷ ys ≡ map f (x' ∷ xs)
∶ y ∷ ys ≡ f x' ∷ map f xs)
equal-tails e
IH : f x ∈ ys → x ∈ xs
IH i = g xs ys et i
conclusion : x ∈ x' ∷ xs
conclusion = inTail x' x xs (IH i)
¬ : Type → Type
¬ A = A → ∅
not-in-map-if-not-in-image : {A B : Type} {f : A → B} {y : B}
→ ((x : A) → ¬(f x ≡ y)) → (xs : List A) → ¬(y ∈ map f xs)
not-in-map-if-not-in-image {A} {B} {f} {y} ni = g
where
remark : (x : A) → f x ≡ y → ∅
remark = ni
g : (xs : List A) → y ∈ map f xs → ∅
g [] ()
g (x ∷ xs) (inHead .(f x) .(map f xs)) = ni x (refl (f x))
g (x ∷ xs) (inTail .(f x) .y .(map f xs) i) = g xs i
left-if-not-in-image : {A B : Type} {f : A → B} {y : B} (xs : List A) {zs : List B}
→ ((x : A) → ¬(f x ≡ y)) → y ∈ zs ++ map f xs → y ∈ zs
left-if-not-in-image {A} {B} {f} {y} xs {zs} ni = g zs
where
g : (zs : List B) → y ∈ zs ++ map f xs → y ∈ zs
g [] i = (have (i ∶ y ∈ map f xs))
∅-elim (not-in-map-if-not-in-image ni xs i) ∶ y ∈ []
g (z ∷ zs) (inHead .z .(zs ++ map f xs)) = inHead z zs ∶ z ∈ z ∷ zs
g (z ∷ zs) (inTail .z y .(zs ++ map f xs) i) = inTail z y zs (g zs i ∶ y ∈ zs)
right-if-not-in-image : {A B : Type} {f : A → B} {y : B} (xs : List A) {zs : List B}
→ ((x : A) → ¬(f x ≡ y)) → y ∈ map f xs ++ zs → y ∈ zs
right-if-not-in-image {A} {B} {f} {y} xs {zs} ni = g xs
where
g : (xs : List A) → y ∈ map f xs ++ zs → y ∈ zs
g [] i = i
g (x ∷ xs) (inHead .(f x) .(map f xs ++ zs)) = ∅-elim (ni x (refl (f x)))
g (x ∷ xs) (inTail .(f x) y .(map f xs ++ zs) i) = g xs i
inLHS : {A : Type} (x : A) (xs ys : List A) → x ∈ xs → x ∈ xs ++ ys
inLHS {A} x xs ys i = g xs i
where
g : (xs : List A) → x ∈ xs → x ∈ xs ++ ys
g (x ∷ xs) (inHead .x .xs) = inHead x (xs ++ ys)
g (x ∷ xs) (inTail .x y .xs i) = inTail x y (xs ++ ys) (g xs i)
inRHS : {A : Type} (x : A) (xs ys : List A) → x ∈ ys → x ∈ xs ++ ys
inRHS {A} x xs ys i = g xs i
where
g : (xs : List A) → x ∈ ys → x ∈ xs ++ ys
g [] i = i
g (x' ∷ xs) i = inTail x' x (xs ++ ys) (g xs i)
isValid-∈-validAddresses : {A : Type} (ds : Address) (t : BT A)
→ isValid ds t ≡ True → ds ∈ validAddresses t
isValid-∈-validAddresses [] Empty e = inHead [] _ ∶ [] ∈ singleton []
isValid-∈-validAddresses [] (Fork x l r) e = inHead [] _ ∶ [] ∈ validAddresses (Fork x l r)
isValid-∈-validAddresses (L ∷ ds) Empty ()
isValid-∈-validAddresses (L ∷ ds) (Fork x l r) e = inTail [] _ _ lemma
where
IH : ds ∈ validAddresses l
IH = isValid-∈-validAddresses ds l (e ∶ isValid (L ∷ ds) (Fork x l r) ≡ True)
a : L ∷ ds ∈ map (L ∷_) (validAddresses l)
a = mapIsIn (L ∷_) IH
lemma : L ∷ ds ∈ map (L ∷_) (validAddresses l) ++ map (R ∷_) (validAddresses r)
lemma = inLHS (L ∷ ds) (map (L ∷_) (validAddresses l)) (map (R ∷_) (validAddresses r)) a
isValid-∈-validAddresses (R ∷ ds) Empty ()
isValid-∈-validAddresses (R ∷ ds) (Fork x l r) e = inTail [] _ _ lemma
where
IH : ds ∈ validAddresses r
IH = isValid-∈-validAddresses ds r (e ∶ isValid (R ∷ ds) (Fork x l r) ≡ True)
a : R ∷ ds ∈ map (R ∷_) (validAddresses r)
a = mapIsIn (R ∷_) IH
lemma : R ∷ ds ∈ map (L ∷_) (validAddresses l) ++ map (R ∷_) (validAddresses r)
lemma = inRHS (R ∷ ds) (map (L ∷_) (validAddresses l)) (map (R ∷_) (validAddresses r)) a
∈-validAddresses-implies-isValid : {A : Type} (ds : Address) (t : BT A)
→ ds ∈ validAddresses t → isValid ds t ≡ True
∈-validAddresses-implies-isValid {A} [] t i = refl (isValid [] t)
∈-validAddresses-implies-isValid {A} (L ∷ ds) Empty (inTail _ _ _ ())
∈-validAddresses-implies-isValid {A} (L ∷ ds) (Fork x l r) (inTail _ _ _ i) = conclusion
where
IH : ds ∈ validAddresses l → isValid ds l ≡ True
IH = ∈-validAddresses-implies-isValid ds l
remark : L ∷ ds ∈ map (L ∷_) (validAddresses l) ++ map (R ∷_) (validAddresses r)
remark = i
c : (ds : _) (vl : _) (vr : _)
→ L ∷ ds ∈ map (L ∷_) vl ++ map (R ∷_) vr → L ∷ ds ∈ map (L ∷_) vl
c ds vl vr = left-if-not-in-image vr ni
where
ni : (es : _) → ¬((R ∷ es) ≡ (L ∷ ds))
ni es ()
b : (ds : _) (vl : _) (vr : _) → L ∷ ds ∈ map (L ∷_) vl ++ map (R ∷_) vr → ds ∈ vl
b ds vl vr i = mapIsIn-converse cons-injective (c ds vl vr i)
a : ds ∈ validAddresses l
a = b ds (validAddresses l) (validAddresses r) i
conclusion : isValid ds l ≡ True
conclusion = IH a
∈-validAddresses-implies-isValid {A} (R ∷ ds) Empty (inTail _ _ _ ())
∈-validAddresses-implies-isValid {A} (R ∷ ds) (Fork x l r) (inTail _ _ _ i) = conclusion
where
IH : ds ∈ validAddresses r → isValid ds r ≡ True
IH = ∈-validAddresses-implies-isValid ds r
remark : R ∷ ds ∈ map (L ∷_) (validAddresses l) ++ map (R ∷_) (validAddresses r)
remark = i
c : (ds : _) (vl : _) (vr : _)
→ R ∷ ds ∈ map (L ∷_) vl ++ map (R ∷_) vr → R ∷ ds ∈ map (R ∷_) vr
c ds vl vr = right-if-not-in-image vl ni
where
ni : (es : _) → ¬((L ∷ es) ≡ (R ∷ ds))
ni es ()
b : (ds : _) (vl : _) (vr : _) → R ∷ ds ∈ map (L ∷_) vl ++ map (R ∷_) vr → ds ∈ vr
b ds vl vr i = mapIsIn-converse cons-injective (c ds vl vr i)
a : ds ∈ validAddresses r
a = b ds (validAddresses l) (validAddresses r) i
conclusion : isValid ds r ≡ True
conclusion = IH a
_⇔_ : Type → Type → Type
A ⇔ B = (A → B) × (B → A)
main-theorem : {A : Type} (ds : Address) (t : BT A)
→ isValid ds t ≡ True ⇔ ds ∈ validAddresses t
main-theorem ds t = isValid-∈-validAddresses ds t , ∈-validAddresses-implies-isValid ds t
infixl 3 _++_
infix 2 _≡_
infix 2 _∈_
infix 1 _⇔_
infixr 1 _,_
infixl 0 id