The following code:
Reserved Notation "g || t |- x < y" (at level 10).
Inductive SubtypeOf :
GammaEnv -> ThetaEnv -> UnsafeType -> UnsafeType -> Set :=
| SubRefl :
forall (gamma : GammaEnv) (theta : ThetaEnv) (u : UnsafeType) , gamma || theta |- u < u
where "g || t |- x < y" := (SubtypeOf g t x y).
gives the following error:
Syntax error: '<' expected after [constr:operconstr level 200] (in [constr:operconstr])
I get a similar error if I use <: in place of <.
But this code works fine:
Reserved Notation "g || t |- x << y" (at level 10).
Inductive SubtypeOf :
GammaEnv -> ThetaEnv -> UnsafeType -> UnsafeType -> Set :=
| SubRefl :
forall (gamma : GammaEnv) (theta : ThetaEnv) (u : UnsafeType) , gamma || theta |- u << u
where "g || t |- x << y" := (SubtypeOf g t x y).
Why? Is there a precedence setting that can be changed to allow < or <: in notation? Is there built-in syntax that I'm colliding with, and need to watch for when defining notations?
Coq uses an LL1 parser to process notations. It also can output the grammar. So, let's check what we are getting with the following
Reserved Notation "g || t |- x < y" (at level 10).
Print Grammar constr. outputs:
...
| "10" LEFTA
[ SELF;
"||";
constr:operconstr LEVEL "200"; (* subexpression t *)
"|-";
constr:operconstr LEVEL "200"; (* subexpression x *)
"<";
NEXT
...
Here,
10 is our precedence level;
LEFTA means left associativity;
200 is the default precedence level for inner subexpressions.
Taking into account the fact that a lower level binds more tightly than a higher level and the fact that the level of < is 70 (see Coq.Init.Notations), we can deduce that Coq is trying to parse the x < y part as a subexpression for x, consuming the < token, hence the error message.
To remedy the situation we can explicitly disallow parsing the third parameter as the less-than expression by assigning x higher precedence, i.e. a lower level.
Reserved Notation "g || t |- x < y" (at level 10, x at level 69).
Print Grammar constr.
| "10" LEFTA
[ SELF;
"||";
constr:operconstr LEVEL "200"; (* subexpression t *)
"|-";
constr:operconstr LEVEL "69"; (* subexpression x *)
"<";
NEXT
Related
I am trying to define two instances of a type class, one of which will use the other's instance. However, unless I bind the function's name outside of the second definition Coq is unable to determine it should use the type class instance from bexp (take a look at the comment for dirty hack). Is there a way to avoid this sort of hack in Coq?
Class Compilable ( A : Type ) := { compile : A -> bool }.
Inductive cexp : Type :=
| CAnd : cexp -> cexp -> cexp
| COr : cexp -> cexp -> cexp
| CProp : bexp -> cexp.
Instance: Compilable bexp :=
{ compile :=
fix compile b :=
match b with
(* elided *)
end
}.
Definition compile2 := compile.
Instance: Compilable cexp :=
{ compile :=
fix compile c :=
match c with
| CAnd x y => (compile x) && (compile y)
| COr x y => (compile x) || (compile y)
| CProp e => (compile2 e) (* <-- dirty hack *)
end
}.
This can be fixed if we replace compile with some other name (rec) like so:
Instance: Compilable cexp :=
{ compile :=
fix rec c :=
match c with
| CAnd x y => (rec x) && (rec y)
| COr x y => (rec x) || (rec y)
| CProp e => (compile e)
end
}.
In this comment the OP pointed out that Haskell easily deals with this situation. To understand the reason why Coq does not do it let us take a look at the type of compile:
About compile.
compile : forall A : Type, Compilable A -> A -> bool
Arguments A, Compilable are implicit and maximally inserted
We can see that Coq is more explicit about how typeclasses work. When you call compile e Coq sort of inserts placeholders standing for the implicit arguments like so #compile _ _ e (see these slides, pages 21-25 for more detail). But with fix compile c you shadowed the previous binding, hence the type error.
Say I have a type Prop for propositions:
type Prop =
| P of string
| Disjunction of Prop * Prop
| Conjunction of Prop * Prop
| Negation of Prop
Where:
• A "p" representing the atom P,
• Disjunction(A "P", A "q") representing the proposition P ∨ q.
• Conjunction(A "P", A "q") representing the proposition P ∧ q.
• Negation(A "P") representing the proposition ¬P.
I'm supposed to use a set-based representation of formulas in disjunctive normal form. Since conjunction is commutative, associative and (a ∧ a) is equivalent to a it is convenient to represent a basic conjunct bc by its set of literals litOf(bc).
bc is defined as: A literal is an atom or the negation of an atom and a basic conjunct is a conjunction of literals
This leads me to the function for litOf:
let litOf bc =
Set.fold (fun acc (Con(x, y)) -> Set.add (x, y) acc) Set.empty bc
I'm pretty sure my litOf is wrong, and I get an error on the (Con(x,y)) part saying: "Incomplete pattern m
atches on this expression. For example, the value 'Dis (_, _)' may indicate a cas
e not covered by the pattern(s).", which I also have no clue what actually means in this context.
Any hints to how I can procede?
I assume your example type Prop changed on the way from keyboard to here, and orginally looked like this:
type Prop =
| P of string
| Dis of Prop * Prop
| Con of Prop * Prop
| Neg of Prop
There are several things that tripped you up:
Set.fold operates on input that is a set, and does something for each element in the set. In your case, the input is a boolean clause, and the output is a set.
You did not fully define what constitutes a literal. For a conjunction, the set of literals is the union of the literals on the left and on the right side. But what about a disjunction? The compiler error message means exactly that.
Here's what I think you are after:
let rec literals = function
| P s -> Set.singleton s
| Dis (x, y) -> Set.union (literals x) (literals y)
| Con (x, y) -> Set.union (literals x) (literals y)
| Neg x -> literals x
With that, you will get
> literals (Dis (P "A", Neg (Con (P "B", Con (P "A", P "C")))))
val it : Set<string> = set ["A"; "B"; "C"]
I have a question for the Follow sets of the following rules:
L -> CL'
L' -> epsilon
| ; L
C -> id:=G
|if GC
|begin L end
I have computed that the Follow(L) is in the Follow(L'). Also Follow(L') is in the Follow(L) so they both will contain: {end, $}. However, as L' is Nullable will the Follow(L) contain also the Follow(C)?
I have computed that the Follow(C) = First(L') and also Follow(C) subset Follow(L) = { ; $ end}.
In the answer the Follow(L) and Follow(L') contain only {end, $}, but shouldn't it contain ; as well from the Follow(C) as L' can be null?
Thanks
However, as L' is Nullable will the Follow(L) contain also the Follow(C)?
The opposite. Follow(C) will contain Follow(L). Think of the following sentence:
...Lx...
where X is some terminal and thus is in Follow(L). This could be expanded to:
...CL'x...
and further to:
...Cx...
So what follows L, can also follow C. The opposite is not necessarily true.
To calculate follows, think of a graph, where the nodes are (NT, n) which means non-terminal NT with the length of tokens as follow (in LL(1), n is either 1 or 0). The graph for yours would look like this:
_______
|/_ \
(L, 1)----->(L', 1) _(C, 1)
| \__________|____________/| |
| | |
| | |
| _______ | |
V |/_ \ V V
(L, 0)----->(L', 0) _(C, 0)
\_______________________/|
Where (X, n)--->(Y, m) means the follows of length n of X, depend on follows of length m of Y (of course, m <= n). That is to calculate (X, n), first you should calculate (Y, m), and then you should look at every rule that contains X on the right hand side and Y on the left hand side e.g.:
Y -> ... X REST
take what REST expands to with length n - m for every m in [0, n) and then concat every result with every follow from the (Y, m) set. You can calculate what REST expands to while calculating the firsts of REST, simply by holding a flag saying whether REST completely expands to that first, or partially. Furthermore, add firsts of REST with length n as follows of X too. For example:
S -> A a b c
A -> B C d
C -> epsilon | e | f g h i
Then to find follows of B with length 3 (which are e d a, d a b and f g h), we look at the rule:
A -> B C d
and we take the sentence C d, and look at what it can produce:
"C d" with length 0 (complete):
"C d" with length 1 (complete):
d
"C d" with length 2 (complete):
e d
"C d" with length 3 (complete or not):
f g h
Now we take these and merge with follow(A, m):
follow(A, 0):
epsilon
follow(A, 1):
a
follow(A, 2):
a b
follow(A, 3):
a b c
"C d" with length 0 (complete) concat follow(A, 3):
"C d" with length 1 (complete) concat follow(A, 2):
d a b
"C d" with length 2 (complete) concat follow(A, 1):
e d a
"C d" with length 3 (complete or not) concat follow(A, 0) (Note: follow(X, 0) is always epsilon):
f g h
Which is the set we were looking for. So in short, the algorithm becomes:
Create the graph of follow dependencies
Find the connected components and create a DAG out of it.
Traverse the DAG from the end (from the nodes that don't have any dependency) and calculate the follows with the algorithm above, having calculated firsts beforehand.
It's worth noting that the above algorithm is for any LL(K). For LL(1), the situation is much simpler.
I thought these two function were the same, but it seems that I was wrong.
I define two function f and g in this way:
let rec f n k =
match k with
|_ when (k < 0) || (k > n) -> 0
|_ when k = n -> 100
|_ -> (f n (k+1)) + 1
let rec g n k =
match k with
|_ when (k < 0) || (k > n) -> 0
| n -> 100
|_ -> (g n (k+1)) + 1
let x = f 10 5
let y = g 10 5
The results are:
val x : int = 105
val y : int = 100
Could anyone tell me what's the difference between these two functions?
EDIT
Why does it work here?
let f x =
match x with
| 1 -> 100
| 2 -> 200
|_ -> -1
List.map f [-1..3]
and we get
val f : x:int -> int
val it : int list = [-1; -1; 100; 200; -1]
The difference is that
match k with
...
when k = n -> 100
is a case that matches when some particular condition is true (k = n). The n used in the condition refers to the n that is bound as the function parameter. On the other hand
match k with
...
n -> 100
is a case that only needs to match k against a pattern variable n, which can always succeed. The n in the pattern isn't the same n as the n passed into the function.
For comparison, try the code
let rec g n k =
match k with
|_ when (k < 0) || (k > n) -> 0
| n -> n
|_ -> (g n (k+1)) + 1
and you should see that when you get to the second case, the value returned is the value of the pattern variable n, which has been bound to the value of k.
This behavior is described in the Variable Patterns section of the MSDN F# Language Reference, Pattern Matching:
Variable Patterns
The variable pattern assigns the value being matched to a variable
name, which is then available for use in the execution expression to
the right of the -> symbol. A variable pattern alone matches any
input, but variable patterns often appear within other patterns,
therefore enabling more complex structures such as tuples and arrays
to be decomposed into variables. The following example demonstrates a
variable pattern within a tuple pattern.
let function1 x =
match x with
| (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2
| (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2
| (var1, var2) -> printfn "%d equals %d" var1 var2
function1 (1,2)
function1 (2, 1)
function1 (0, 0)
The use of when is described in more depth in Match Expressions.
The first function is ok, it calls recursively itself n-k times and returns 100 when matches with the conditional where k = n. So, it returns all the calls adding 1 n-k times. with your example, with n=10 and k=5 it is ok the result had been 105.
The problem is the second function. I tested here. See I changed the pattern n->100 to z->100 and it still matches there and never calls itself recursively. So, it always returns 100 if it does not fail in the first conditional. I think F# don't allow that kind of match so it is better to put a conditional to get what you want.
I am currently experimenting with F#. The articles found on the internet are helpful, but as a C# programmer, I sometimes run into situations where I thought my solution would help, but it did not or just partially helped.
So my lack of knowledge of F# (and most likely, how the compiler works) is probably the reason why I am totally flabbergasted sometimes.
For example, I wrote a C# program to determine perfect numbers. It uses the known form of Euclids proof, that a perfect number can be formed from a Mersenne Prime 2p−1(2p−1) (where 2p-1 is a prime, and p is denoted as the power of).
Since the help of F# states that '**' can be used to calculate a power, but uses floating points, I tried to create a simple function with a bitshift operator (<<<) (note that I've edit this code for pointing out the need):
let PowBitShift (y:int32) = 1 <<< y;;
However, when running a test, and looking for performance improvements, I also tried a form which I remember from using Miranda (a functional programming language also), which uses recursion and a pattern matcher to calculate the power. The main benefit is that I can use the variable y as a 64-bit Integer, which is not possible with the standard bitshift operator.
let rec Pow (x : int64) (y : int64) =
match y with
| 0L -> 1L
| y -> x * Pow x (y - 1L);;
It turns out that this function is actually faster, but I cannot (yet) understand the reason why. Perhaps it is a less intellectual question, but I am still curious.
The seconds question then would be, that when calculating perfect numbers, you run into the fact that the int64 cannot display the big numbers crossing after finding the 9th perfectnumber (which is formed from the power of 31). I am trying to find out if you can use the BigInteger object (or bigint type) then, but here my knowledge of F# is blocking me a bit. Is it possible to create a powerfunction which accepts both arguments to be bigints?
I currently have this:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| bigint.Zero -> 1I
| y -> x * Pow x (y - 1I);;
But it throws an error that bigint.Zero is not defined. So I am doing something wrong there as well. 0I is not accepted as a replacement, since it gives this error:
Non-primitive numeric literal constants cannot be used in pattern matches because they
can be mapped to multiple different types through the use of a NumericLiteral module.
Consider using replacing with a variable, and use 'when <variable> = <constant>' at the
end of the match clause.
But a pattern matcher cannot use a 'when' statement. Is there another solution to do this?
Thanks in advance, and please forgive my long post. I am only trying to express my 'challenges' as clear as I can.
I failed to understand why you need y to be an int64 or a bigint. According to this link, the biggest known Mersenne number is the one with p = 43112609, where p is indeed inside the range of int.
Having y as an integer, you can use the standard operator pown : ^T -> int -> ^T instead because:
let Pow (x : int64) y = pown x y
let PowBigInt (x: bigint) y = pown x y
Regarding your question of pattern matching bigint, the error message indicates quite clearly that you can use pattern matching via when guards:
let rec PowBigInt x y =
match y with
| _ when y = 0I -> 1I
| _ -> x * PowBigInt x (y - 1I)
I think the easiest way to define PowBigInt is to use if instead of pattern matching:
let rec PowBigInt (x : bigint) (y : bigint) =
if y = 0I then 1I
else x * PowBigInt x (y - 1I)
The problem is that bigint.Zero is a static property that returns the value, but patterns can only contain (constant) literals or F# active patterns. They can't directly contain property (or other) calls. However, you can write additional constraints in where clause if you still prefer match:
let rec PowBigInt (x : bigint) (y : bigint) =
match y with
| y when y = bigint.Zero -> 1I
| y -> x * PowBigInt x (y - 1I)
As a side-note, you can probably make the function more efficent using tail-recursion (the idea is that if a function makes recursive call as the last thing, then it can be compiled more efficiently):
let PowBigInt (x : bigint) (y : bigint) =
// Recursive helper function that stores the result calculated so far
// in 'acc' and recursively loops until 'y = 0I'
let rec PowBigIntHelper (y : bigint) (acc : bigint) =
if y = 0I then acc
else PowBigIntHelper (y - 1I) (x * acc)
// Start with the given value of 'y' and '1I' as the result so far
PowBigIntHelper y 1I
Regarding the PowBitShift function - I'm not sure why it is slower, but it definitely doesn't do what you need. Using bit shifting to implement power only works when the base is 2.
You don't need to create the Pow function.
The (**) operator has an overload for bigint -> int -> bigint.
Only the second parameter should be an integer, but I don't think that's a problem for your case.
Just try
bigint 10 ** 32 ;;
val it : System.Numerics.BigInteger =
100000000000000000000000000000000 {IsEven = true;
IsOne = false;
IsPowerOfTwo = false;
IsZero = false;
Sign = 1;}
Another option is to inline your function so it works with all numeric types (that support the required operators: (*), (-), get_One, and get_Zero).
let rec inline PowBigInt (x:^a) (y:^a) : ^a =
let zero = LanguagePrimitives.GenericZero
let one = LanguagePrimitives.GenericOne
if y = zero then one
else x * PowBigInt x (y - one)
let x = PowBigInt 10 32 //int
let y = PowBigInt 10I 32I //bigint
let z = PowBigInt 10.0 32.0 //float
I'd probably recommend making it tail-recursive, as Tomas suggested.