also parameterize Precond
[~helmut/bidiragda.git] / Precond.agda
1 open import Relation.Binary.Core using (Decidable ; _≡_)
2
3 module Precond (Carrier : Set) (deq : Decidable {A = Carrier} _≡_) where
4
5 open import Data.Nat using (ℕ) renaming (zero to nzero ; suc to nsuc)
6 open import Data.Fin using (Fin ; zero ; suc)
7 open import Data.Vec using (Vec ; [] ; _∷_ ; map ; lookup ; toList)
8 open import Data.List.Any using (here ; there)
9 open Data.List.Any.Membership-≡ using (_∉_)
10 open import Data.Maybe using (just)
11 open import Data.Product using (∃ ; _,_)
12 open import Function using (flip ; _∘_)
13 open import Relation.Binary.Core using (_≢_)
14 open import Relation.Binary.PropositionalEquality using (refl ; cong)
15 open Relation.Binary.PropositionalEquality.≡-Reasoning using (begin_ ; _≡⟨_⟩_ ; _∎)
16
17 open import FinMap using (FinMap ; FinMapMaybe ; union ; fromFunc ; empty ; insert)
18 open import CheckInsert using (EqInst ; checkInsert ; lemma-checkInsert-new)
19 open import BFF using (fmap ; _>>=_)
20 import Bidir
21 open Bidir Carrier deq using (lemma-∉-lookupM-assoc)
22
23 open BFF.VecBFF using (get-type ; assoc ; enumerate ; denumerate ; bff)
24
25 assoc-enough : {getlen : ℕ → ℕ} (get : get-type getlen) → {m : ℕ} → (s : Vec Carrier m) → (v : Vec Carrier (getlen m)) → (h : FinMapMaybe m Carrier) → assoc deq (get (enumerate s)) v ≡ just h → ∃ λ u → bff get deq s v ≡ just u
26 assoc-enough get {m} s v h p = map (flip lookup (union h g)) s′ , (begin
27   bff get deq s v
28     ≡⟨ refl ⟩
29   fmap (flip map s′ ∘ flip lookup) (fmap (flip union g) (assoc deq (get s′) v))
30     ≡⟨ cong (fmap (flip map s′ ∘ flip lookup)) (cong (fmap (flip union g)) p) ⟩
31   fmap (flip map s′ ∘ flip lookup) (fmap (flip union g) (just h))
32     ≡⟨ refl ⟩
33   just (map (flip lookup (union h g)) s′) ∎)
34     where s′ : Vec (Fin m) m
35           s′ = enumerate s
36           g : FinMap m Carrier
37           g = fromFunc (denumerate s)
38
39 all-different : {A : Set} {n : ℕ} → Vec A n → Set
40 all-different {_} {n} v = (i : Fin n) → (j : Fin n) → i ≢ j → lookup i v ≢ lookup j v
41
42 suc-injective : {n : ℕ} {i j : Fin n} → (suc i ≡ suc j) → i ≡ j
43 suc-injective refl = refl
44
45 different-swap : {A : Set} {n : ℕ} → (a b : A) → (v : Vec A n) → all-different (a ∷ b ∷ v) → all-different (b ∷ a ∷ v)
46 different-swap a b v p zero          zero          i≢j li≡lj = i≢j refl
47 different-swap a b v p zero          (suc zero)    i≢j li≡lj = p (suc zero) zero (λ ()) li≡lj
48 different-swap a b v p zero          (suc (suc j)) i≢j li≡lj = p (suc zero) (suc (suc j)) (λ ()) li≡lj
49 different-swap a b v p (suc zero)    zero          i≢j li≡lj = p zero (suc zero) (λ ()) li≡lj
50 different-swap a b v p (suc zero)    (suc zero)    i≢j li≡lj = i≢j refl
51 different-swap a b v p (suc zero)    (suc (suc j)) i≢j li≡lj = p zero (suc (suc j)) (λ ()) li≡lj
52 different-swap a b v p (suc (suc i)) zero          i≢j li≡lj = p (suc (suc i)) (suc zero) (λ ()) li≡lj
53 different-swap a b v p (suc (suc i)) (suc zero)    i≢j li≡lj = p (suc (suc i)) zero (λ ()) li≡lj
54 different-swap a b v p (suc (suc i)) (suc (suc j)) i≢j li≡lj = p (suc (suc i)) (suc (suc j)) i≢j li≡lj
55
56 different-drop : {A : Set} {n : ℕ} → (a : A) → (v : Vec A n) → all-different (a ∷ v) → all-different v
57 different-drop a v p i j i≢j = p (suc i) (suc j) (i≢j ∘ suc-injective)
58
59 different-∉ : {A : Set} {n : ℕ} → (x : A) (xs : Vec A n) → all-different (x ∷ xs) → x ∉ (toList xs)
60 different-∉ x [] p ()
61 different-∉ x (y ∷ ys) p (here px) = p zero (suc zero) (λ ()) px
62 different-∉ x (y ∷ ys) p (there pxs) = different-∉ x ys (different-drop y (x ∷ ys) (different-swap x y ys p)) pxs
63
64 different-assoc : {m n : ℕ} → (u : Vec (Fin n) m) → (v : Vec Carrier m) → all-different u → ∃ λ h → assoc deq u v ≡ just h
65 different-assoc []       []       p = empty , refl
66 different-assoc (u ∷ us) (v ∷ vs) p with different-assoc us vs (λ i j i≢j → p (suc i) (suc j) (i≢j ∘ suc-injective))
67 different-assoc (u ∷ us) (v ∷ vs) p | h , p' = insert u v h , (begin
68   assoc deq (u ∷ us) (v ∷ vs)
69     ≡⟨ refl ⟩
70   assoc deq us vs >>= checkInsert deq u v
71     ≡⟨ cong (flip _>>=_ (checkInsert deq u v)) p' ⟩
72   checkInsert deq u v h
73     ≡⟨ lemma-checkInsert-new deq u v h (lemma-∉-lookupM-assoc u us vs h p' (different-∉ u us p)) ⟩
74   just (insert u v h) ∎)