How do I make a fuel annotation for a templated function? - dafny

I would like to write Dafny some code with fuel annotations, like the following:
predicate {:fuel 0,0} eq<A>(x: A, y: A)
{
x == y
}
lemma {:fuel eq,1,2} reflexive<A>(x: A)
ensures eq(x, x)
{
}
Unfortunately, I get an error message:
templates.dfy(6,13): Error: type '?' to the predicate 'eq' is not determined
templates.dfy(6,13): Error: the type of this expression is underspecified
Well, it looks like I just need to specify the type argument to eq. But the 'obvious' approach doesn't work. This code,
predicate {:fuel 0,0} eq<A>(x: A, y: A)
{
x == y
}
lemma {:fuel eq<A>,1,2} reflexive<A>(x: A)
ensures eq(x, x)
{
}
gives the error message:
templates.dfy(6,17): Error: this operator chain cannot continue with a descending operator
templates.dfy(6,18): Error: invalid UnaryExpression
It is possible to accomplish fuel annotations with templated functions in this manner?

The "obvious" way to do it is indeed the way to do it. The parsing error messages you're getting were fixed in Dafny version 2.2.0 (more precisely, in a 10 July 2018 commit).

Related

Boolean operators, first-class functions

It appears that built-in Boolean operators are not first-class functions in Dafny, as the following code doesn't compile. Am I missing something? As a work-around, I assume that we can just wrap built-in functions in our own functions.
datatype binOp = X
function evalOp(o: binOp): bool -> bool
{
match o
{
case X => &&
}
}
The error message, by the way, is "Invalid UnaryExpression".
No, Dafny does not treat operators like && as function values.
As you guessed, you can wrap the operator to create a function. In your example, something like this might work.
case X => (x, y) => x && y
If you plan to use the function a lot, you might instead prefer to give it a name.

what does this error mean, and how to fix it?

Here's my code
let rec Interest a b c =
if (c=0) then b else Interest(a ((1.0+a)*b) (c-1));;
The error is:
if (c=0) then b else Interest(a ((1.0+a)*b) (c-1));;
-------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(2,26): error FS0001: Type mismatch. Expecting a
'a but given a
'a -> int -> 'a The resulting type would be infinite when unifying ''a' and ''a -> int -> 'a'
>
You've defined Interest as a function that takes three arguments but what you pass doesn't match that. The way it's written, you're only passing in a single argument to the recursive call to Interest - the parenthesized expression a ((1.0=a)*b) (c-1). Here, a is inferred to be a function of two arguments, ((1.0=a)*b) and (c-1).
Long story short, this throws off the type inference algorithm, until it gives up saying that it can't get a hang of what type to give to Interest.
What you want is this:
let rec Interest a b c =
if (c=0) then b else Interest a ((1.0=a)*b) (c-1)
You'll also have a problem with (1.0=a). This evaluates to a boolean value that you later want to multiply with b. Not sure what the intent is, but you might be looking for something like (if 1.0 = a then 1 else 0)?
Unlike C-like languages that support implicit conversions between "bools" and ints, F# requires you to make all your conversions explicit to ensure correctness (this goes for converting between numeric types as well).

Inferred types of constructor keyword parameters in Rascal pattern matches

I suppose I do not fully understand the concept of keywords in Rascal in relation to pattern matching (as the following notations are in fact supported by Rascal). Say I have defined a datatype Exp and a function demoFun1 (assuming that in this case z binds to y):
data Exp = a(int x, int y = 5) | b(int x);
Exp demoFun1(a(x, y = z)) = b(z);
And then I execute: demoFun1(a(2, y = 3)), Rascal returns:
|stdin:///|(25,4,<1,25>,<1,29>): The called signature: b(value),
does not match the declared signature: Exp = b(int)
(Which is already quite a strange error message, since I cannot say something like int y = ... in the arguments, assuming that this would be the correct syntax). However, if I define another function where instead I assume that the value after the "="-sign is the default value (as is the case in the ADT-definition), and I can simply use the value of y instead:
Exp demoFun2(a(x, y = 3)) = b(y);
And I execute demoFun2(a(1, y=2))
Then Rascal returns:
|stdin:///|(0,19,<1,0>,<1,19>): The called signature: demoFun2(Exp),
does not match the declared signature: Exp demoFun2(Exp); (abstract pattern);
Is pattern matching on keywords not (yet fully) supported, or am I doing something wrong?
Thank you!
First of all, yes, the error message needs improvement. Actually there is another unreported error which comes first. All introduced variables in patterns in function headers in Rascal must have types. The interpreter does not complain about this, and hence downstream there is an unexpected result.
This fixes your problem, annotating the fresh variable z with int:
Exp demoFun2(a(x, y = int z)) = b(z);
Having said that, the following code triggers a similar issue, indicating that indeed something is amiss in the type inferencing during pattern matching keyword parameters:
rascal>if (a(x, y = q) := xxx) q;
value: 3
The type of q should be nothing but int given the declaration of y.
Thanks for the report, see https://github.com/cwi-swat/rascal/issues/843

