Why does compiling this code:
triples( [], _,_,_)->
[];
triples( Self, X, Y, none )->
[ Result || Result = { X, Y, _} <- Self ].
report:
./simple_graph.erl:63: Warning: variable 'X' is unused
./simple_graph.erl:63: Warning: variable 'Y' is unused
./simple_graph.erl:64: Warning: variable 'X' is unused
./simple_graph.erl:64: Warning: variable 'X' shadowed in generate
./simple_graph.erl:64: Warning: variable 'Y' is unused
./simple_graph.erl:64: Warning: variable 'Y' shadowed in generate
And return wrong result: full Self.
This is because variables occurring on the LHS of generators, X and Y here, are always new unbound variables local to the comprehension. This means that they are not the same variables as the X and Y in the head of triples and, therefore, there is no implicit equality test. This similar to funs where all variables occurring in the head of a fun are alse new variables local to the fun.
This is different from most of the rest of erlang, which is why the compiler not only warns that the X and Y in the head are not used but also that the X and Y in the comprehension shadow the other variables. They are also unused anywhere in the comprehension.
An easy way to get what you want is:
[ Result || Result = {X1,Y1,_} <- Self, X =:= X1, Y =:= Y1 ]
Related
It is actually pretty unxpected to me but consider this snippet in F#:
let f x =
printfn $"{x}"
fun x' -> x'
let y<'t> = f 1 //> val y<'t> : (obj -> obj)
y 2
//>
//1
//val it: obj = 2
what I would expect is that it will print "1" only when you bind f 1 to "y" (and that would tell me that "f" body only executes once) but seem like it executes "f" body on the every call of "y". Is it unavoidable effect related to auto curring or I'm missing something and there is a way to bypass outer function body execution on the every call of the returned function?
The hint as to what's going on here is the fact that 't has been constrained to obj and the signature of y is (obj -> obj). That's the F# compiler effectively say, "I give up, these have no real types, it is whatever it is" and emitting something that can execute at runtime but without any real type safety.
A side effect of this is that because it can't "pin down" y to a known signature, it cannot evaluate f, so it just emits y as a direct call to f, since you've effectively told the compiler that this is fine by parameterizing it with 't (which ends up just being obj, or "whatever").
Why is this happening? Value restriction!
I suspect you've evaluated this in F# Interactive block-by-block. The line of code that defines let y = f 1 is not possible to compile with more information. You can do so in two ways:
Use y with a real type that will pin its signature to the type you're using it as.
Give it an explicit signature like let y: int -> int = f 1 so that it's pinned down to a concrete type.
That's why if you execute this entire snippet in FSI or run it as a program, things work exactly like you'd expect:
let f x =
printfn $"{x}"
fun x' -> x'
let y = f 1
y 2
y 3
This is because y is generic.
Every time you refer to y, you choose a particular 't to go with that. For example:
let a = y<int>
let b = y<string>
a and b cannot be the same value, because they have been obtained from different instantiations of y. They have to be two different values. And this in turn means that y itself cannot be a single value. It has to be a function.
And that's what it is under the hood: it's compiled as a function, and every time you refer to it, the function is instantiated with the generic parameter you chose, and the body of the function is executed to obtain the result.
If you remove the generic parameter and give y a concrete type, the issue should go away:
let y = f 1 : obj -> obj
I'm implementing a vector field method that should return a numeric value based on an (x, y) position, where x and y are both instances of pydrake.symbolic.Variable. I'm essentially looking to run f(x, y) -> float inside of the dynamics method of my SymbolicVectorSystem. Is it possible to evaluate the numeric value of x and y so that they can be used to compute f(x, y) numerically?
Yes. You can just call y = Evaluate(my_symbolic_expression), or y = Evaluate(my_vector_or_matrix_of_symbolic_expressions) which are using https://drake.mit.edu/pydrake/pydrake.symbolic.html#pydrake.symbolic.Evaluate with the default arguments. This will return floats iff the expression is simply holding a constant value, or will throw an error if you still have symbols inside that need to be defined.
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
If I run the first example from MSDN (https://msdn.microsoft.com/en-us/library/dd233212.aspx) in the F# Interactive window, I get the expected output:
fun (x:System.Int32) -> x + 1
a + 1
let f = fun (x:System.Int32) -> x + 10 in f 10
But if I run it in the Main from my program, all let bindings are replaced by their constant values:
[<EntryPoint>]
let main argv =
let a = 2
// exprLambda has type "(int -> int)".
let exprLambda = <# fun x -> x + 1 #>
// exprCall has type unit.
let exprCall = <# a + 1 #>
println exprLambda
println exprCall
println <## let f x = x + 10 in f 10 ##>
Result:
fun (x:System.Int32) -> x + 1
2 + 1
let f = fun (x:System.Int32) -> x + 10 in f 10
Is this normal or a bug? Are the rules for this documented? What can I do to force it to the expected output?
Edit:
This answer (https://stackoverflow.com/a/4945137/1872399) states (Variables are automatically replaced with values if the variable is defined outside of the quotation). but I couldn't find any mention of this elsewhere.
Edit 2: What I really want to do
This code (https://gist.github.com/0x53A/8848b04c2250364a3c22) goes into the catch-all case and fails with not implemented:parseQuotation:Value (Variable "ax1") (I expected it to go into | Var(var) ->) so not only constants known at compile-time, but also function parameters are expanded to their values.
Edit 3:
I ran the working version (https://gist.github.com/0x53A/53f45949db812bde5d97) under the debugger, and it looks like that one is actually the bug:
The quotation is {Call (None, op_Addition, [PropertyGet (None, a, []), Value (1)])} witha = Program.a, so this seems to be a side-effect of the fact that let bindings in modules are compiled into properties. If I am correct, I should maybe file a doc-bug at Microsoft...
In general, the problem with quoting of variables is that they escape their scope. That is, having a variable foo in your quotation does not really make any sense if you do not have any way to find out what does the foo variable refer to.
So, for example, the following is OK, because the variable x is defined by the lambda:
<# fun x -> x #>
But if you have something like the following, it does not make sense to capture variable x because once the function returns, x is no longer in scope:
fun x -> <# x #>
This is the same to the situation you're describing - top-level bindings become static members of a module and so those can be captured, but local variables are not available after the expression evaluates and so they are replaced by values. So, the general rules are:
Accessing top-level bindings is quoted as getter of a static member
Accessing variables defined inside the quotations is captured as variable access
Accessing local variables of a function captures the value of the variable
There are definitely cases where being able to capture the variable name would be useful. One example that I really wanted to be able to do is to let people write for example:
plot(years, GDP)
The idea is that the plot function would get a quotation with variable names (which can then be used e.g. for plot axis). There is actually an F# 4.0 change proposal that lets you do this.
Suppose we have the following code:
context c;
solver s(c);
expr x=c.bool_const("a");
expr y=c.bool_const("a");
expr z=c.bool_const("b");
s.add(x&&!y);
std::cout<<s.check();
s.reset();
s.add(x&&!z);
std::cout<<s.check();
The executing result of above code is 'unsat sat';
The result shows that z3 regards x and y as the same variable.
Does z3 distinguish variables by their names?
And if I use the same variable in different places, can I write the code as following:
context c;
solver(s);
function test1(){
s.add(c.bool_const("a"));
}
function test2(){
s.add(!c.bool_const("a"));
}
Dose the function 'test1' and 'test2" manipulate the same variable?
You seem to confuse the programming variables x and y that exist in the host language C++ with logical variables a and b that Z3 reasons about. x and y both represent the logical variable a, and by adding x && !y to the constraints you give Z3 the fact a && !a, which makes your constraints unsatisfiable.