switch examples to PartialVecVec
[~helmut/bidiragda.git] / BFFPlug.agda
1 open import Level using () renaming (zero to ℓ₀)
2 open import Relation.Binary using (DecSetoid)
3
4 module BFFPlug (A : DecSetoid ℓ₀ ℓ₀) where
5
6 open import Data.Nat using (ℕ ; _≟_ ; _+_ ; _∸_ ; zero ; suc ; ⌈_/2⌉)
7 open import Data.Nat.Properties using (m+n∸n≡m)
8 open import Data.Maybe using (Maybe ; just ; nothing)
9 open import Data.Vec using (Vec)
10 open import Data.Product using (∃ ; _,_)
11 open import Relation.Binary using (module DecSetoid)
12 open import Relation.Binary.PropositionalEquality using (refl ; cong ; subst ; sym ; module ≡-Reasoning) renaming (setoid to PropEq)
13 open import Relation.Nullary using (yes ; no)
14 open import Function using (flip ; id ; _∘_)
15 open import Function.Equality using (_⟶_ ; _⟨$⟩_)
16 open import Function.LeftInverse using (_RightInverseOf_)
17
18 open import Generic using (≡-to-Π)
19 import BFF
20 import GetTypes
21 import Examples
22
23 open DecSetoid A using (Carrier)
24 open GetTypes.PartialVecVec public using (Get)
25 open BFF.PartialVecBFF A public
26
27 bffsameshape : (G : Get) → {i : Get.|I| G} → Vec Carrier (Get.|gl₁| G i) → Vec Carrier (Get.|gl₂| G i) → Maybe (Vec Carrier (Get.|gl₁| G i))
28 bffsameshape G {i} = bff G i
29
30 bffplug : (G : Get) → (Get.|I| G → ℕ → Maybe (Get.|I| G)) → {i : Get.|I| G} → {m : ℕ} → Vec Carrier (Get.|gl₁| G i) → Vec Carrier m → Maybe (∃ λ j → Vec Carrier (Get.|gl₁| G j))
31 bffplug G sput {i} {m} s v with sput i m
32 ...                        | nothing = nothing
33 ...                        | just j with Get.|gl₂| G j ≟ m
34 ...                                 | no gl₂j≢m  = nothing
35 bffplug G sput {i}     s v | just j | yes refl with bff G j s v
36 ...                                            | nothing = nothing
37 ...                                            | just s′ = just (j , s′)
38
39 _SimpleRightInvOf_ : (ℕ → ℕ) → (ℕ → ℕ) → Set
40 f SimpleRightInvOf g = ≡-to-Π f RightInverseOf ≡-to-Π g
41
42 bffinv : (G : Get) → (nelteg : PropEq ℕ ⟶ Get.I G) → nelteg RightInverseOf Get.gl₂ G → {i : Get.|I| G} → {m : ℕ} → Vec Carrier (Get.|gl₁| G i) → Vec Carrier m → Maybe (Vec Carrier (Get.|gl₁| G (nelteg ⟨$⟩ m)))
43 bffinv G nelteg inv {m = m} s v = bff G (nelteg ⟨$⟩ m) s (subst (Vec Carrier) (sym (inv m)) v)
44
45 module InvExamples where
46   open Examples using (reverse' ; drop' ; sieve')
47   
48   reverse-put : {n m : ℕ} → Vec Carrier n → Vec Carrier m → Maybe (Vec Carrier m)
49   reverse-put = bffinv reverse' (≡-to-Π id) (λ _ → refl)
50
51   drop-put : (k : ℕ) → {n m : ℕ} → Vec Carrier n → Vec Carrier m → Maybe (Vec Carrier (m + k))
52   drop-put k = bffinv (drop' k) (≡-to-Π (flip _+_ k)) (flip m+n∸n≡m k)
53
54   double : ℕ → ℕ
55   double zero    = zero
56   double (suc n) = suc (suc (double n))
57
58   sieve-inv-len : double SimpleRightInvOf ⌈_/2⌉
59   sieve-inv-len zero          = refl
60   sieve-inv-len (suc zero)    = refl
61   sieve-inv-len (suc (suc x)) = cong (suc ∘ suc) (sieve-inv-len x)
62
63   sieve-put : {n m : ℕ} → Vec Carrier n → Vec Carrier m → Maybe (Vec Carrier (double m))
64   sieve-put = bffinv sieve' (≡-to-Π double) sieve-inv-len