I have a grammar that looks like this
G = ({A, B, C},{a, c},P, A),
P = {
1. A → BaC,
2. B → aB
3. B → ε,
4. C→c
}
and I want to resolve the FIRST(2.) = {a} FOLLOW(B) = {a} conflict. But with every attempt I fail because I am not able to use the terminal symbol absorption after which the grammar looks like this
G = ({A, B, C, [Ba]},{a, c},P, A),
P = {
1. A → [Ba]C,
2. B → aB
3. B → ε,
4. C → c
5. [Ba] → aBa | a
}
but the problem remains still the same
Related
I was asked to finish one of the recommended question from plfa:
Exercise ⇔≃× (recommended)
Show that A ⇔ B as defined earlier is isomorphic to (A → B) × (B → A).
I know I need to prove some property of equivalence first, and here is my proof:
record _⇔_ (A B : Set) : Set where
field
to : A → B
from : B → A
⇔-refl : ∀ {A : Set} → A ⇔ A
⇔-refl =
record
{ to = λ{x → x}
; from = λ{y → y}
}
⇔-sym : ∀ {A B : Set}
→ A ⇔ B
→ B ⇔ A
⇔-sym A⇔B =
record
{ to = _⇔_.from A⇔B
; from = _⇔_.to A⇔B
}
⇔-trans : ∀ {A B C : Set}
→ A ⇔ B
→ B ⇔ C
→ A ⇔ C
⇔-trans A⇔B B⇔C =
record
{ to = (_⇔_.to B⇔C) ∘ (_⇔_.to A⇔B )
; from = (_⇔_.from A⇔B) ∘ (_⇔_.from B⇔C )
}
And now, from my understanding, I need to prove
⇔≃× : ∀ {A B : Set} → A ⇔ B ≃ (A → B) × (B → A)
So to prove this, we need to prove four sections: "to" "from" "from∘to" "to∘from"
⇔≃× : ∀ {A B : Set} → (A ⇔ B) ≃ ((A → B) × (B → A))
⇔≃× =
record
{ to = λ{ x ⇔ y → ⟨ ( x → y ) , ( y → x ) ⟩ }
; from = ?
; from∘to = ?
; to∘from = ?
}
But when I finish the "to" section, I want to see if it can pass. So I compile and I got this error message:
Cannot eliminate type (A → B) × (B → A) with variable pattern ⇔(did you supply too many arguments?)when checking the clause left hand side.extendedlambda2 x ⇔ y
Can anyone give some explanation on this type of error message?
Thanks in advance
λ{ x ⇔ y → binds three arguments: x, ⇔, and y but the function you're supposed to define only takes one.
I have a function like this:
open import Data.Char
open import Data.Nat
open import Data.Bool
open import Relation.Binary.PropositionalEquality
open Relation.Binary.PropositionalEquality.≡-Reasoning
foo : Char → Char → ℕ
foo c1 c2 with c1 == c2
... | true = 123
... | false = 456
I would like to prove that when I call it with the same argument (foo c c), it always yields 123:
foo-eq⇒123 : ∀ (c : Char) → foo c c ≡ 123
foo-eq⇒123 c =
foo c c ≡⟨ {!!} ⟩
123 ∎
I am able to use refl to prove a trivial example:
foo-example : foo 'a' 'a' ≡ 123
foo-example = refl
So, I would think that I could just put refl in the hole since all Agda needs to do is beta-reduce foo c c. However, replacing the hole with refl yields the following error:
.../Unfold.agda:15,14-18
(foo c c
| Relation.Nullary.Decidable.Core.isYes
(Relation.Nullary.Decidable.Core.map′ Data.Char.Properties.≈⇒≡
Data.Char.Properties.≈-reflexive
(Relation.Nullary.Decidable.Core.map′
(Data.Nat.Properties.≡ᵇ⇒≡ (toℕ c) (toℕ c))
(Data.Nat.Properties.≡⇒≡ᵇ (toℕ c) (toℕ c)) (T? (toℕ c ≡ᵇ toℕ c)))))
!= 123 of type ℕ
when checking that the expression refl has type foo c c ≡ 123
I suspect the issue is that Agda doesn't automatically understand that c == c is true for all c:
c==c : ∀ (c : Char) → (c == c) ≡ true
c==c c = refl
.../Unfold.agda:23,10-14
Relation.Nullary.Decidable.Core.isYes
(Relation.Nullary.Decidable.Core.map′ Data.Char.Properties.≈⇒≡
Data.Char.Properties.≈-reflexive
(Relation.Nullary.Decidable.Core.map′
(Data.Nat.Properties.≡ᵇ⇒≡ (toℕ c) (toℕ c))
(Data.Nat.Properties.≡⇒≡ᵇ (toℕ c) (toℕ c)) (T? (toℕ c ≡ᵇ toℕ c))))
!= true of type Bool
when checking that the expression refl has type (c == c) ≡ true
So, what is the right way to prove my foo-eq⇒123 theorem?
Agda's built-in Char type is a little weird. Let's contrast it with a non-weird built-in type, ℕ. The equality test for ℕ looks as follows.
_≡ᵇ_ : Nat → Nat → Bool
zero ≡ᵇ zero = true
suc n ≡ᵇ suc m = n ≡ᵇ m
_ ≡ᵇ _ = false
Note that n ≡ᵇ n doesn't reduce to true, either. After all, Agda doesn't know whether n is zero or suc, i.e., which of the two clauses to apply for the reduction. So, this has the same problem as your Char example. But for ℕ there is an easy way out.
Let's look at your example again and let's also add a ℕ-based version of foo, bar.
open import Data.Char using (Char ; _==_ ; _≟_)
open import Data.Nat using (ℕ ; zero ; suc ; _≡ᵇ_)
open import Data.Bool using (true ; false)
open import Relation.Binary.PropositionalEquality using (_≡_ ; refl)
open import Relation.Nullary using (yes ; no)
open import Relation.Nullary.Negation using (contradiction)
foo : Char → Char → ℕ
foo c1 c2 with c1 == c2
... | true = 123
... | false = 456
bar : ℕ → ℕ → ℕ
bar n1 n2 with n1 ≡ᵇ n2
... | true = 123
... | false = 456
So, what's the easy way out for ℕ? We pattern match / do a case split on n to reduce n ≡ᵇ n just enough to do our proof. I.e., either to the base case zero or to the next recursive step suc n.
bar-eq⇒123 : ∀ n → bar n n ≡ 123
bar-eq⇒123 zero = refl
bar-eq⇒123 (suc n) = bar-eq⇒123 n
ℕ just has two constructors and we know what ≡ᵇ looks like, so pattern matching is straight forward.
For Char, things are way more complicated. Long story short, the equality test for Char is defined in terms of a function toℕ that Agda doesn't give us a definition for. Also, the Char data type is postulated and doesn't come with any constructors. So a proof like bar-eq⇒123 is not an option for Char. We don't have clauses and we don't have constructors. (I wouldn't call, say, 'a' a constructor for Char. Similarly to how 1234 is not a constructor for ℕ.)
So, what could we do? Note that c == c in the error message that you quoted reduces to something pretty complicated that involves isYes. If we reduced c == c only a tiny little bit (instead of as much as possible), we'd get isYes (c ≟ c) (instead of the complicated thing from the error message).
_≟_ is the decidable equality for Char (i.e., a combination of an "Equal or not?" Boolean and a proof). isYes strips away the proof and gives us the Boolean.
My idea for a proof would then be to not do a case split on c (as we did for ℕ), but on c ≟ c. This would yield two cases and reduce the isYes to true or false, respectively. The true case would be obvious. The false case could be dicharged by contradiction with the proof from the decidable equality.
foo-eq⇒123 : ∀ c → foo c c ≡ 123
foo-eq⇒123 c with c ≟ c
... | yes p = refl
... | no ¬p = contradiction refl ¬p
Note that, in turn, this proof doesn't easily translate to ℕ, as _≡ᵇ_ isn't based on decidable equality and isYes. It's a primitive instead.
Maybe an even better idea would be to consistently stick to decidable equality, for Char as well as ℕ instead of using _==_ or _≡ᵇ_. foo would then look as follows.
baz : Char → Char → ℕ
baz c1 c2 with c1 ≟ c2
... | yes p = 123
... | no ¬p = 456
And the foo-eq⇒123 proof would apply to it unchanged.
Mind the following datatype:
data AB : Set where
A : AB -> AB
B : AB -> AB
C : AB
rwt : AB -> AB
rwt (B (A ab)) = rwt ab
rwt (A ab) = A (rwt ab)
rwt (B ab) = B (rwt ab)
rwt C = C
ab : AB
ab = rwt (rwt (B (B (A (A (A (A (B (B (A (B C)))))))))))
Here, rwt is meant to replace all occurrences of B (A x) by x. The way it is written, though, doesn't guarantee the result is in normal form, which can be seen by the fact we needed two applications of rwt to get to A (A (B (B x))), which can't be further rewritten.
Is there any way to write reduce : AB -> AB in Agda that will return the same result as if we called rewrite repeatedly until no B (A x) is left? And, can we also get a proof of that (perhaps reduce : (input : AB) -> Σ AB (λ output . is-reduction-of input && is-in-nf output)?
An attempt:
The program below will always return the normal form of ab:
reduce : AB -> ℕ -> AB
reduce (A ab) (suc n) = reduce ab n
reduce (A ab) zero = A (reduce ab zero)
reduce (B ab) n = reduce ab (suc n)
reduce C (suc n) = B (reduce C n)
reduce C zero = C
But how do we prove it actually returns a term without "redexes", and that it is equivalent to rwt (rwt (rwt ... ab))? I'm asking because I expect there to be popular techniques to deal with that situation.
You could define rewriting inductively, then say that a normal term is not rewritable to anything. Then, prove that reduce is sound and returns normal forms.
open import Data.Empty
open import Data.Nat
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary
data AB : Set where
A : AB -> AB
B : AB -> AB
C : AB
-- 1-step rewrite
infix 3 _~>_
data _~>_ : AB → AB → Set where
BA : ∀ {x} → B (A x) ~> x
A : ∀ {x y} → x ~> y → A x ~> A y
B : ∀ {x y} → x ~> y → B x ~> B y
-- reflexive-transitive closure
infixr 5 _◅_
data Star {A : Set}(R : A → A → Set) : A → A → Set where
ε : ∀ {x} → Star R x x
_◅_ : ∀ {x y z} → R x y → Star R y z → Star R x z
-- n-step rewrite
infix 3 _~>*_
_~>*_ : AB → AB → Set
_~>*_ = Star _~>_
normal : AB → Set
normal ab = ∀ {ab'} → ¬ (ab ~> ab')
-- TODO
reduceSound : ∀ ab → ab ~>* reduce ab 0
reduceNormal : ∀ ab → normal (reduce ab 0)
You will need to generalize reduceSound and reduceNormal for cases other than 0. Otherwise, both are provable by direct induction, so I don't think it could be made easier by any particular technique.
I'm getting a strange error of the form x != y of type Y when checking that the pattern p(y) has type Z. I do not know why or how I'm getting this and would like to solve the issue. A problem instance follows; thank-you.
Suppose I've a set,
postulate A : Set
and a way to interpret its elements as sets,
postulate F : A → Set
Then using pairs of that set,
record B : Set where field s t : A
I can build a parametrised type on it:
data C : A → Set where MkC : (b : B) → F (B.s b) → C (B.t b)
Now I'd like to, for example, form a function
ABCF : ∀ a → (f : A → A) → C a → C (f a)
ABCF t f e = {!!}
and I'd do so by pattern matching on the third argument via C-c C-c
and doing so gets me
ABCF .(B.t b) f (MkC b x) = {!!}
then another C-c C-c, on b, yields
ABCF t f (MkC record { s = s ; t = .t } x) = ?
but this casing is immediately followed by an error:
B.t b != t of type A
when checking that the pattern MkC record { s = s ; t = .t } x has
type C t
Replacing .t with t' also does not solve this.
Any help indicating the reason behind this error and how to fix it would be greatly appreciated!
Edit
As answered below, the above problem may be due to a bug, but what of the converse case?
FCBA : ∀ {a} (f : A → A) → C (f a) → C a
FCBA {a} f (MkC record { s = s ; t = .(f a) } x) = ?
How would we solve this one? Which comes with the error
B.t b != f a of type A
when checking that the pattern MkC record { s = s ; t = .(f a) } x
has type C (f a)
Looks like a bug. If you swap the inaccessible pattern with the regular one, everything works:
ABCF : ∀ a → (f : A → A) → C a → C (f a)
ABCF .t f (MkC record { s = s ; t = t } x) = {!!}
But that a should anyway be implicit, since it's always inferrable from C a. Then there is no problem:
ABCF : ∀ {a} → (f : A → A) → C a → C (f a)
ABCF f (MkC record { s = s ; t = t } x) = {!!}
If you cannot pattern match directly due to the type being too specific, you can generalize it:
open import Relation.Binary.PropositionalEquality
FCBA : ∀ {a} (f : A → A) → C (f a) → C a
FCBA {a} f c with f a | inspect f a | c
... | .b | [ r ] | MkC record { s = s ; t = b } x = {!!}
Here we generalize f a to b and remember that f a ≡ b (in this case such remembering is not useful probably, but it's needed if you don't want to forget that b is actually f a). This allows to pattern match on c with swapping the inaccessible and the regular patterns like before.
But this is not a trick — it's an ugly hack. You should probably ask on the Agda mailing list why this swapping is required and whether this is the intended behavior.
We can implement a delimited continuation monad in Agda rather easily.
There is, however, no need to, as the Agda "standard library" has an implementation of a delimited continuation monad. What confuses me about this implementation, though, is the addition of an extra parameter to the DCont type.
DCont : ∀ {i f} {I : Set i} → (I → Set f) → IFun I f
DCont K = DContT K Identity
My question is: why is the extra parameter K there? And how would I use the DContIMonadDCont instance? Can I open it in such a way that I'll get something akin to the below reference implementation in (global) scope?
All my attempts to use it are leading to unsolvable metas.
Reference implementation of delimited continuations not using the Agda "standard library".
DCont : Set → Set → Set → Set
DCont r i a = (a → i) → r
return : ∀ {r a} → a → DCont r r a
return x = λ k → k x
_>>=_ : ∀ {r i j a b} → DCont r i a → (a → DCont i j b) → DCont r j b
c >>= f = λ k → c (λ x → f x k)
join : ∀ {r i j a} → DCont r i (DCont i j a) → DCont r j a
join c = c >>= id
shift : ∀ {r o i j a} → ((a → DCont i i o) → DCont r j j) → DCont r o a
shift f = λ k → f (λ x → λ k′ → k′ (k x)) id
reset : ∀ {r i a} → DCont a i i → DCont r r a
reset a = λ k → k (a id)
Let me answer your second and third questions first. Looking at how DContT is defined:
DContT K M r₂ r₁ a = (a → M (K r₁)) → M (K r₂)
We can recover the requested definition by specifying M = id and K = id (M also has to be a monad, but we have the Identity monad). DCont already fixes M to be id, so we are left with K.
import Category.Monad.Continuation as Cont
open import Function
DCont : Set → Set → Set → Set
DCont = Cont.DCont id
Now, we can open the RawIMonadDCont module provided we have an instance of the corresponding record. And luckily, we do: Category.Monad.Continuation has one such record under the name DContIMonadDCont.
module ContM {ℓ} =
Cont.RawIMonadDCont (Cont.DContIMonadDCont {f = ℓ} id)
And that's it. Let's make sure the required operations are really there:
return : ∀ {r a} → a → DCont r r a
return = ContM.return
_>>=_ : ∀ {r i j a b} → DCont r i a → (a → DCont i j b) → DCont r j b
_>>=_ = ContM._>>=_
join : ∀ {r i j a} → DCont r i (DCont i j a) → DCont r j a
join = ContM.join
shift : ∀ {r o i j a} → ((a → DCont i i o) → DCont r j j) → DCont r o a
shift = ContM.shift
reset : ∀ {r i a} → DCont a i i → DCont r r a
reset = ContM.reset
And indeed, this typechecks. You can also check if the implementation matches. For example, using C-c C-n (normalize) on shift, we get:
λ {.r} {.o} {.i} {.j} {.a} e k → e (λ a f → f (k a)) (λ x → x)
Modulo renaming and some implicit parameters, this is exactly implementation of the shift in your question.
Now the first question. The extra parameter is there to allow additional dependency on the indices. I haven't used delimited continuations in this way, so let me reach for an example somewhere else. Consider this indexed writer:
open import Data.Product
IWriter : {I : Set} (K : I → I → Set) (i j : I) → Set → Set
IWriter K i j A = A × K i j
If we have some sort of indexed monoid, we can write a monad instance for IWriter:
record IMonoid {I : Set} (K : I → I → Set) : Set where
field
ε : ∀ {i} → K i i
_∙_ : ∀ {i j k} → K i j → K j k → K i k
module IWriterMonad {I} {K : I → I → Set} (mon : IMonoid K) where
open IMonoid mon
return : ∀ {A} {i : I} →
A → IWriter K i i A
return a = a , ε
_>>=_ : ∀ {A B} {i j k : I} →
IWriter K i j A → (A → IWriter K j k B) → IWriter K i k B
(a , w₁) >>= f with f a
... | (b , w₂) = b , w₁ ∙ w₂
Now, how is this useful? Imagine you wanted to use the writer to produce a message log or something of the same ilk. With usual boring lists, this is not a problem; but if you wanted to use vectors, you are stuck. How to express that type of the log can change? With the indexed version, you could do something like this:
open import Data.Nat
open import Data.Unit
open import Data.Vec
hiding (_>>=_)
open import Function
K : ℕ → ℕ → Set
K i j = Vec ℕ i → Vec ℕ j
K-m : IMonoid K
K-m = record
{ ε = id
; _∙_ = λ f g → g ∘ f
}
open IWriterMonad K-m
tell : ∀ {i j} → Vec ℕ i → IWriter K j (i + j) ⊤
tell v = _ , _++_ v
test : ∀ {i} → IWriter K i (5 + i) ⊤
test =
tell [] >>= λ _ →
tell (4 ∷ 5 ∷ []) >>= λ _ →
tell (1 ∷ 2 ∷ 3 ∷ [])
Well, that was a lot of (ad-hoc) code to make a point. I haven't given it much thought, so I'm fairly sure there's nicer/more principled approach, but it illustrates that such dependency allows your code to be more expressive.
Now, you could apply the same thing to DCont, for example:
test : Cont.DCont (Vec ℕ) 2 3 ℕ
test c = tail (c 2)
If we apply the definitions, the type reduces to (ℕ → Vec ℕ 3) → Vec ℕ 2. Not very convincing example, I know. But perhaps you can some up with something more useful now that you know what this parameter does.