F# inferred types in If/Then

If I have the following function:
let myFunc x y =
if y = 0 then 1
x
I get the error:
Program.fs(58,17): error FS0001: This expression was expected to have type
unit
but here has type
int
Why does the compiler expect 'unit' instead of int ?
It might worth adding that this is not just a property of if. F# is an expression-based language meaning that pretty much every piece of code (aside from type declarations and a few exceptions) is an expression that evaluates to some result. In fact, F# does not call if the if statement, but an if expression.
This means that you can use if in unexpected places. For example, this might be useful:
x/2 + (if x%2=0 then 0 else 1)
As already explained by Garry, if you omit else, then the expression still needs to return something - if the result was to be an int, then it would not really make sense (which number should the compiler pick?), so it requires that the result is of type unit, which is a special type representing "no result".
The unit type is also the result of all imperative functions (e.g. printf) or of all expressions that do not logically return any value (assignment or e.g. loop). This means that if you write:
if x > 0 then printfn "Big!"
... then the expression is well-typed, because printfn "Big!" has a return type unit and the implicitly added else branch also returns unit. You can create a value of type unit directly by hand (the type has exactly one value), so the above actually corresponds to:
if x > 0 then printfn "Big!" else ()
From the C# perspective, it makes more sense to read if .. then .. else as the conditional operator:
x/2 + (x%2 == 0 ? 0 : 1)
In F# when using an if statement when there is no else branch then it implicitly returns unit. If your then branch returns a type other than unit you must have an explicit else branch for it to work correctly. In your example you could write:
let myFunc x y = if y = 0 then 1 else x
MSDN - http://msdn.microsoft.com/en-us/library/dd233231.aspx

Ranges A to B where A > B in F#

I've just found something I'd call a quirk in F# and would like to know whether it's by design or by mistake and if it's by design, why is it so...
If you write any range expression where the first term is greater than the second term the returned sequence is empty. A look at reflector suggests this is by design, but I can't really find a reason why it would have to be so.
An example to reproduce it is:
[1..10] |> List.length
[10..1] |> List.length
The first will print out 10 while the second will print out 0.
Tests were made in F# CTP 1.9.6.2.
EDIT: thanks for suggesting expliciting the range, but there's still one case (which is what inspired me to ask this question) that won't be covered. What if A and B are variables and none is constantly greater than the other although they're always different?
Considering that the range expression does not seem to get optimized at compiled time anyway, is there any good reason for the code which determines the step (not explicitly specified) in case A and B are ints not to allow negative steps?
As suggested by other answers, you can do
[10 .. -1 .. 1] |> List.iter (printfn "%A")
e.g.
[start .. step .. stop]
Adam Wright - But you should be able
to change the binding for types you're
interested in to behave in any way you
like (including counting down if x >
y).
Taking Adam's suggestion into code:
let (..) a b =
if a < b then seq { a .. b }
else seq { a .. -1 .. b }
printfn "%A" (seq { 1 .. 10 })
printfn "%A" (seq { 10 .. 1 })
This works for int ranges. Have a look at the source code for (..): you may be able to use that to work over other types of ranges, but not sure how you would get the right value of -1 for your specific type.
What "should" happen is, of course, subjective. Normal range notation in my mind defines [x..y] as the set of all elements greater than or equal to x AND less than or equal to y; an empty set if y < x. In this case, we need to appeal to the F# spec.
Range expressions expr1 .. expr2 are evaluated as a call to the overloaded operator (..), whose default binding is defined in Microsoft.FSharp.Core.Operators. This generates an IEnumerable<_> for the range of values between the given start (expr1) and finish (expr2) values, using an increment of 1. The operator requires the existence of a static member (..) (long name GetRange) on the static type of expr1 with an appropriate signature.
Range expressions expr1 .. expr2 .. expr3 are evaluated as a call to the overloaded operator (.. ..), whose default binding is defined in Microsoft.FSharp.Core.Operators. This generates an IEnumerable<_> for the range of values between the given start (expr1) and finish (expr3) values, using an increment of expr2. The operator requires the existence of a static member (..) (long name GetRange) on the static type of expr1 with an appropriate signature.
The standard doesn't seem to define the .. operator (a least, that I can find). But you should be able to change the binding for types you're interested in to behave in any way you like (including counting down if x > y).
In haskell, you can write [10, 9 .. 1]. Perhaps it works the same in F# (I haven't tried it)?
edit:
It seems that the F# syntax is different, maybe something like [10..-1..1]
Ranges are generally expressed (in the languages and frameworks that support them) like this:
low_value <to> high_value
Can you give a good argument why a range ought to be able to be expressed differently? Since you were requesting a range from a higher number to a lower number does it not stand to reason that the resulting range would have no members?

Resources