I want to specify a production in ANTLR where the order of its sub-productions does not matter. Note that I want each of the sub-productions to occur once. The brute force way to accomplish this would look something like this:
grammar Foo;
r : (A B) | (B A) ;
A : 'a' ;
B : 'b' ;
As more sub-productions are added, the number of permutations increases... n!/(n-k)!
grammar Foo2;
r : (A B C) | (A C B) | (B A C) | (B C A) | (C A B) | (C B A) ;
A : 'a' ;
B : 'b' ;
C : 'c' ;
Obviously the above solution is not practical. Is there a construct in ANTLR which describes permutations like this in a more concise way?
No, there is no way to describe a permutation in a production in ANTLR. You will need to match A, B or C three times and then use a listener to check if all three tokens have been matched exactly one time.
You could do it inside your grammar using custom code and a predicate, but that would make your grammar very hard to read: best do this with a listener.
Related
I am new to Coq, and was hoping that someone with more experience could help me with a problem I am facing.
I have defined a relation to represent the evaluation of a program in an imaginary programming language. The goal of the language is unify function calls and a constrained subset of macro invocations under a single semantics. Here is the definition of the relation, with its first constructor (I am omitting the rest to save space and avoid unnecessary details).
Inductive EvalExpr:
store -> (* Store, mapping L-values to R-values *)
environment -> (* Local environment, mapping function-local variables names to L-values *)
environment -> (* Global environment, mapping global variables names to L-values *)
function_table ->(* Mapping function names to function definitions *)
macro_table -> (* Mapping macro names to macro definitions *)
expr -> (* The expression to evaluate *)
Z -> (* The value the expression terminates to *)
store -> (* The final state of the program store after evaluation *)
Prop :=
(* Numerals evaluate to their integer representation and do not
change the store *)
| E_Num : forall S E G F M z,
EvalExpr S E G F M (Num z) z S
...
The mappings are defined as follows:
Module Import NatMap := FMapList.Make(OrderedTypeEx.Nat_as_OT).
Module Import StringMap := FMapList.Make(OrderedTypeEx.String_as_OT).
Definition store : Type := NatMap.t Z.
Definition environment : Type := StringMap.t nat.
Definition function_table : Type := StringMap.t function_definition.
Definition macro_table : Type := StringMap.t macro_definition.
I do not think the definitions of the other types are relevant to this question, but I can add them if needed.
Now when trying to prove the following lemma, which seems intuitively obvious, I get stuck:
Lemma S_Equal_EvalExpr_EvalExpr : forall S1 S2,
NatMap.Equal S1 S2 ->
forall E G F M e v S',
EvalExpr S1 E G F M e v S' <-> EvalExpr S2 E G F M e v S'.
Proof.
intros. split.
(* -> *)
- intros. induction H0.
+ (* Num *)
Fail constructor.
Abort.
If I were able to rewrite S2 for S1 in the goal, the proof would be trivial; however, if I try to do this, I get the following error:
H : NatMap.Equal S S2
(* Other premises *)
---------------------
EvalExpr S2 E G F M (Num z) z S
rewrite <- H.
Found no subterm matching "NatMap.find (elt:=Z) ?M2433 S2" in the current goal.
I think this has to do with finite mappings being abstract types, and thus not being rewritable like concrete types are. However, I noticed that I can rewrite mappings within other equations/relations found in Coq.FSets.FMapFacts. How would I tell Coq to let me rewrite mapping types inside my EvalExpr relation?
Update: Here is a gist containing a minimal working example of my problem. The definitions of some of the mapping types have been altered for brevity, but the problem is the same.
The issue here is that the relation NatMap.Equal, which says that two maps have the same bindings, is not the same as the notion of equality in Coq's logic, =. While it is always possible to rewrite with =, rewriting with some other relation R is only possible if you can prove that the property you are trying to show is compatible with it. This is already done for the relations in FMap, which is why rewriting there works.
You have two options:
Replace FMap with an implementation for which the intended map equality coincides with =, a property usually known as extensionality. There are many libraries that provide such data structures, including my own extructures, but also finmap and std++. Then, you never need to worry about a custom equality relation; all the important properties of maps work with =.
Keep FMap, but use the generalized rewriting mechanism to allow rewriting with FMap.Equal. To do this, you probably need to modify the definition of your execution relation so that it is compatible with FMap.Equal. Unfortunately, I believe the only way to do this is by explicitly adding equality hypotheses everywhere, e.g.
Definition EvalExpr' S E G F M e v S' :=
exists S0 S0', NatMap.Equal S S0 /\
NatMap.Equal S' S0' /\
EvalExpr S0 E G F M e v S0'.
Since this will pollute your definitions, I would not recommend this approach.
Arthur's answer explains the problem very well.
One other (?) way to do it could be to modify your Inductive definition of EvalExpr to explicitly use the equality that you care about (NatMap.Equal instead of Eq). You will have to say in each rule that it is enough for two maps to be Equal.
For example:
| E_Num : forall S E G F M z,
EvalExpr S E G F M (Num z) z S
becomes
| E_Num : forall S1 S2 E G F M z,
NatMap.Equal S1 S2 ->
EvalExpr S1 E G F M (Num z) z S2
Then when you want to prove your Lemma and apply the constructor, you will have to provide a proof that S1 and S2 are equal. (you'll have to reason a little using that NatMap.Equal is an equivalence relation).
I was hoping that Haskell's compiler would understand that f v Is type-safe given Unfold v f (Although that is a tall order).
data Sequence a = FirstThen a (Sequence a) | Repeating a | UnFold b (b -> b) (b -> a)
Is there some way that I can encapsulate a Generic pattern for a datatype without adding extra template parameters.
(I am aware of a solution for this specific case using lazy maps but I am after a more general solution)
You can use existential quantification to get there:
data Sequence a = ... | forall b. UnFold b (b -> b) (b -> a)
I'm not sure this buys you much over the simpler solution of storing the result of unfolding directly, though:
data Stream a = Cons a (Stream a)
data Sequence' a = ... | Explicit (Stream a)
In particular, if somebody hands you a Sequence a, you can't pattern match on the b's contained within, even if you think you know what type they are.
I have tried
S-A|B
A-aCcD|aAc|ac
B-bBd|bd
C-b
D-d
this to only to output ac and bd's but I can't put b's between a and c's.
Consider the string a^p b^p c^p d^p. This string is surely in the language. If the language were regular, and there existed a regular grammar for it, then it would satisfy the requirements of the pumping lemma for regular languages: namely, the string given above could be written as uvx where |uv| <= p, |v| > 0 and for all natural numbers n, u(v^n)x is also in the language. There are seven cases for what v contains: just a; a and b; just b; b and c; just c; c and d; or just d. In any case, pumping v will change the number of instances of one kind of symbol but not the number of instances of the corresponding symbol (the one the language requires be exactly as frequent). So, the language cannot be regular.
Similarly, the pumping lemma for context-free languages would require that the string given above be written as uvxyz where |vxy| <= p, |vy| > 0 and for all natural numbers n, u(v^n)x(y^n)z is also a string of the language. We get exactly the same cases here as above and reach exactly the same conclusion: the language cannot be context-free.
Given all this, we might as well just target an unrestricted grammar (it might be possible to get a context-sensitive grammar for this language, but that is not requested). We want the same number of a and c, and the same number of b and d, and we want them to be in alphabetical order. We can start out like this:
S -> ACS | BDS | T
This lets us get strings with the same number of A as C, and the same number of B as D, ending with T. Next, we need some rules to allow putting the symbols A, B, C and D in the right order:
BA -> AB
CA -> AC
DA -> AD
CB -> BC
DB -> BD
DC -> CD
Finally, we need a way to convert the non-terminals A, B, C and D to terminals a, b, c and d in such a way that it can't work unless they're all in order. We can use T (and a few other symbols to be introduced soon) to sweep from right to left, converting as we go:
DT -> Td
CT -> Uc
BT -> Vb
AT -> Wa
T -> e
CU -> Uc
BU -> Vb
AU -> Wa
U -> e
BV -> Vb
AV -> Wa
V -> e
AW -> Wa
W -> e
Nonterminals T, U, V and W allow converting A-D, A-C, A-B and A to a-d, a-c, a-b and a, respectively. We can also get rid of this marker symbol at any time. The only way to eliminate all nonterminals and get a string of terminals (that is, to generate a string according to this grammar) is to sweep from right to left, converting all encountered symbols, and finally use whichever of the X -> e rules is needed to eliminate the marker. This can only work if the symbols were converted in descending order from right to left, so they must be in ascending order from left to right, as required. Because the productions for S introduce A, C and B, D in matched pairs, that requirement is satisfied as well.
I tried to find out how Haskell is able to resolve types from a guarded equation where no type is specified through the web.
Like in e.g. following function definition, ghci is able to resolve the type and tells me exactly what it is.
fun a b c
| a == c = b
| b < 0 = a+b
| otherwise = c
How does it do this? I know how this works for if-then-else constructs (basically: start with generic version, add constraints) but I am wondering which extra steps are needed here?
fun has three arguments and a result. So initially the compiler assumes they might each be a different type:
fun :: alpha -> beta -> gamma -> delta -- the type vars are placeholders
Ignoring the guards, look at the rhs result of the equations: they each must be type delta. So set up a series of type-level equations from the term-level equations. Use ~ between types to say they must be the same.
The first equation has result b, so b's type must be same as the result, i.e. beta ~ delta.
The third equation has result c, so c's type must be the same as the result, gamma ~ delta.
The second equation has rhs + operator :: Num a => a -> a -> a. We'll come back to the Num a =>. This is saying + has two arguments and a result, all of which are same type. That type is the result of fun's rhs so must be delta. The second arg to + is b, so b's type must be same as the result, beta ~ delta. We already had that from the first equation, so this is just confirming consistency.
The first arg to + is a, so a's type must be same again, alpha ~ delta.
We have alpha ~ beta ~ gamma ~ delta. So go back to the initial signature (which was as general as possible), and substitute equals for equals:
fun :: (constraints) => alpha -> alpha -> alpha -> alpha
Constraints
Pick those up on the fly from the operators.
We already saw Num because of operator +.
The first equation's a == c gives us Eq.
The second equation's b < 0 gives us Ord.
Actually the appearance of 0 gives us another Num, because 0 :: Num a => a, and < :: Ord a => a -> a -> Bool IOW the arguments to < must be same type and same constraints.
So pile up those constraints at the front of fun's type, eliminating duplicates
fun :: (Num alpha, Eq alpha, Ord alpha) => alpha -> alpha -> alpha -> alpha
Is that what you're favourite compiler is telling you? It's probably using type variable a rather than alpha. It's probably not showing Eq alpha.
Eliminating unnecessary superclass constraints
Main> :i Ord
...
class Eq a => Ord a where
...
The Eq a => is telling every Ord type must come with an Eq already. So in giving the signature for fun, the compiler is assuming away its Eq.
fun :: (Num a, Ord a) => a -> a -> a -> a
QED
fun a b c
| a == c = b
| b < 0 = a+b
| otherwise = c
Is it clear how this translates to if/else?
fun a b c
= if a == c
then b
else if b < 0
then a+b
else c
And if we add some human-readable annotations:
fun a b c -- Start reasoning with types of `a`, `b`, `c`, and `result :: r`
= if a == c -- types `a` and `c` are equal, aka `a ~ c`. Also `Eq a, Eq c`.
then b -- types `b ~ r`
else if b < 0 -- `Num b, Ord b`
then a+b -- `a ~ b ~ r` and `Num a, Num b`
else c -- `c ~ r`
If you take all these facts together the type boils down pretty quickly.
a ~ b ~ r and c ~ r
So we know there's actually only one type which we'll just call a and rename all the other types variables in the facts.
Num a, Eq a, Ord a
As a small cognitive savings we know Ord implies Eq so we can end up with constraints Num a, Ord a.
All that swept the mechanics - leveraging of implications such as (==) t1 t2 ~~> t1 = t2 - under the rug but hopefully in an acceptable fashion.
In Haskell we are given the ability to combine constraints on types with a logical and.
Consider the following
type And (a :: Constraint) b = (a, b)
or more complicatedly
class (a, b) => And a b
instance (a, b) => And a b
I want to know how to logically or two constraints together in Haskell.
My closest attempt is this, but it doesn't quite work. In this attempt I reify type constraints with tags and than dereify them with implicit parameters.
data ROr a b where
L :: a => ROr a b
R :: b => ROr a b
type Or a b = (?choose :: ROr a b)
y :: Or (a ~ Integer) (Bool ~ Integer) => a
y = case ?choose of
L -> 4
x :: Integer
x = let ?choose = L in y
It almost works, but the user has to apply the final part, and the compiler should do that for me. As well, this case does not let one choose a third choice when both constraints are satisfied.
How can I logically or two constraints together?
I believe that there is no way to automatically pick an ROr a b; it would violate the open world assumption if, e.g. b was satisfied, but later a was satisfied as well; any conflict resolution rule would necessarily cause the addition of an instance to change the behaviour of existing code.
That is, picking R when b is satisfied but a is not breaks the open world assumption, because it involves deciding that an instance is not satisfied;1 even if you added a "both satisfied" constructor, you would be able to use it to decide whether an instance is not present (by seeing if you get an L or an R).
Therefore, I do not believe that such an or constraint is possible; if you can observe which instance you get, then you can create a program whose behaviour changes by adding an instance, and if you can't observe which instance you get, then it's pretty useless.
1 The difference between this and normal instance resolution, which can also fail, is that normally, the compiler cannot decide that a constraint is satisfied; here, you're asking the compiler to decide that the constraint cannot be satisfied. A subtle but important difference.
I came here to answer your question on the cafe. Not sure the q here is the same, but anyway ...
a type class with three parameters.
class Foo a b c | a b -> c where
foo :: a -> b -> c
instance Foo A R A where ...
instance Foo R A A where ...
In addition to the functional dependency I'd like to express that at least one of the parameters a and b is c,
import Data.Type.Equality
import Data.Type.Bool
class ( ((a == c) || (b == c)) ~ True)
=> Foo a b c | a b -> c where ...
You'll need a bunch of extensions switched on. In particular UndecidableSuperClasses, because the type family calls in the class constraint are opaque as far as GHC can see.
Your q here
How can I logically or two constraints together?
Is far more tricky. For the type equality approach, == uses a Closed Type Family. So you could write a Closed Type Family returning kind Constraint, but I doubt there's a general solution. For your Foo class:
type family AorBeqC a b c :: Constraint where
AorBeqC a b a = ()
AorBeqC a b c = (b ~ c)
class AorBeqC a b c => Foo a b c | a b -> c where ...
It's likely to have poor and non-symmetrical type improvement behaviour: if GHC can see that a, c are apart, it'll go to the second equation and use (b ~ c) to improve either; if it can't see they're apart nor that they're unifiable, it'll get stuck.
In general, as #ehird points out, you can't test whether a constraint is not satisfiable. Type equality is special.