Question
I'm trying to implement a rotate function on Vec, which moves every element n positions to the left, looping around. I could implement that function by using splitAt. Here is a sketch:
open import Data.Nat
open import Data.Nat.DivMod
open import Data.Fin
open import Data.Vec
open import Relation.Nullary.Decidable
open import Relation.Binary.PropositionalEquality
rotateLeft : {A : Set} -> {w : ℕ} -> {w≢0 : False (w ≟ 0)} -> ℕ -> Vec A w -> Vec A w
rotateLeft {A} {w} n vec =
let parts = splitAt (toℕ (n mod w)) {n = ?} vec
in ?
The problem is that splitAt requires two inputs, m and n, such that the size of the vector is m + n. Since the size of the vector here is w, I need to find a k such that k + toℕ (n mod w) = w. I couldn't find any standard function handy for that. What is the best way to proceed?
Some possibilities?
Perhaps it would be helpful if k = n mod w gave me a proof that k < w, that way I could try implementing a function diff : ∀ {k w} -> k < w -> ∃ (λ a : Nat) -> a + k = w. Another possibility would be to just receive a and b as inputs, rather than the bits to shift and size of the vector, but I'm not sure that is the best interface.
Update
I've implemented the following:
add-diff : (a : ℕ) -> (b : Fin (suc a)) -> toℕ b + (a ℕ-ℕ b) ≡ a
add-diff zero zero = refl
add-diff zero (suc ())
add-diff (suc a) zero = refl
add-diff (suc a) (suc b) = cong suc (aaa a b)
Now I just need a proof that ∀ {n m} -> n mod m < m.
Here's what I came up with.
open import Data.Vec
open import Data.Nat
open import Data.Nat.DivMod
open import Data.Fin hiding (_+_)
open import Data.Product
open import Relation.Binary.PropositionalEquality
open import Data.Nat.Properties using (+-comm)
difference : ∀ m (n : Fin m) → ∃ λ o → m ≡ toℕ n + o
difference zero ()
difference (suc m) zero = suc m , refl
difference (suc m) (suc n) with difference m n
difference (suc m) (suc n) | o , p1 = o , cong suc p1
rotate-help : ∀ {A : Set} {m} (n : Fin m) → Vec A m → Vec A m
rotate-help {A} {m = m} n vec with difference m n
... | o , p rewrite p with splitAt (toℕ n) vec
... | xs , ys , _ = subst (Vec A) (+-comm o (toℕ n)) (ys ++ xs)
rotate : ∀ {A : Set} {m} (n : ℕ) → Vec A m → Vec A m
rotate {m = zero} n v = v
rotate {m = suc m} n v = rotate-help (n mod suc m) v
After talking with adamse on IRC, I've came up with this:
open import Data.Fin hiding (_+_)
open import Data.Vec
open import Data.Nat
open import Data.Nat.Properties
open import Data.Nat.DivMod
open import Data.Empty
open import Data.Product
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary.Decidable
diff : {a : ℕ} → {b : Fin a} → ∃ λ c → toℕ b + c ≡ a
diff {zero} {()}
diff {suc a} {zero} = suc a , refl
diff {suc a} {suc b} with diff {a} {b}
... | c , prf = c , cong suc prf
rotateLeft : {A : Set} → {w : ℕ} → {w≢0 : False (w ≟ 0)} → ℕ → Vec A w → Vec A w
rotateLeft {A} {w} {w≢0} n v =
let m = _mod_ n w {w≢0}
d = diff {w} {m}
d₁ = proj₁ d
d₂ = proj₂ d
d₃ = subst (λ x → x ≡ w) (+-comm (toℕ (n mod w)) d₁) d₂
v₁ = subst (λ x → Vec A x) (sym d₂) v
sp = splitAt {A = A} (toℕ m) {n = d₁} v₁
xs = proj₁ (proj₂ sp)
ys = proj₁ sp
in subst (λ x → Vec A x) d₃ (xs ++ ys)
Which is nowhere as elegant as his implementation (partly because I'm still learning Agda's syntax so I opt to just use functions), but works. Now I should return a more refined type, I believe. (Can't thank him enough!)
For your last question to just prove k < w, since k = toℕ (n mod w), you can use bounded from Data.Fin.Properties:
bounded : ∀ {n} (i : Fin n) → toℕ i ℕ< n
I am trying to wrap my head around the Σ type by playing with a filterVec function, analogous to the filter function available for lists. See my implementation below:
-- Some imports we will need later
open import Data.Bool
open import Data.Nat
open import Data.Product
open import Data.Vec
-- The filterVec function
filterVec : {n : ℕ} -> (ℕ -> Bool) -> Vec ℕ n -> Σ ℕ (λ length → Vec ℕ length)
filterVec _ [] = 0 , []
filterVec f (x ∷ xs) with filterVec f xs
... | length , filtered = if f x then (suc length , x ∷ filtered) else (length , filtered)
Happy with my function, I decided to test it
dummyVec : Vec ℕ 5
dummyVec = 1 ∷ 2 ∷ 3 ∷ 4 ∷ 5 ∷ []
dummyFn : Vec ℕ 5
dummyFn with filterVec (λ _ → true) dummyVec
dummyFn | length , xs = {!!} -- I would like to return xs here, but Agda throws a type error
For some reason, Agda is unable to tell that length is 5, so it doesn't allow me to return xs. However, the code below does work:
open import Relation.Binary.PropositionalEquality
dummyProof : proj₁ (filterVec (λ _ → true) dummyVec) ≡ 5
dummyProof = refl
I am utterly confused by this behavior. In the case of dummyFn, Agda cannot tell that the length is 5, but in the case of dummyProof, Agda proves it without any problem.
What am I missing? How can I get dummyFn to work?
with binds a value to a name. If you want to compute, you can use let:
dummyFn′ : Vec ℕ 5
dummyFn′ = let length , xs = filterVec (λ _ → true) dummyVec
in xs
Let's look at the following example:
dummy : Set
dummy with 5
dummy | x = {!!}
Should the x magically reduce to 5 in the hole? No. You've given 5 another name — x, and those expressions are neither judgementally nor propositionally equal.
Now in your example:
dummyFn : Vec ℕ 5
dummyFn with filterVec (λ _ → true) dummyVec
dummyFn | length , xs = {!!}
You've given the length name to the length of xs. And it does not reduce to 5. It's a name. If you want both to give a name and to remember what the name is for, there is the inspect idiom for this:
dummyFn′′ : Vec ℕ 5
dummyFn′′ with filterVec (λ _ → true) dummyVec | inspect (filterVec (λ _ → true)) dummyVec
dummyFn′′ | length , xs | [ refl ] = xs
I have defined Stream of positive rational like this.
one : ℤ
one = + 1
--giving a rational as input it will return next rational (in some down tailing method)
next : pair → pair
next q = if (n eq one) then (mkPair (+ m Data.Integer.+ one) 1)
else (mkPair (n Data.Integer.- one) (m Nat.+ 1))
where
n = getX q
m = getY q
--it will generate all rational from (1,1)
rational : Stream pair
rational = iterate next (mkPair one 1)
--it will get all the rational which are greater than the given rational.
RQ : pair → Stream pair → Stream pair
RQ q (x ∷ xs) = (x add q) ∷ ♯ (RQ q (♭ xs))
--This is a stream of positive rational greater than (0,1).
positiveRat : Stream pair
positiveRat = RQ (mkPair (+ 0) (1)) rational
here pair is a record with two field Z and N.
Now i want to prove that `for all x if x > 0 then x will belong to Stream of positive rational.
open import Data.Stream
open import Data.Nat
open import Data.Rational
open import Data.Integer
open import Coinduction
lemma : (x : pair) → ((+ 0) Data.Integer.≤ (pair.x x)) → ( x ∈ positiveRat )
lemma q proof = ?
An attempt to split proof leads to the following error message:
I'm not sure if there should be a case for the constructor +≤+,
because I get stuck when trying to solve the following unification
problems (inferred index ≟ expected index):
+ m ≟ + 0
+ n ≟ getX q₁
when checking that the expression ? has type q ∈ positiveRat
Please help to resolve this error.
I actually want to prove one theorem but i think if I prove on the other side that is fine also.
I have defined a stream of positive rationals like this:
one : ℤ
one = + 1
next : pair → pair
next q = if (n eq one) then (mkPair (+ m Data.Integer.+ one) 1)
else (mkPair (n Data.Integer.- one) (m Nat.+ 1))
where
n = getX q
m = getY q
-- eq is defined correctly for equivalence of two integer.
rational : Stream pair
rational = iterate next (mkPair one 1)
RQ : pair → Stream pair → Stream pair
RQ q (x ∷ xs) = (x add q) ∷ ♯ (RQ q (♭ xs))
positiveRat : Stream pair
positiveRat = RQ (mkPair (+ 0) (1)) rational
Here pair is a record with ℤ and ℕ fields:
--records of rational number
record pair : Set where
field
x : ℤ
y : ℕ
mkPair : ℤ → ℕ → pair
mkPair a b = record { x = a; y = b}
Now I want to prove that every rational which is in positiveRat will be positive.
open import Data.Stream
open import Data.Nat
open import Data.Rational
open import Data.Integer
open import Coinduction
open import Data.Unit
lemma : (x : pair) → (x ∈ positiveRat) → (+ 0 Data.Integer.≤ pair.x x)
lemma .(record { x = + 1 ; y = 1 }) here = +≤+ z≤n
lemma .(record { x = + 2 ; y = 1 }) (there here) = +≤+ z≤n
lemma .(record { x = + 1 ; y = 2 }) (there (there here)) = {!!}
lemma q (there (there (there pf))) = {!!}
I am writing the proof by splitting on pf. But it is unstoppable.
This is very easy to solve on this mock example because stream is periodic:
lemma : (x : ℚ) → (x ∈ stream) → (+ 0 Data.Integer.≤ ℚ.numerator x)
lemma .(record { numerator = + 1}) here = +≤+ z≤n
lemma .(record { numerator = + 2}) (there here) = +≤+ z≤n
lemma .(record { numerator = + 3}) (there (there here)) = +≤+ z≤n
lemma q (there (there (there pf))) = lemma q pf
However, I imagine in your real example, stream is not periodic. There is no generic answer; the correct proof of lemma depends on how your real stream is defined, so you will have to post that.
I am trying to parse nested lists in Agda. I searched on google and the closest I have found is parsing addressed in Haskell, but usually libraries like "parsec" are used that are not available in Agda.
So I would like to parse "((1,2,3),(4,5,6))" with a result type of (List (List Nat)).
And further nested lists should be supported (up to depth 5), e.g., depth 3 would be (List (List (List Nat))).
My code is very long and cumbersome, and it only works for (List (List Nat)) but not for further nested lists. I didn't make any progress on my own.
If helpful, I would like to reuse splitBy from the first answer of one of my older posts.
NesList : ℕ → Set
NesList 0 = ℕ -- this case is easy
NesList 1 = List ℕ -- this case is easy
NesList 2 = List (List ℕ)
NesList 3 = List (List (List ℕ))
NesList 4 = List (List (List (List ℕ)))
NesList 5 = List (List (List (List (List ℕ)))) -- I am only interested to list depth 5
NesList _ = ℕ -- this is a hack, but I think okay for now
-- My implementation is *not* shown here
--
--
-- (it's about 80 lines long and uses 3 different functions
parseList2 : List Char → Maybe (List (List ℕ))
parseList2 _ = nothing -- dummy result
parseList : (dept : ℕ) → String → Maybe (NesList dept)
parseList 2 s = parseList2 (toList s)
parseList _ _ = nothing
-- Test Cases that are working (in my version)
p1 : parseList 2 "((1,2,3),(4,5,6))" ≡ just ((1 ∷ 2 ∷ 3 ∷ []) ∷ (4 ∷ 5 ∷ 6 ∷ []) ∷ [])
p1 = refl
p2 : parseList 2 "((1,2,3),(4,5,6),(7,8,9,10))" ≡ just ((1 ∷ 2 ∷ 3 ∷ []) ∷ (4 ∷ 5 ∷ 6 ∷ []) ∷ (7 ∷ 8 ∷ 9 ∷ 10 ∷ []) ∷ [])
p2 = refl
p3 : parseList 2 "((1),(2))" ≡ just ((1 ∷ []) ∷ (2 ∷ []) ∷ [])
p3 = refl
p4 : parseList 2 "((1,2))" ≡ just ((1 ∷ 2 ∷ []) ∷ [])
p4 = refl
-- Test Cases that are not working
-- i.e., List (List (List Nat))
lp5 : parseList 3 "(((1,2),(3,4)),((5,6),(7,8)))" ≡ just ( ((1 ∷ 2 ∷ []) ∷ (3 ∷ 4 ∷ []) ∷ []) ∷ ((5 ∷ 6 ∷ []) ∷ (7 ∷ 8 ∷ []) ∷ []) ∷ [])
lp5 = refl
EDIT1 **
Connor's talk at ICFP is online -- the title is "Agda-curious?".
It is from two days ago. Check it out!!
.
See the video:
http://www.youtube.com/watch?v=XGyJ519RY6Y
--
EDIT2:
I found a link that seems to be almost the code I need for my parsing.
There is a tokenize function provided:
https://github.com/fkettelhoit/agda-prelude/blob/master/Examples/PrefixCalculator.agda
--
EDIT3:
I finally found a simple combinator library that should be fast enough. There are no examples included in the library so I still have to look how to solve the problem.
Here is the link:
https://github.com/crypto-agda/agda-nplib/blob/master/lib/Text/Parser.agda
There is more agda-code from Nicolas Pouillard online:
https://github.com/crypto-agda
I don't have access to an agda implementation right now, so I can't check syntax, but this is how I would address it.
First, NesList can be simplified.
NesList 0 = ℕ
NesList (succ n) = List (NesList n)
Then you need a general-purpose list parsing function. Instead of Maybe you could use List to specify alternative parses. The return value is a successful parse and the remainder of the string.
Parser : Set -> Set
Parser a = List Char -> Maybe (Pair a (List Char))
This, given a parser routine for type x, parses a parenthesis-delineated comma-separated list of x.
parseGeneralList : { a : Set } Parser a -> Parser (List a)
parseGeneralList = ...implement me!...
This parses a general NesList.
parseNesList : (a : ℕ) -> Parser (NesList a)
parseNesList 0 = parseNat
parseNesList (succ n) = parseGeneralList (parseNesList n)
Edit: As was pointed out in the comments, code using this kind of Parser won't pass agda's termination checker. I'm thinking that if you want to do parser combinators you need a Stream based setup.
I'm a bit late to the party but I am currently writing a total parser combinators library and I have a fairly compact solution re-using the neat NesList type suggested by #NovaDenizen.
I use difference lists but the basic ones would do too (we'd simply have to replace DList.toList with List.reverse because chainl1 aggregates values left to right).
NList : Set → ℕ → Set
NList A zero = A
NList A (suc n) = List (NList A n)
NList′ : {A : Set} → [ Parser A ] →
(n : ℕ) → [ Parser (NList A n) ]
NList′ A zero = A
NList′ A (suc n) = parens $ return $ DList.toList <$>
chainl1 (DList.[_] <$> NList′ A n)
(return $ DList._++_ <$ char ',')
All the test cases pass successfully. I have added the example to the (monolithic) poc file so you can check for yourself
_ : "((1,2,3),(4,5,6))" ∈ NList′ decimal 2
_ = (1 ∷ 2 ∷ 3 ∷ []) ∷ (4 ∷ 5 ∷ 6 ∷ []) ∷ [] !
_ : "((1,2,3),(4,5,6),(7,8,9,10))" ∈ NList′ decimal 2
_ = (1 ∷ 2 ∷ 3 ∷ []) ∷ (4 ∷ 5 ∷ 6 ∷ []) ∷ (7 ∷ 8 ∷ 9 ∷ 10 ∷ []) ∷ [] !
_ : "((1),(2))" ∈ NList′ decimal 2
_ = (1 ∷ []) ∷ (2 ∷ []) ∷ [] !
_ : "((1,2))" ∈ NList′ decimal 2
_ = (1 ∷ 2 ∷ []) ∷ [] !
_ : "(((1,2),(3,4)),((5,6),(7,8)))" ∈ NList′ decimal 3
_ = ((1 ∷ 2 ∷ []) ∷ (3 ∷ 4 ∷ []) ∷ []) ∷
((5 ∷ 6 ∷ []) ∷ (7 ∷ 8 ∷ []) ∷ []) ∷ [] !
I post here my solution using parser combinators.
It uses the agda-nplib library is on github.
The code is far from optimal but it works.
module NewParser where
-- dummy
open import Data.Maybe
open import Data.Bool
-- includes
open import Data.List hiding (map)
-- ***
-- WAS PRELUDE IMPORTS
open import StringHelpers using (charToℕ; stringToℕ)
open import Data.String hiding (_==_; _++_)
open import Data.Char
open import Function
open import Data.Nat
open import Data.Unit
open import Data.Maybe
-- https://github.com/crypto-agda/agda-nplib/tree/master/lib/Text
open import Text.Parser
open import ParserHelpers
--- ****
--- Lessons Learned, this is the key:
--- (was a basic error that tyeps where too specific, generalisation not possible)
-- parseList : {A : Set} → Parser (Maybe A) → Parser (Maybe A) → ℕ → Parser (List (Maybe A))
-- converted to
-- parseList : {A : Set} → Parser A → Parser A → ℕ → Parser (List A)
-- *****
-- General ... Normal List (depth 1)
parseList : {A : Set} → Parser A → Parser A → ℕ → Parser (List A)
parseList oneMatcher manyMatcher n = ⟪ _++_ · (map toL oneMatcher) · (many n manyMatcher) ⟫
parseBracketList : {A : Set} → Parser A → Parser A → ℕ → Parser (List A)
parseBracketList oneMatcher manyMatcher n = bracket '(' (parseList oneMatcher manyMatcher n) ')'
parseCommaListConvert : {A : Set} → (List Char → A) → (Parser (List Char)) → ℕ → Parser (List A)
parseCommaListConvert convert parser = parseBracketList (⟪ convert · parser ⟫) (⟪ convert · parseOne "," *> parser ⟫)
-- For Numbers
number : Parser (List Char)
number = manyOneOf (toList "1234567890")
parseNumList : ℕ → Parser (List (Maybe ℕ))
parseNumList = parseCommaListConvert charsToℕ number
-- Nested List (depth 2)
--
parseListListNum : ℕ → Parser (List (List (Maybe ℕ)))
parseListListNum n = parseList (parseNumList n) ((parseOne ",") *> (parseNumList n)) n
parseManyLists : ℕ → Parser (List (List (Maybe ℕ)))
parseManyLists n = bracket '(' (parseListListNum n) ')'
-- Run the Parsers
--
open import MaybeEliminatorHelper
-- max number of terms is the number of characters in the string
-- this is for the termination checker
runParseList' : String → Maybe (List (Maybe ℕ))
runParseList' s = runParser (parseNumList (strLength s)) (toList s)
runParseList : String → Maybe (List ℕ)
runParseList = maybe-list-maybe-eliminate ∘ runParseList'
-- nested list
runParseNesList' : String → Maybe (List (List( Maybe ℕ)))
runParseNesList' s = runParser (parseManyLists (length (toList s))) (toList s)
runParseNesList : String → Maybe (List (List ℕ))
runParseNesList = maybe-list-list-maybe-eliminate ∘ runParseNesList'
Here is are my helper functions:
module MaybeEliminatorHelper where
open import Data.Maybe
open import Category.Monad
open import Function
open import Data.List
open import Category.Functor
sequence-maybe : ∀ {a} {A : Set a} → List (Maybe A) → Maybe (List A)
sequence-maybe = sequence Data.Maybe.monad
join : {A : Set} → Maybe (Maybe A) → Maybe A
join m = m >>= id
where
open RawMonad Data.Maybe.monad
maybe-list-elem : {A : Set} → Maybe (List (Maybe A)) → Maybe (List A)
maybe-list-elem mlm = join (sequence-maybe <$> mlm)
where open RawFunctor functor
{-
sequence-maybe : [Maybe a] -> Maybe [a]
join :: Maybe (Maybe a) -> Maybe a
Maybe (List (List (Maybe A))
Maybe.fmap (List.fmap sequenc-maybe)
Maybe (List (Maybe (List A))
Maybe.fmap sequence-maybe
Maybe (Maybe (List (List A)))
join
Maybe (List (List A))
join . Maybe.fmap sequence-maybe . Maybe.fmap (List.fmap sequenc-maybe)
join . Maybe.fmap (sequence-maybe . List.fmap sequenc-maybe)
(short form)
-}
maybe-list-elem2 : {A : Set} → Maybe (List (List (Maybe A))) → Maybe (List (List A))
maybe-list-elem2 = join ∘ Mfmap (sequence-maybe ∘ Lfmap sequence-maybe)
where
open RawMonad Data.Maybe.monad hiding (join) renaming (_<$>_ to Mfmap)
open RawMonad Data.List.monad hiding (join) renaming (_<$>_ to Lfmap)
maybe-list-maybe-eliminate = maybe-list-elem
maybe-list-list-maybe-eliminate = maybe-list-elem2
Further helper functions:
-- ***
-- WAS PRELUDE IMPORTS
open import StringHelpers using (charToℕ; stringToℕ)
open import Data.String hiding (_==_)
open import Data.Char
open import Function
open import Data.Nat
open import Data.Unit
open import Data.Maybe
open import Text.Parser
open import Data.List
-- mini helpers
--
parseOne : String → Parser Char
parseOne = oneOf ∘ toList
strLength : String → ℕ
strLength = length ∘ toList
-- misc helpers
--
charsToℕ : List Char → Maybe ℕ
charsToℕ [] = nothing
charsToℕ xs = stringToℕ (fromList xs)
toL : ∀ {a} {A : Set a} → A → List A
toL x = x ∷ []
-- test
l : List (Maybe ℕ)
l = (just 3) ∷ (just 3) ∷ []
-- Parser Helpers Nicolas
--
isSpace : Char → Bool
isSpace = (_==_ ' ')
spaces : Parser ⊤
spaces = manySat isSpace *> pure _
-- decide if seperator before after brackets is spaces
someSpaces : Parser ⊤
someSpaces = someSat isSpace *> pure _
tok : Char → Parser ⊤
tok c = spaces *> char c *> pure _
bracket : ∀ {A} → Char → Parser A → Char → Parser A
bracket start p stop = tok start *> p <* tok stop
And some test cases:
tn09 : pList "12,13,,14" ≡ nothing
tn09 = refl
tn08 : pList "" ≡ nothing
tn08 = refl
tn07 : pList "12,13,14" ≡ nothing
tn07 = refl
-- not working tn06 : pList "(12,13,14,17)," ≡ nothing
-- not working tn06 = refl
tn05 : pList "aa,bb,cc" ≡ nothing
tn05 = refl
tn04 : pList "11" ≡ nothing
tn04 = refl
tn03 : pList "(11,12,13)" ≡ just (11 ∷ 12 ∷ 13 ∷ [])
tn03 = refl
-- new testcases
tn11 : pList2 "((1,2,3),(4,5,6),(7,8,9))" ≡ just ((1 ∷ 2 ∷ 3 ∷ []) ∷ (4 ∷ 5 ∷ 6 ∷ []) ∷ (7 ∷ 8 ∷ 9 ∷ []) ∷ [])
tn11 = refl
-- old testcases
p1 : pList2 "((1,2,3),(4,5,6))" ≡ just ((1 ∷ 2 ∷ 3 ∷ []) ∷ (4 ∷ 5 ∷ 6 ∷ []) ∷ [])
p1 = refl
p2 : pList2 "((1,2,3),(4,5,6),(7,8,9,10))" ≡ just ((1 ∷ 2 ∷ 3 ∷ []) ∷ (4 ∷ 5 ∷ 6 ∷ []) ∷ (7 ∷ 8 ∷ 9 ∷ 10 ∷ []) ∷ [])
p2 = refl
p3 : pList2 "((1),(2))" ≡ just ((1 ∷ []) ∷ (2 ∷ []) ∷ [])
p3 = refl
p4 : pList2 "((1,2))" ≡ just ((1 ∷ 2 ∷ []) ∷ [])
p4 = refl
I am open for suggestions to improve the code.