Correctness of a grammar for propositional logic - parsing

I am trying to write a grammar for propositional logic for the purpose of creating a LL parser (lexical analysis).
I tried the following grammar:
F = F and F
F = F or F
F = F => F
F = F <=> F
F = not F
F = (F)
D = a
but I discovered that it is ambiguous. I tried the following to remove the ambiguity:
F = F and A
F = A
A = F or B
A = B
B = F => C
B = C
C = F <=> C
C=D
D = not F
D = (F)
D = a
Is this grammar correct? Was I successful in removing the ambiguity?

The grammar is still ambiguous. Here are two derivations for
not a and a:
Derivation 1:
F
F and A
A and A
B and B
C and C
not F and a
not A and a
not B and a
not C and a
not D and a
not a and a
Derivation 2:
F
A
B
C
D
not F
not F and A
not A and A
not B and B
not C and C
not D and D
not a and a
You need to put parentheses around your derivations, e.g.
F = (F and A)
Another possibility if you don't want to use parentheses is to use prefix notation.

Related

Get atoms of a Boolean formula in Z3

I was wondering if there is a method to get the atoms of a Boolean formula:
a = Bool('a')
b = Bool('b')
c = Bool('C')
d = Bool('D')
e = Bool('E')
f = Bool('F')
formula = And(Or(a, b), Or(c, d), Or(e, f))
I wonder if something like this exists:
formula.get_atoms() or get_atoms(formula)
to give me following desired output:
{A, B, C, D, E, F}
In pySMT, get_atoms() exists the provides the atoms. However, for some reason, I need to experiment on Z3.
You can traverse through the hierarchy of children() (documentation):
def atoms(expr):
a = set()
if not str(expr) in {'True', 'False'}:
c = expr.children()
if len(c):
for child in c:
a = a.union(atoms(child))
else:
a = {expr}
return a
a = Bool('a')
b = Bool('b')
c = Bool('C')
d = Bool('D')
e = Bool('E')
f = Bool('F')
formula = And(Or(a, b), Or(c, d), Or(e, f))
print(atoms(formula))

Why cannot define function of type 'Set -> Set' in Agda?

Assume there are four types , D, Q, P, C
data Q : Set where
q1 : Q
q2 : Q
data P : Set where
p1 : P
p2 : P
data C : Set where
c1 : C
c2 : C
data D : Set where
d1 : D
d2 : D
When trying to define function
f : Set -> Set
f D = Q
f P = C
I get the warning unreachable clause .
I assume it is because domains of Agda function are defined on sets but not category of sets.
What if I want a mapping relation which behaves like a close type family in Haskell ?
Because the Agda compiler erases types during compilation, it is not allowed to pattern match on Set directly. (The error 'unreachable clause' is a bit confusing but it results from Agda interpreting D as a pattern variable rather than the datatype.)
The usual way to work around this problem is to define your own universe, i.e. a datatype whose elements are interpreted as specific sets. Here is an example:
data Q : Set where
q1 : Q
q2 : Q
data P : Set where
p1 : P
p2 : P
data C : Set where
c1 : C
c2 : C
data D : Set where
d1 : D
d2 : D
-- Our little universe
data U : Set where
d : U
p : U
-- The interpretation function
⟦_⟧ : U → Set
⟦ d ⟧ = D
⟦ p ⟧ = P
f : U → Set
f d = Q
f p = C
-- An example of how to use f:
omo : {u : U} → ⟦ u ⟧ → f u
omo {d} d1 = q1
omo {d} d2 = q2
omo {p} p1 = c1
omo {p} p2 = c2

Diamond-like interface constraints issue

