Compare commits
6 Commits
eb2d64f3b5
...
dag-lattic
| Author | SHA1 | Date | |
|---|---|---|---|
| 299938d97e | |||
| 927030c337 | |||
| ef3c351bb0 | |||
| 84c4ea6936 | |||
| a277c8f969 | |||
| d1700f23fa |
@@ -2,23 +2,29 @@ module Lattice.Builder where
|
||||
|
||||
open import Lattice
|
||||
open import Equivalence
|
||||
open import Utils using (Unique; fins; fins-complete)
|
||||
open import Utils using (Unique; push; empty; Unique-append; Unique-++⁻ˡ; Unique-++⁻ʳ; Unique-narrow; All¬-¬Any; ¬Any-map; fins; fins-complete; findUniversal; Decidable-¬)
|
||||
open import Data.Nat as Nat using (ℕ)
|
||||
open import Data.Fin as Fin using (Fin; suc; zero; _≟_)
|
||||
open import Data.Maybe as Maybe using (Maybe; just; nothing; _>>=_; maybe)
|
||||
open import Data.Maybe.Properties using (just-injective)
|
||||
open import Data.Unit using (⊤; tt)
|
||||
open import Data.List.NonEmpty using (List⁺; tail; toList) renaming (_∷_ to _∷⁺_)
|
||||
open import Data.List.Membership.Propositional as MemProp using () renaming (_∈_ to _∈ˡ_; mapWith∈ to mapWith∈ˡ)
|
||||
open import Data.List.Membership.Propositional as MemProp using (lose) renaming (_∈_ to _∈ˡ_; mapWith∈ to mapWith∈ˡ)
|
||||
open import Data.List.Membership.Propositional.Properties using () renaming (∈-++⁺ʳ to ∈ˡ-++⁺ʳ; ∈-++⁺ˡ to ∈ˡ-++⁺ˡ; ∈-cartesianProductWith⁺ to ∈ˡ-cartesianProductWith⁺)
|
||||
open import Data.List.Relation.Unary.Any using (Any; here; there)
|
||||
open import Data.List.Relation.Unary.All using (All; []; _∷_; map; lookup)
|
||||
open import Data.List.Relation.Unary.Any using (Any; here; there; any?; satisfied)
|
||||
open import Data.List.Relation.Unary.Any.Properties using (¬Any[])
|
||||
open import Data.List.Relation.Unary.All using (All; []; _∷_; map; lookup; zipWith; tabulate; all?)
|
||||
open import Data.List.Relation.Unary.All.Properties using () renaming (++⁺ to ++ˡ⁺; ++⁻ʳ to ++ˡ⁻ʳ)
|
||||
open import Data.List using (List; _∷_; []; cartesianProduct; cartesianProductWith; foldr) renaming (_++_ to _++ˡ_)
|
||||
open import Data.List.Properties using () renaming (++-conicalʳ to ++ˡ-conicalʳ; ++-identityʳ to ++ˡ-identityʳ; ++-assoc to ++ˡ-assoc)
|
||||
open import Data.Sum using (_⊎_; inj₁; inj₂)
|
||||
open import Data.Product using (Σ; _,_; _×_; proj₁; proj₂)
|
||||
open import Data.Product using (Σ; _,_; _×_; proj₁; proj₂; uncurry)
|
||||
open import Data.Empty using (⊥; ⊥-elim)
|
||||
open import Relation.Nullary using (¬_; Dec; yes; no)
|
||||
open import Relation.Nullary using (¬_; Dec; yes; no; ¬?)
|
||||
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl; sym; trans; cong; subst)
|
||||
open import Relation.Binary.PropositionalEquality.Properties using (decSetoid)
|
||||
open import Relation.Binary using () renaming (Decidable to Decidable²)
|
||||
open import Relation.Unary using (Decidable)
|
||||
open import Agda.Primitive using (lsuc; Level) renaming (_⊔_ to _⊔ℓ_)
|
||||
|
||||
record Graph : Set where
|
||||
@@ -43,21 +49,199 @@ record Graph : Set where
|
||||
done : ∀ {n : Node} → Path n n
|
||||
step : ∀ {n₁ n₂ n₃ : Node} → (n₁ , n₂) ∈ˡ edges → Path n₂ n₃ → Path n₁ n₃
|
||||
|
||||
data IsDone : ∀ {n₁ n₂} → Path n₁ n₂ → Set where
|
||||
isDone : ∀ {n : Node} → IsDone (done {n})
|
||||
|
||||
IsDone? : ∀ {n₁ n₂} → Decidable (IsDone {n₁} {n₂})
|
||||
IsDone? done = yes isDone
|
||||
IsDone? (step _ _) = no (λ {()})
|
||||
|
||||
_++_ : ∀ {n₁ n₂ n₃} → Path n₁ n₂ → Path n₂ n₃ → Path n₁ n₃
|
||||
done ++ p = p
|
||||
(step e p₁) ++ p₂ = step e (p₁ ++ p₂)
|
||||
|
||||
++-done : ∀ {n₁ n₂} (p : Path n₁ n₂) → p ++ done ≡ p
|
||||
++-done done = refl
|
||||
++-done (step e∈edges p) rewrite ++-done p = refl
|
||||
|
||||
++-assoc : ∀ {n₁ n₂ n₃ n₄} (p₁ : Path n₁ n₂) (p₂ : Path n₂ n₃) (p₃ : Path n₃ n₄) →
|
||||
(p₁ ++ p₂) ++ p₃ ≡ p₁ ++ (p₂ ++ p₃)
|
||||
++-assoc done p₂ p₃ = refl
|
||||
++-assoc (step n₁,n∈edges p₁) p₂ p₃ rewrite ++-assoc p₁ p₂ p₃ = refl
|
||||
|
||||
IsDone-++ˡ : ∀ {n₁ n₂ n₃} (p₁ : Path n₁ n₂) (p₂ : Path n₂ n₃) →
|
||||
¬ IsDone p₁ → ¬ IsDone (p₁ ++ p₂)
|
||||
IsDone-++ˡ done _ done≢done = ⊥-elim (done≢done isDone)
|
||||
|
||||
interior : ∀ {n₁ n₂} → Path n₁ n₂ → List Node
|
||||
interior done = []
|
||||
interior (step _ done) = []
|
||||
interior (step {n₂ = n₂} _ p) = n₂ ∷ interior p
|
||||
|
||||
interior-extend : ∀ {n₁ n₂ n₃} → (p : Path n₁ n₂) → (n₂,n₃∈edges : (n₂ , n₃) ∈ˡ edges) →
|
||||
let p' = (p ++ (step n₂,n₃∈edges done))
|
||||
in (interior p' ≡ interior p) ⊎ (interior p' ≡ interior p ++ˡ (n₂ ∷ []))
|
||||
interior-extend done _ = inj₁ refl
|
||||
interior-extend (step n₁,n₂∈edges done) n₂n₃∈edges = inj₂ refl
|
||||
interior-extend {n₂ = n₂} (step {n₂ = n} n₁,n∈edges p@(step _ _)) n₂n₃∈edges
|
||||
with p ++ (step n₂n₃∈edges done) | interior-extend p n₂n₃∈edges
|
||||
... | done | inj₁ []≡intp rewrite sym []≡intp = inj₁ refl
|
||||
... | done | inj₂ []=intp++[n₂] with () ← ++ˡ-conicalʳ (interior p) (n₂ ∷ []) (sym []=intp++[n₂])
|
||||
... | step _ p | inj₁ IH rewrite IH = inj₁ refl
|
||||
... | step _ p | inj₂ IH rewrite IH = inj₂ refl
|
||||
|
||||
interior-++ : ∀ {n₁ n₂ n₃} → (p₁ : Path n₁ n₂) → (p₂ : Path n₂ n₃) →
|
||||
¬ IsDone p₁ → ¬ IsDone p₂ →
|
||||
interior (p₁ ++ p₂) ≡ interior p₁ ++ˡ (n₂ ∷ interior p₂)
|
||||
interior-++ done _ done≢done _ = ⊥-elim (done≢done isDone)
|
||||
interior-++ _ done _ done≢done = ⊥-elim (done≢done isDone)
|
||||
interior-++ (step _ done) (step _ _) _ _ = refl
|
||||
interior-++ (step n₁,n∈edges p@(step n,n'∈edges p')) p₂ _ p₂≢done
|
||||
rewrite interior-++ p p₂ (λ {()}) p₂≢done = refl
|
||||
|
||||
SimpleWalkVia : List Node → Node → Node → Set
|
||||
SimpleWalkVia ns n₁ n₂ = Σ (Path n₁ n₂) (λ p → Unique (interior p) × All (λ n → n ∈ˡ ns) (interior p))
|
||||
SimpleWalkVia ns n₁ n₂ = Σ (Path n₁ n₂) (λ p → Unique (interior p) × All (_∈ˡ ns) (interior p))
|
||||
|
||||
postulate SplitSimpleWalkVia : ∀ {n n₁ n₂ ns} (w : SimpleWalkVia (n ∷ ns) n₁ n₂) → (Σ (SimpleWalkVia ns n₁ n × SimpleWalkVia ns n n₂) λ (w₁ , w₂) → proj₁ w₁ ++ proj₁ w₂ ≡ proj₁ w) ⊎ (Σ (SimpleWalkVia ns n₁ n₂) λ w' → proj₁ w' ≡ proj₁ w)
|
||||
SimpleWalk-extend : ∀ {n₁ n₂ n₃ ns} → (w : SimpleWalkVia ns n₁ n₂) → (n₂ , n₃) ∈ˡ edges → All (λ nʷ → ¬ nʷ ≡ n₂) (interior (proj₁ w)) → n₂ ∈ˡ ns → SimpleWalkVia ns n₁ n₃
|
||||
SimpleWalk-extend (p , (Unique-intp , intp⊆ns)) n₂,n₃∈edges w≢n₂ n₂∈ns
|
||||
with p ++ (step n₂,n₃∈edges done) | interior-extend p n₂,n₃∈edges
|
||||
... | p' | inj₁ intp'≡intp rewrite sym intp'≡intp = (p' , Unique-intp , intp⊆ns)
|
||||
... | p' | inj₂ intp'≡intp++[n₂]
|
||||
with intp++[n₂]⊆ns ← ++ˡ⁺ intp⊆ns (n₂∈ns ∷ [])
|
||||
rewrite sym intp'≡intp++[n₂] = (p' , (subst Unique (sym intp'≡intp++[n₂]) (Unique-append (¬Any-map sym (All¬-¬Any w≢n₂)) Unique-intp) , intp++[n₂]⊆ns))
|
||||
|
||||
postulate findCycle : ∀ {n₁ n₂} (p : Path n₁ n₂) → (Σ (SimpleWalkVia (proj₁ nodes) n₁ n₂) λ w → proj₁ w ≡ p) ⊎ (Σ Node (λ n → Σ (SimpleWalkVia (proj₁ nodes) n n) λ w → ¬ proj₁ w ≡ done))
|
||||
∈ˡ-narrow : ∀ {x y : Node} {ys : List Node} → x ∈ˡ (y ∷ ys) → ¬ y ≡ x → x ∈ˡ ys
|
||||
∈ˡ-narrow (here refl) x≢y = ⊥-elim (x≢y refl)
|
||||
∈ˡ-narrow (there x∈ys) _ = x∈ys
|
||||
|
||||
SplitSimpleWalkViaHelp : ∀ {n n₁ n₂ ns} (nⁱ : Node)
|
||||
(w : SimpleWalkVia (n ∷ ns) n₁ n₂)
|
||||
(p₁ : Path n₁ nⁱ) (p₂ : Path nⁱ n₂) →
|
||||
¬ IsDone p₁ → ¬ IsDone p₂ →
|
||||
All (_∈ˡ ns) (interior p₁) →
|
||||
proj₁ w ≡ p₁ ++ p₂ →
|
||||
(Σ (SimpleWalkVia ns n₁ n × SimpleWalkVia ns n n₂) λ (w₁ , w₂) → proj₁ w₁ ++ proj₁ w₂ ≡ proj₁ w) ⊎ (Σ (SimpleWalkVia ns n₁ n₂) λ w' → proj₁ w' ≡ proj₁ w)
|
||||
SplitSimpleWalkViaHelp nⁱ w done _ done≢done _ _ _ = ⊥-elim (done≢done isDone)
|
||||
SplitSimpleWalkViaHelp nⁱ w p₁ done _ done≢done _ _ = ⊥-elim (done≢done isDone)
|
||||
SplitSimpleWalkViaHelp {n} {ns = ns} nⁱ w@(p , (Unique-intp , intp⊆ns)) p₁@(step _ _) p₂@(step {n₂ = nⁱ'} nⁱ,nⁱ',∈edges p₂') p₁≢done p₂≢done intp₁⊆ns p≡p₁++p₂
|
||||
with intp≡intp₁++[n]++intp₂ ← trans (cong interior p≡p₁++p₂) (interior-++ p₁ p₂ p₁≢done p₂≢done)
|
||||
with nⁱ∈n∷ns ∷ intp₂⊆n∷ns ← ++ˡ⁻ʳ (interior p₁) (subst (All (_∈ˡ (n ∷ ns))) intp≡intp₁++[n]++intp₂ intp⊆ns)
|
||||
with nⁱ ≟ n
|
||||
... | yes refl
|
||||
with Unique-intp₁ ← Unique-++⁻ˡ (interior p₁) (subst Unique intp≡intp₁++[n]++intp₂ Unique-intp)
|
||||
with (push n≢intp₂ Unique-intp₂) ← Unique-++⁻ʳ (interior p₁) (subst Unique intp≡intp₁++[n]++intp₂ Unique-intp)
|
||||
= inj₁ (((p₁ , (Unique-intp₁ , intp₁⊆ns)) , (p₂ , (Unique-intp₂ , zipWith (uncurry ∈ˡ-narrow) (intp₂⊆n∷ns , n≢intp₂)))) , sym p≡p₁++p₂)
|
||||
... | no nⁱ≢n
|
||||
with p₂'
|
||||
... | done
|
||||
= let
|
||||
-- note: copied with below branch. can't use with <- to
|
||||
-- share and re-use because the termination checker loses the thread.
|
||||
p₁' = (p₁ ++ (step nⁱ,nⁱ',∈edges done))
|
||||
n≢nⁱ n≡nⁱ = nⁱ≢n (sym n≡nⁱ)
|
||||
intp₁'=intp₁++[nⁱ] = subst (λ xs → interior p₁' ≡ interior p₁ ++ˡ xs) (++ˡ-identityʳ (nⁱ ∷ [])) (interior-++ p₁ (step nⁱ,nⁱ',∈edges done) p₁≢done (λ {()}))
|
||||
intp₁++[nⁱ]⊆ns = ++ˡ⁺ intp₁⊆ns (∈ˡ-narrow nⁱ∈n∷ns n≢nⁱ ∷ [])
|
||||
intp₁'⊆ns = subst (All (_∈ˡ ns)) (sym intp₁'=intp₁++[nⁱ]) intp₁++[nⁱ]⊆ns
|
||||
-- end shared with below branch.
|
||||
Unique-intp₁++[nⁱ] = Unique-++⁻ˡ (interior p₁ ++ˡ (nⁱ ∷ [])) (subst Unique (trans intp≡intp₁++[n]++intp₂ (sym (++ˡ-assoc (interior p₁) (nⁱ ∷ []) []))) Unique-intp)
|
||||
in inj₂ ((p₁ ++ (step nⁱ,nⁱ',∈edges done) , (subst Unique (sym intp₁'=intp₁++[nⁱ]) Unique-intp₁++[nⁱ] , intp₁'⊆ns)) , sym p≡p₁++p₂)
|
||||
... | p₂'@(step _ _)
|
||||
= let p₁' = (p₁ ++ (step nⁱ,nⁱ',∈edges done))
|
||||
n≢nⁱ n≡nⁱ = nⁱ≢n (sym n≡nⁱ)
|
||||
intp₁'=intp₁++[nⁱ] = subst (λ xs → interior p₁' ≡ interior p₁ ++ˡ xs) (++ˡ-identityʳ (nⁱ ∷ [])) (interior-++ p₁ (step nⁱ,nⁱ',∈edges done) p₁≢done (λ {()}))
|
||||
intp₁++[nⁱ]⊆ns = ++ˡ⁺ intp₁⊆ns (∈ˡ-narrow nⁱ∈n∷ns n≢nⁱ ∷ [])
|
||||
intp₁'⊆ns = subst (All (_∈ˡ ns)) (sym intp₁'=intp₁++[nⁱ]) intp₁++[nⁱ]⊆ns
|
||||
p≡p₁'++p₂' = trans p≡p₁++p₂ (sym (++-assoc p₁ (step nⁱ,nⁱ',∈edges done) p₂'))
|
||||
in SplitSimpleWalkViaHelp nⁱ' w p₁' p₂' (IsDone-++ˡ _ _ p₁≢done) (λ {()}) intp₁'⊆ns p≡p₁'++p₂'
|
||||
|
||||
SplitSimpleWalkVia : ∀ {n n₁ n₂ ns} (w : SimpleWalkVia (n ∷ ns) n₁ n₂) → (Σ (SimpleWalkVia ns n₁ n × SimpleWalkVia ns n n₂) λ (w₁ , w₂) → proj₁ w₁ ++ proj₁ w₂ ≡ proj₁ w) ⊎ (Σ (SimpleWalkVia ns n₁ n₂) λ w' → proj₁ w' ≡ proj₁ w)
|
||||
SplitSimpleWalkVia (done , (_ , _)) = inj₂ ((done , (empty , [])) , refl)
|
||||
SplitSimpleWalkVia (step n₁,n₂∈edges done , (_ , _)) = inj₂ ((step n₁,n₂∈edges done , (empty , [])) , refl)
|
||||
SplitSimpleWalkVia w@(step {n₂ = nⁱ} n₁,nⁱ∈edges p@(step _ _) , (push nⁱ≢intp Unique-intp , nⁱ∈ns ∷ intp⊆ns)) = SplitSimpleWalkViaHelp nⁱ w (step n₁,nⁱ∈edges done) p (λ {()}) (λ {()}) [] refl
|
||||
|
||||
open import Data.List.Membership.DecSetoid (decSetoid {A = Node} _≟_) using () renaming (_∈?_ to _∈ˡ?_)
|
||||
|
||||
splitFromInteriorʳ : ∀ {n₁ n₂ n} (p : Path n₁ n₂) → n ∈ˡ (interior p) →
|
||||
Σ (Path n n₂) (λ p' → ¬ IsDone p' × (Σ (List Node) λ ns → interior p ≡ ns ++ˡ n ∷ interior p'))
|
||||
splitFromInteriorʳ done ()
|
||||
splitFromInteriorʳ (step _ done) ()
|
||||
splitFromInteriorʳ (step {n₂ = n'} n₁,n'∈edges p'@(step _ _)) (here refl) = (p' , ((λ {()}) , ([] , refl)))
|
||||
splitFromInteriorʳ (step {n₂ = n'} n₁,n'∈edges p'@(step _ _)) (there n∈intp')
|
||||
with (p'' , (¬IsDone-p'' , (ns , intp'≡ns++intp''))) ← splitFromInteriorʳ p' n∈intp'
|
||||
rewrite intp'≡ns++intp'' = (p'' , (¬IsDone-p'' , (n' ∷ ns , refl)))
|
||||
|
||||
splitFromInteriorˡ : ∀ {n₁ n₂ n} (p : Path n₁ n₂) → n ∈ˡ (interior p) →
|
||||
Σ (Path n₁ n) (λ p' → ¬ IsDone p' × (Σ (List Node) λ ns → interior p ≡ interior p' ++ˡ ns))
|
||||
splitFromInteriorˡ done ()
|
||||
splitFromInteriorˡ (step _ done) ()
|
||||
splitFromInteriorˡ p@(step {n₂ = n'} n₁,n'∈edges p'@(step _ _)) (here refl) = (step n₁,n'∈edges done , ((λ {()}) , (interior p , refl)))
|
||||
splitFromInteriorˡ p@(step {n₂ = n'} n₁,n'∈edges p'@(step _ _)) (there n∈intp')
|
||||
with splitFromInteriorˡ p' n∈intp'
|
||||
... | (p''@(step _ _) , (¬IsDone-p'' , (ns , intp'≡intp''++ns)))
|
||||
rewrite intp'≡intp''++ns
|
||||
= (step n₁,n'∈edges p'' , ((λ { () }) , (ns , refl)))
|
||||
... | (done , (¬IsDone-Done , _)) = ⊥-elim (¬IsDone-Done isDone)
|
||||
|
||||
findCycleHelp : ∀ {n₁ nⁱ n₂} (p : Path n₁ n₂) (p₁ : Path n₁ nⁱ) (p₂ : Path nⁱ n₂) →
|
||||
¬ IsDone p₁ → Unique (interior p₁) →
|
||||
p ≡ p₁ ++ p₂ →
|
||||
(Σ (SimpleWalkVia (proj₁ nodes) n₁ n₂) λ w → proj₁ w ≡ p) ⊎ (Σ Node (λ n → Σ (SimpleWalkVia (proj₁ nodes) n n) λ w → ¬ IsDone (proj₁ w)))
|
||||
findCycleHelp p p₁ done ¬IsDonep₁ Unique-intp₁ p≡p₁++done rewrite ++-done p₁ = inj₁ ((p₁ , (Unique-intp₁ , tabulate (λ {x} _ → nodes-complete x))) , sym p≡p₁++done)
|
||||
findCycleHelp {nⁱ = nⁱ} p p₁ (step nⁱ,nⁱ'∈edges p₂') ¬IsDone-p₁ Unique-intp₁ p≡p₁++p₂
|
||||
with nⁱ ∈ˡ? interior p₁
|
||||
... | no nⁱ∉intp₁ =
|
||||
let p₁' = p₁ ++ step nⁱ,nⁱ'∈edges done
|
||||
intp₁'≡intp₁++[nⁱ] = subst (λ xs → interior p₁' ≡ interior p₁ ++ˡ xs) (++ˡ-identityʳ (nⁱ ∷ [])) (interior-++ p₁ (step nⁱ,nⁱ'∈edges done) ¬IsDone-p₁ (λ {()}))
|
||||
¬IsDone-p₁' = IsDone-++ˡ p₁ (step nⁱ,nⁱ'∈edges done) ¬IsDone-p₁
|
||||
p≡p₁'++p₂' = trans p≡p₁++p₂ (sym (++-assoc p₁ (step nⁱ,nⁱ'∈edges done) p₂'))
|
||||
Unique-intp₁' = subst Unique (sym intp₁'≡intp₁++[nⁱ]) (Unique-append nⁱ∉intp₁ Unique-intp₁)
|
||||
in findCycleHelp p p₁' p₂' ¬IsDone-p₁' Unique-intp₁' p≡p₁'++p₂'
|
||||
... | yes nⁱ∈intp₁
|
||||
with (pᶜ , (¬IsDone-pᶜ , (ns , intp₁≡ns++intpᶜ))) ← splitFromInteriorʳ p₁ nⁱ∈intp₁
|
||||
rewrite sym (++ˡ-assoc ns (nⁱ ∷ []) (interior pᶜ)) =
|
||||
let Unique-intp₁' = subst Unique intp₁≡ns++intpᶜ Unique-intp₁
|
||||
in inj₂ (nⁱ , ((pᶜ , (Unique-++⁻ʳ (ns ++ˡ nⁱ ∷ []) Unique-intp₁' , tabulate (λ {x} _ → nodes-complete x))) , ¬IsDone-pᶜ))
|
||||
|
||||
findCycle : ∀ {n₁ n₂} (p : Path n₁ n₂) → (Σ (SimpleWalkVia (proj₁ nodes) n₁ n₂) λ w → proj₁ w ≡ p) ⊎ (Σ Node (λ n → Σ (SimpleWalkVia (proj₁ nodes) n n) λ w → ¬ IsDone (proj₁ w)))
|
||||
findCycle done = inj₁ ((done , (empty , [])) , refl)
|
||||
findCycle (step n₁,n₂∈edges done) = inj₁ ((step n₁,n₂∈edges done , (empty , [])) , refl)
|
||||
findCycle p@(step {n₂ = n'} n₁,n'∈edges p'@(step _ _)) = findCycleHelp p (step n₁,n'∈edges done) p' (λ {()}) empty refl
|
||||
|
||||
toSimpleWalk : ∀ {n₁ n₂} (p : Path n₁ n₂) → SimpleWalkVia (proj₁ nodes) n₁ n₂
|
||||
toSimpleWalk done = (done , (empty , []))
|
||||
toSimpleWalk (step {n₂ = nⁱ} n₁,nⁱ∈edges p')
|
||||
with toSimpleWalk p'
|
||||
... | (done , _) = (step n₁,nⁱ∈edges done , (empty , []))
|
||||
... | (p''@(step _ _) , (Unique-intp'' , intp''⊆nodes))
|
||||
with nⁱ ∈ˡ? interior p''
|
||||
... | no nⁱ∉intp'' = (step n₁,nⁱ∈edges p'' , (push (tabulate (λ { n∈intp'' refl → nⁱ∉intp'' n∈intp'' })) Unique-intp'' , (nodes-complete nⁱ) ∷ intp''⊆nodes))
|
||||
... | yes nⁱ∈intp''
|
||||
with splitFromInteriorʳ p'' nⁱ∈intp''
|
||||
... | (done , (¬IsDone=p''ʳ , (ns , intp''≡ns++intp''ʳ))) = ⊥-elim (¬IsDone=p''ʳ isDone)
|
||||
... | (p''ʳ@(step _ _) , (¬IsDone=p''ʳ , (ns , intp''≡ns++intp''ʳ))) =
|
||||
-- no rewrites because then I can't reason about the return value of toSimpleWalk
|
||||
-- rewrite intp''≡ns++intp''ʳ
|
||||
-- rewrite sym (++ˡ-assoc ns (nⁱ ∷ []) (interior p''ʳ)) =
|
||||
let reassoc-intp''≡ns++intp''ʳ = subst (interior p'' ≡_) (sym (++ˡ-assoc ns (nⁱ ∷ []) (interior p''ʳ))) intp''≡ns++intp''ʳ
|
||||
intp''ʳ⊆nodes = ++ˡ⁻ʳ (ns ++ˡ nⁱ ∷ []) (subst (All (_∈ˡ (proj₁ nodes))) reassoc-intp''≡ns++intp''ʳ intp''⊆nodes)
|
||||
Unique-ns++intp''ʳ = subst Unique reassoc-intp''≡ns++intp''ʳ Unique-intp''
|
||||
nⁱ∈p''ˡ = ∈ˡ-++⁺ʳ ns {ys = nⁱ ∷ []} (here refl)
|
||||
in (step n₁,nⁱ∈edges p''ʳ , (Unique-narrow (ns ++ˡ nⁱ ∷ []) Unique-ns++intp''ʳ nⁱ∈p''ˡ , nodes-complete nⁱ ∷ intp''ʳ⊆nodes ))
|
||||
|
||||
toSimpleWalk-IsDone⁻ : ∀ {n₁ n₂} (p : Path n₁ n₂) →
|
||||
¬ IsDone p → ¬ IsDone (proj₁ (toSimpleWalk p))
|
||||
toSimpleWalk-IsDone⁻ done ¬IsDone-p _ = ¬IsDone-p isDone
|
||||
toSimpleWalk-IsDone⁻ (step {n₂ = nⁱ} n₁,nⁱ∈edges p') _ isDone-w
|
||||
with toSimpleWalk p'
|
||||
... | (done , _) with () ← isDone-w
|
||||
... | (p''@(step _ _) , (Unique-intp'' , intp''⊆nodes))
|
||||
with nⁱ ∈ˡ? interior p''
|
||||
... | no nⁱ∉intp'' with () ← isDone-w
|
||||
... | yes nⁱ∈intp''
|
||||
with splitFromInteriorʳ p'' nⁱ∈intp''
|
||||
... | (done , (¬IsDone=p''ʳ , (ns , intp''≡ns++intp''ʳ))) = ¬IsDone=p''ʳ isDone
|
||||
... | (p''ʳ@(step _ _) , (¬IsDone=p''ʳ , (ns , intp''≡ns++intp''ʳ)))
|
||||
with () ← isDone-w
|
||||
|
||||
Adjacency : Set
|
||||
Adjacency = ∀ (n₁ n₂ : Node) → List (Path n₁ n₂)
|
||||
@@ -144,11 +328,54 @@ record Graph : Set where
|
||||
adj : Adjacency
|
||||
adj = throughAll (proj₁ nodes)
|
||||
|
||||
PathExists : Node → Node → Set
|
||||
PathExists n₁ n₂ = Path n₁ n₂
|
||||
|
||||
PathExists? : Decidable² PathExists
|
||||
PathExists? n₁ n₂
|
||||
with allSimplePathsNoted ← paths-throughAll {n₁ = n₁} {n₂ = n₂} (proj₁ nodes)
|
||||
with adj n₁ n₂
|
||||
... | [] = no (λ p → let w = toSimpleWalk p in ¬Any[] (allSimplePathsNoted w))
|
||||
... | (p ∷ ps) = yes p
|
||||
|
||||
NoCycles : Set
|
||||
NoCycles = ∀ (n : Node) → All (_≡ done) (adj n n)
|
||||
NoCycles = ∀ {n} (p : Path n n) → IsDone p
|
||||
|
||||
NoCycles? : Dec NoCycles
|
||||
NoCycles? with any? (λ n → any? (Decidable-¬ IsDone?) (adj n n)) (proj₁ nodes)
|
||||
... | yes existsCycle =
|
||||
no (λ ∀p,IsDonep → let (n , n,n-cycle) = satisfied existsCycle in
|
||||
let (p , ¬IsDone-p) = satisfied n,n-cycle in
|
||||
¬IsDone-p (∀p,IsDonep p))
|
||||
... | no noCycles =
|
||||
yes (λ { done → isDone
|
||||
; p@(step {n₁ = n} _ _) →
|
||||
let w = toSimpleWalk p in
|
||||
let ¬IsDone-w = toSimpleWalk-IsDone⁻ p (λ {()}) in
|
||||
let w∈adj = paths-throughAll (proj₁ nodes) w in
|
||||
⊥-elim (noCycles (lose (nodes-complete n) (lose w∈adj ¬IsDone-w)))
|
||||
})
|
||||
|
||||
NoCycles⇒adj-complete : NoCycles → ∀ {n₁ n₂} {p : Path n₁ n₂} → p ∈ˡ adj n₁ n₂
|
||||
NoCycles⇒adj-complete noCycles {n₁} {n₂} {p}
|
||||
with findCycle p
|
||||
... | inj₁ (w , w≡p) rewrite sym w≡p = paths-throughAll (proj₁ nodes) w
|
||||
... | inj₂ (nᶜ , (wᶜ , wᶜ≢done)) = ⊥-elim (wᶜ≢done (lookup (noCycles nᶜ) (paths-throughAll (proj₁ nodes) wᶜ)))
|
||||
... | inj₂ (nᶜ , (wᶜ , wᶜ≢done)) = ⊥-elim (wᶜ≢done (noCycles (proj₁ wᶜ)))
|
||||
|
||||
Is-⊤ : Node → Set
|
||||
Is-⊤ n = All (PathExists n) (proj₁ nodes)
|
||||
|
||||
Is-⊥ : Node → Set
|
||||
Is-⊥ n = All (λ n' → PathExists n' n) (proj₁ nodes)
|
||||
|
||||
Has-⊤ : Set
|
||||
Has-⊤ = Any Is-⊤ (proj₁ nodes)
|
||||
|
||||
Has-T? : Dec Has-⊤
|
||||
Has-T? = findUniversal (proj₁ nodes) PathExists?
|
||||
|
||||
Has-⊥ : Set
|
||||
Has-⊥ = Any Is-⊥ (proj₁ nodes)
|
||||
|
||||
Has-⊥? : Dec Has-⊥
|
||||
Has-⊥? = findUniversal (proj₁ nodes) (λ n₁ n₂ → PathExists? n₂ n₁)
|
||||
|
||||
51
Utils.agda
51
Utils.agda
@@ -6,16 +6,26 @@ open import Data.Nat using (ℕ; suc)
|
||||
open import Data.Fin as Fin using (Fin; suc; zero)
|
||||
open import Data.Fin.Properties using (suc-injective)
|
||||
open import Data.List using (List; cartesianProduct; []; _∷_; _++_; foldr; filter) renaming (map to mapˡ)
|
||||
open import Data.List.Membership.Propositional using (_∈_)
|
||||
open import Data.List.Membership.Propositional using (_∈_; lose)
|
||||
open import Data.List.Membership.Propositional.Properties as ListMemProp using ()
|
||||
open import Data.List.Relation.Unary.All using (All; []; _∷_; map)
|
||||
open import Data.List.Relation.Unary.Any using (Any; here; there) -- TODO: re-export these with nicer names from map
|
||||
open import Data.List.Relation.Unary.All using (All; []; _∷_; map; all?; lookup)
|
||||
open import Data.List.Relation.Unary.All.Properties using (++⁻ˡ; ++⁻ʳ)
|
||||
open import Data.List.Relation.Unary.Any as Any using (Any; here; there; any?) -- TODO: re-export these with nicer names from map
|
||||
open import Data.Sum using (_⊎_)
|
||||
open import Function.Definitions using (Injective)
|
||||
open import Relation.Binary using (Antisymmetric) renaming (Decidable to Decidable²)
|
||||
open import Relation.Binary.PropositionalEquality using (_≡_; sym; refl; cong)
|
||||
open import Relation.Nullary using (¬_; yes; no)
|
||||
open import Relation.Nullary using (¬_; yes; no; Dec)
|
||||
open import Relation.Nullary.Decidable using (¬?)
|
||||
open import Relation.Unary using (Decidable)
|
||||
|
||||
All¬-¬Any : ∀ {p c} {C : Set c} {P : C → Set p} {l : List C} → All (λ x → ¬ P x) l → ¬ Any P l
|
||||
All¬-¬Any {l = x ∷ xs} (¬Px ∷ _) (here Px) = ¬Px Px
|
||||
All¬-¬Any {l = x ∷ xs} (_ ∷ ¬Pxs) (there Pxs) = All¬-¬Any ¬Pxs Pxs
|
||||
|
||||
Decidable-¬ : ∀ {p c} {C : Set c} {P : C → Set p} → Decidable P → Decidable (λ x → ¬ P x)
|
||||
Decidable-¬ Decidable-P x = ¬? (Decidable-P x)
|
||||
|
||||
data Unique {c} {C : Set c} : List C → Set c where
|
||||
empty : Unique []
|
||||
push : ∀ {x : C} {xs : List C}
|
||||
@@ -36,6 +46,24 @@ Unique-append {c} {C} {x} {x' ∷ xs'} x∉xs (push x'≢ uxs') =
|
||||
help {[]} _ = x'≢x ∷ []
|
||||
help {e ∷ es} (x'≢e ∷ x'≢es) = x'≢e ∷ help x'≢es
|
||||
|
||||
Unique-++⁻ˡ : ∀ {c} {C : Set c} (xs : List C) {ys : List C} → Unique (xs ++ ys) → Unique xs
|
||||
Unique-++⁻ˡ [] Unique-ys = empty
|
||||
Unique-++⁻ˡ (x ∷ xs) {ys} (push x≢xs++ys Unique-xs++ys) = push (++⁻ˡ xs {ys = ys} x≢xs++ys) (Unique-++⁻ˡ xs Unique-xs++ys)
|
||||
|
||||
Unique-++⁻ʳ : ∀ {c} {C : Set c} (xs : List C) {ys : List C} → Unique (xs ++ ys) → Unique ys
|
||||
Unique-++⁻ʳ [] Unique-ys = Unique-ys
|
||||
Unique-++⁻ʳ (x ∷ xs) {ys} (push x≢xs++ys Unique-xs++ys) = Unique-++⁻ʳ xs Unique-xs++ys
|
||||
|
||||
Unique-∈-++ˡ : ∀ {c} {C : Set c} {x : C} (xs : List C) {ys : List C} → Unique (xs ++ ys) → x ∈ xs → ¬ x ∈ ys
|
||||
Unique-∈-++ˡ [] _ ()
|
||||
Unique-∈-++ˡ {x = x} (x' ∷ xs) (push x≢xs++ys _) (here refl) = All¬-¬Any (++⁻ʳ xs x≢xs++ys)
|
||||
Unique-∈-++ˡ {x = x} (x' ∷ xs) (push _ Unique-xs++ys) (there x̷∈xs) = Unique-∈-++ˡ xs Unique-xs++ys x̷∈xs
|
||||
|
||||
Unique-narrow : ∀ {c} {C : Set c} {x : C} (xs : List C) {ys : List C} → Unique (xs ++ ys) → x ∈ xs → Unique (x ∷ ys)
|
||||
Unique-narrow [] _ ()
|
||||
Unique-narrow {x = x} (x' ∷ xs) (push x≢xs++ys Unique-xs++ys) (here refl) = push (++⁻ʳ xs x≢xs++ys) (Unique-++⁻ʳ xs Unique-xs++ys)
|
||||
Unique-narrow {x = x} (x' ∷ xs) (push _ Unique-xs++ys) (there x̷∈xs) = Unique-narrow xs Unique-xs++ys x̷∈xs
|
||||
|
||||
All-≢-map : ∀ {c d} {C : Set c} {D : Set d} (x : C) {xs : List C} (f : C → D) →
|
||||
Injective (_≡_ {_} {C}) (_≡_ {_} {D}) f →
|
||||
All (λ x' → ¬ x ≡ x') xs → All (λ y' → ¬ (f x) ≡ y') (mapˡ f xs)
|
||||
@@ -48,9 +76,8 @@ Unique-map : ∀ {c d} {C : Set c} {D : Set d} {l : List C} (f : C → D) →
|
||||
Unique-map {l = []} _ _ _ = empty
|
||||
Unique-map {l = x ∷ xs} f f-Injecitve (push x≢xs uxs) = push (All-≢-map x f f-Injecitve x≢xs) (Unique-map f f-Injecitve uxs)
|
||||
|
||||
All¬-¬Any : ∀ {p c} {C : Set c} {P : C → Set p} {l : List C} → All (λ x → ¬ P x) l → ¬ Any P l
|
||||
All¬-¬Any {l = x ∷ xs} (¬Px ∷ _) (here Px) = ¬Px Px
|
||||
All¬-¬Any {l = x ∷ xs} (_ ∷ ¬Pxs) (there Pxs) = All¬-¬Any ¬Pxs Pxs
|
||||
¬Any-map : ∀ {p₁ p₂ c} {C : Set c} {P₁ : C → Set p₁} {P₂ : C → Set p₂} {l : List C} → (∀ {x} → P₁ x → P₂ x) → ¬ Any P₂ l → ¬ Any P₁ l
|
||||
¬Any-map f ¬Any-P₂ Any-P₁ = ¬Any-P₂ (Any.map f Any-P₁)
|
||||
|
||||
All-single : ∀ {p c} {C : Set c} {P : C → Set p} {c : C} {l : List C} → All P l → c ∈ l → P c
|
||||
All-single {c = c} {l = x ∷ xs} (p ∷ ps) (here refl) = p
|
||||
@@ -129,3 +156,13 @@ fins (suc n') =
|
||||
fins-complete : ∀ (n : ℕ) (f : Fin n) → f ∈ (proj₁ (fins n))
|
||||
fins-complete (suc n') zero = here refl
|
||||
fins-complete (suc n') (suc f') = there (x∈xs⇒fx∈fxs suc (fins-complete n' f'))
|
||||
|
||||
findUniversal : ∀ {p c} {C : Set c} {R : C → C → Set p} (l : List C) → Decidable² R →
|
||||
Dec (Any (λ x → All (R x) l) l)
|
||||
findUniversal l Rdec = any? (λ x → all? (Rdec x) l) l
|
||||
|
||||
findUniversal-unique : ∀ {p c} {C : Set c} (R : C → C → Set p) (l : List C) →
|
||||
Antisymmetric _≡_ R →
|
||||
∀ x₁ x₂ → x₁ ∈ l → x₂ ∈ l → All (R x₁) l → All (R x₂) l →
|
||||
x₁ ≡ x₂
|
||||
findUniversal-unique R l Rantisym x₁ x₂ x₁∈l x₂∈l Allx₁ Allx₂ = Rantisym (lookup Allx₁ x₂∈l) (lookup Allx₂ x₁∈l)
|
||||
|
||||
Reference in New Issue
Block a user