Boolean operators, first-class functions - dafny

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.

Related

Is there a better way to write a commutative function in F#/OCaml?

Is there a more elegant or better way to write a commutative function in F#/OCaml rather than listing all possible cases?
let commutative x y =
match x,y with
a, _ -> val1
|_, a -> val1
|b, _ -> val2
|_, b -> val2
...
|_,z -> |valN
While I was writing the question I thought one could make the function recursive and swap the arguments if no match is found.
let rec commutative x y =
match x,y with
a,_ -> val1
|b,_ -> val2
...
|nox,noy -> commutative noy nox
But if I adopt this approach I cannot have in the function a default case that matches with everything unless I add another argument whose value indicates if it's the second time the function is being called and return the default value instead of calling the function with the swapped args if that's the case.
Any other ideas?
Does the language offer a construct for expressing the fact a function I'm defining is commutative?
(I'm answering for OCaml only as my F# is extremely rusty.)
There's no special help in OCaml for defining commutative functions.
If your parameter type has a reasonable ordering relation you can swap them if necessary to make x the larger (say). Almost all types can be compared in OCaml, so this should work very commonly. (Things that can't be compared: function types, cyclic values.)
I'm not sure this would help, but it might reduce the number of cases that you need to write out:
let commutative x y =
match (max x y, min x y) with
| A, _ -> value
. . .

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

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).

How to pass a "Function" type in FunScript?

I am encountering this Function type that I need to pass to a JQueryAnimationOptions object. I usually would pass a lambda to callbacks but these seem to be incompatible. I looked up every sample I could find in the FunScript repo. and couldn't find any workaround.
It also said the the Function is actually an interface (for what?) when used as a return statement Error: Invalid use of interface type.
So how to pass a callback argument with this Function type?
the code:
[<FunScript.JS>]
module Main
open FunScript
open FunScript.TypeScript
let sayHelloFrom (name:string) =
Globals.window.alert("Hello, " + name)
let jQuery (selector:string) = Globals.jQuery.Invoke selector
let main() =
let options = createEmpty<JQueryAnimationOptions>()
options.duration <- 3000
options.complete <- (fun _ -> sayHelloFrom("F#"))
let properties = createEmpty<Object>()
properties.Item("opacity") <- 1
let mainContent = jQuery "#mainContent"
mainContent.animate(properties, options) |> ignore
mainContent.click(fun e -> sayHelloFrom("F#") :> obj)
This works more or less as you would expect when passing lambdas between F# and C#. In F#, functions can be curried, while in C# (and JavaScript) cannot. So when you need to send a lambda from F# to C# you need to convert it first. In F# this is done by wrapping the lambda like this:
open System.Linq
open System.Collections.Generic
let ar = [|1;2;3|]
let f = fun (x: int) (y: int) -> x + y
let acc = ar.Aggregate( System.Func<int,int,int>(f) )
Actually, the F# compiler can deduce the types most of the times, so you only need to write: System.Func<_,_,_>(f). Furthermore, when passing a F# lambda to a method expecting a C# lambda, the compiler makes the wrapping automatically for you. Then the previous example becomes:
let ar = [|1;2;3|]
let acc = ar.Aggregate( fun x y -> x + y )
(Of course, in this case it would be better to use the idiomatic Array.reduce. This is just a contrived example.)
This works exactly the same when interacting with JS using FunScript. The only thing you need to be aware of is how F# lambdas get translated to JS. To allow currying, a lambda with two or more parameters like fun x y -> x + y becomes:
function (x) {
return function (y) {
return x + y;
}
}
Which may be a problem because the native JS will expect the following signature: function (x, y). In that case, you would have to wrap the lambda with System.Func<_,_,_>() as when interacting with C# (remember this is done automatically if you pass the lambda to a method).
However, lambdas with just one parameter don't suppose any problem: fun x -> x*x becomes function (x) { return x*x; }. In that case you don't need to wrap them (it doesn't hurt to do it anyway) and it's enough just to use unbox to appease the F# compiler when necessary. Just please be aware the FunScript compiler ignores unbox in the final JS code so there'll be no type check at all at runtime.
I hope the explanation is clear. Please add a comment if it isn't and I'll edit the answer.
Nevermind , I found the solution, I had to unbox the lambda:
options.complete <- unbox<Function> (fun _ -> sayHelloFrom("F#"))

Postfix conditional operator in F#

In Perl language one can write something like
someFunction() if $x == 0
i.e. apply condition in postfix notation.
I was sure there must be similar type of expression in F#, since it is so flexible in working with functions. But when I try to write
someFunction() if x = 0
or
someFunction() << if x = 0
I recieve an expected error message. Is there any way to implement more or less general postfix conditional operator in F#?
There is no built-in F# support for this and so I would recommend just using the normal prefix style conditionals (or pattern matching). There is also no standard operator/function that would be common in the community, so the idiomatic style would just use ordinary if.
I think that the best you can do is something like this:
/// Evaluates lazy value only if the specified boolean holds
let assuming b (v:Lazy<_>) = if b then v.Value
// Print foo only when x > 40
let foo() = printfn "hi"
let x = 42
lazy foo() |> assuming (x > 40)
Note that I had to add lazy to the expression (to make sure it is not actually evaluated when the condition does not holds). This works, but it is certainly uglier than writing if x>40 then foo() - but it is a fun thing to experiment with :-)

Why isn't it possible to use the same function twice with differently typed arguments?

I played around a little with F# today, wrote this:
let sq x = x * x
let i = sq 3
let d = sq 3.0
It compiles if I remove either the third or the fourth line, but not if both are present.
I get the error This expression should have type 'int', but has type 'float'.
The type inference works so that your function sq has type int -> int, because the first time compiler sees you use that function, you pass it an integer. So it assumes that sq is a function that takes an integer, and by definition of the function (x * x) it also returns an integer.
It is a bit complicated to define a fully generic arithmetic function in F#, but one way to do it is to make the function inline, like so:
let inline sq x = x * x
This way the body of your function will be inlined each time at the call site, so using an inlined sq function will be the same as substituting it's body every time it's used.
This approach has it's drawbacks, and I think it will be interesting for you to see this question.
Let-bound functions cannot be overloaded. In your specific case, you could use inline, which inlines the function body at compile time and can therefore choose an appropriate implementation of *, e.g.
let inline sq x = x * x
The other answers are correct but they leave out an important part of the jigsaw: the fact that in F# there are no implicit conversions between, for example, ints and floats. This is the reason why your second call is in effect calling a different, non existent, overload with a float argument.
The function let sq x = x * x on default has type int -> int.
If you put it in the context of a let d = sq 3.0, F# compiler will infer its type as float -> float.
In any way, this function can have only one type signature, either int->int, or float->float.
This is a limitation in how the bindings are implemented. There are 2 alternatives.
Firstly, add inline to the declaration.
Secondly, use member bindings in a class and override the different types.

Resources