I've written an implementation of an Applicative and VerifiedApplicative for a pair with a monoid:
import Interfaces.Verified
VerifiedMonoid a => Applicative (Pair a) where
(l, f) <*> (r, x) = (l <+> r, f x)
pure x = (neutral, x)
VerifiedMonoid a => VerifiedApplicative (Pair a) where
applicativeMap (l, x) g = sym $ cong {f=(\y => (y, g x))} (monoidNeutralIsNeutralR l)
applicativeIdentity = ?h1
applicativeComposition = ?h2
applicativeHomomorphism = ?h3
applicativeInterchange = ?h4
Although it compiles, if I weaken a condition on a in Applicative instance as follows:
Monoid a => Applicative (Pair a) where
(l, f) <*> (r, x) = (l <+> r, f x)
pure x = (neutral, x)
I see an error message complaining on applicativeMap:
When checking right hand side of Interfaces.Verified.Contravariant.Pair a implementation of Interfaces.Verified.VerifiedApplicative, method applicativeMap with expected type
map g (l, x) = pure g <*> (l, x)
When checking an application of function Prelude.Basics.cong:
Type mismatch between
(<+>) {{constructor of Interfaces.Verified.VerifiedSemigroup#Semigroup a {{constructor of Interfaces.Verified.VerifiedMonoid#VerifiedSemigroup a}}}}
neutral
l =
l (Type of monoidNeutralIsNeutralR l)
and
(<+>) {{constructor of Prelude.Algebra.Monoid#Semigroup ty {{constructor of Interfaces.Verified.VerifiedMonoid#Monoid a}}}} neutral l = l (Expected type)
Specifically:
Type mismatch between
(<+>) {{constructor of Interfaces.Verified.VerifiedSemigroup#Semigroup a {{constructor of Interfaces.Verified.VerifiedMonoid#VerifiedSemigroup a}}}}
neutral
l
and
(<+>) {{constructor of Prelude.Algebra.Monoid#Semigroup ty {{constructor of Interfaces.Verified.VerifiedMonoid#Monoid a}}}}
neutral
l
Since it's shown Semigroup ty, apparently Semigroup instance is not inferred. I tried to write it explicitly as (Semigroup a, VerifiedMonoid a) => VerifiedApplicative (Pair a), but it doesn't help.
Also it comes in mind a diamond inheritance issue, since Semigroup => Monoid => VerifiedMonoid and in the same time Semigroup => VerifiedSemigroup => VerifiedMonoid.
Any ideas how to workaround this? Limiting Applicative instance only on VerifiedMonoid is a bit awkward.

Why is defining an instance of Choice failing with unknown value?

UPDATE: I'm inlining the code here instead.
I'm trying to define an instance of Data.Profunctor.Choice where right is defined by calling left, but for some reason the compiler complains that left is unknown.
newtype StateTrans s i o = ST (Tuple s i → Tuple s o)
instance stFunctor ∷ Functor (StateTrans s a) where
map f (ST st) = ST $ second f <<< st
instance stProfunctor ∷ Profunctor (StateTrans s) where
dimap f g (ST st) = ST $ second g <<< st <<< second f
instance stChoice ∷ Choice (StateTrans s) where
left (ST f) = ST lf
where
lf (Tuple s (Left a)) = let (Tuple s' b) = f (Tuple s a)
in Tuple s' (Left b)
lf (Tuple s (Right c)) = Tuple s (Right c)
-- Fails to compile with: Unknown value left
right f = arr mirror <<< left f <<< arr mirror
where
mirror Left x = Right x
mirror Right x = Left x
Probably a silly mistake but I've been looking at my code for so long, I can't figure out what's wrong.
(Of minor importance and unrelated: in the Right case for left, I have to unwrap and repackage the value so that it type-aligns. Adding a type ascription fails to compile too.)
Strangely enough, I have no problem doing the same for Strong, see:
instance stStrong ∷ Strong (StateTrans s) where
first (ST f) = ST ff
where
ff (Tuple s (Tuple a c)) = let (Tuple s' b) = f $ Tuple s a
in Tuple s' (Tuple b c)
second f = arr swap <<< first f <<< arr swap
I'm not 100% sure as the pasted snippet doesn't include imports, but I suspect you have an import for Data.Profunctor.Choice (class Choice) rather than Data.Profunctor.Choice (class Choice, left, right).
Importing a class does not import its members implicitly, even though it is possible to define them in an instance without doing so.
First, to use arr you need to declare the Category instance for StateTrans s:
instance stSemigroupoid :: Semigroupoid (StateTrans s) where
compose (ST f1) (ST f2) = ST $ f1 <<< f2
instance stCategory :: Category (StateTrans s) where
id = ST $ \x -> x
For the second step, I needed to add more type annotations (not sure why they're necessary, but this way the build succeeded):
choiceLeft :: forall input output a s. (StateTrans s) input output -> (StateTrans s) (Either input a) (Either output a)
choiceLeft (ST f) = ST lf
where
lf (Tuple s (Left a)) = let (Tuple s' b) = f (Tuple s a)
in Tuple s' (Left b)
lf (Tuple s (Right c)) = Tuple s (Right c)
choiceRight :: forall input output t s. (StateTrans s) input output -> (StateTrans s) (Either t input) (Either t output)
choiceRight f = amirror <<< choiceLeft f <<< amirror
where
mirror :: forall a b. Either a b -> Either b a
mirror (Left x) = Right x
mirror (Right x) = Left x
amirror :: forall a b. StateTrans s (Either b a) (Either a b)
amirror = arr mirror
instance stChoice ∷ Choice (StateTrans s) where
left = choiceLeft
right = choiceRight
Note: used PureScript version 0.11.7 and purescript-profunctor version 3.2.0.

x != y of type Y when checking that the pattern p(y) has type Z

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.

Resources