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.
Related
In Z3-Py, I am performing quantifier elimination (QE) over the following formulae:
Exists y. Forall x. (x>=2) => ((y>1) /\ (y<=x))
Forall x. Exists y. (x>=2) => ((y>1) /\ (y<=x)),
where both x and y are Integers. I did QE in the following way:
x, y = Ints('x, y')
t = Tactic("qe")
negS0= (x >= 2)
s1 = (y > 1)
s2 = (y <= x)
#EA
ea = Goal()
ea.add(Exists([y],Implies(negS0, (ForAll([x], And(s1,s2))))))
ea_qe = t(ea)
print(ea_qe)
#AE
ae = Goal()
ae.add(ForAll([x],Implies(negS0, (Exists([y], And(s1,s2))))))
ae_qe = t(ae)
print(ae_qe)
Result QE for ae is as expected: [[]] (i.e., True). However, as for ea, QE outputs: [[Not(x, >= 2)]], which is a results that I do not know how to interpret since (1) it has not really performed QE (note the resulting formula still contains x and indeed does not contain y which is the outermost quantified variable) and (2) I do not understand the meaning of the comma in x, >=. I cannot get the model either:
phi = Exists([y],Implies(negS0, (ForAll([x], And(s1,s2)))))
s_def = Solver()
s_def.add(phi)
print(s_def.model())
This results in the error Z3Exception: model is not available.
I think the point is as follows: since (x>=2) is an implication, there are two ways to satisfy the formula; by making the antecedent False or by satisfying the consequent. In the second case, the model would be y=2. But in the first case, the result of QE would be True, thus we cannot get a single model (as it happens with a universal model):
phi = ForAll([x],Implies(negS0, (Exists([y], And(s1,s2)))))
s_def = Solver()
s_def.add(phi)
print(s_def.model())
In any case, I cannot 'philosophically' understand the meaning of a QE of x where x is part of the (quantifier-eliminated) answer.
Any help?
There are two separate issues here, I'll address them separately.
The mysterious comma This is a common gotcha. You declared:
x, y = Ints('x, y')
That is, you gave x the name "x," and y the name "y". Note the comma after the x in the name. This should be
x, y = Ints('x y')
I guess you can see the difference: The name you gave to the variable x is "x," when you do the first; i.e., comma is part of the name. Simply skip the comma on the right hand side, which isn't what you intended anyhow. And the results will start being more meaningful. To be fair, this is a common mistake, and I wish the z3 developers ignored the commas and other punctuation in the string you give; but that's just not the case. They simply break at whitespace.
Quantification
This is another common gotcha. When you write:
ea.add(Exists([y],Implies(negS0, (ForAll([x], And(s1,s2))))))
the x that exists in negS0 is not quantified over by your ForAll, since it's not in the scope. Perhaps you meant:
ea.add(Exists([y],ForAll([x], Implies(negS0, And(s1,s2)))))
It's hard to guess what you were trying to do, but I hope the above makes it clear that the x wasn't quantified. Also, remember that a top-level exist quantifier in a formula is more or less irrelevant. It's equivalent to a top-level declaration for all practical purposes.
Once you make this fix, I think things will become more clear. If not, please ask further clarifying questions. (As a separate question on Stack-overflow; as edits to existing questions only complicate the matters.)
I'm looking to use a one-way function in a z3 Python program. I'd like z3 to respect the following properties/tactics:
if x = y, then f(x) = f(y)
f is a computable Python function that I can provide when x is known
if f(x) = y, attempt to resolve by matching f(*y) = f(x) implying x = *y from prior assignments (never attempt to guess x that computes to y)
Are there built in features to support this construct or anything else that may help introduce it?
So I'm trying to get all of the elements from a set of sets but am getting the error:
"a set comprehension must produce a finite set, but Dafny's heuristics can't figure out how to produce a bounded set of values for 'x' "
I think it may be to do with the fact that you can't get the cardinality of a set.
Appreciate all help.
function flatten(nested: set<set<int>>) : set<int>
{ set x | forall y :: y in nested && x in y :: x }
Perhaps the following will do what you want:
function flatten(nested: set<set<int>>) : set<int>
{
set x, y | y in nested && x in y :: x
}
Your definition is quite different. It says something along the lines of "the set of elements such that for all y at all of type set<int>, y is in nested and x is in y." This is typically false (and thus useless) because it requires that nested be a finite set that contains all sets of type set<int>.
Finally, also note that you can get the cardinality of a set S using the expression |S|.
I know that OCaml provide the let rec ... and ... for definition of mutually recursive function. Why I can't use that expression for define mutually recursive value?
In particular, why I can't do something like let rec x=3 and y=x+5 in x but I can do let rec x=3 and y=[x;4] in y?
For the first case, I've try to give me an answer and I think that is a binding "problem", since the binding of the values should be simultaneous, so y can't know the value of x so I can't add it to the value of the constant 5.
It is true?
Neither of your definitions are mutually recursive. You could just as well write them like this:
let x = 3 in
let y = x + 5 in
x
and
let x = 3 in
let y = [x; 4] in
y
Mutually recursive definitions would look like this:
let rec x = y + 3
and y = x + 5 in
x
and
let rec x = 3 :: y
and y = 4:: x in
x
In the second piece of code x is a cyclic list that contains a 3 followed by a 4 and then loops back to the beginning. However the first piece of code doesn't make any sense. How can x equal y + 3 when y equals x + 5? It can't and therefore recursive values can only be defined using constructors of variant types (because that's the only case where a recursive value would not lead to infinite recursion).
So since recursive values can't be defined without constructors and the let rec ... and syntax is not necessary when the value you're trying to define is not recursive, the syntax simply can not be used with anything but constructor applications.
I have 2 formulas F1 and F2. These two formulas share most variables, except some 'temporary' (or I call them 'free') variables having different names, that are there for some reasons.
Now I want to prove F1 == F2, but prove() method of Z3 always takes into account all the variables. How can I tell prove() to ignore those 'free' variables, and focuses only on a list of variables I really care about?
I mean with all the same input to the list of my variables, if at the output time, F1 and F2 have the same value of all these variables (regardless the values of 'free' variables), then I consider them 'equivalence'
I believe this problem has been solved in other researches before, but I dont know where to look for the information.
Thanks so much.
We can use existential quantifiers to capture 'temporary'/'free' variables.
For example, in the following example, the formulas F and G are not equivalent.
x, y, z, w = Ints('x y z w')
F = And(x >= y, y >= z)
G = And(x > z - 1, w < z)
prove(F == G)
The script will produce the counterexample [z = 0, y = -1, x = 0, w = -1].
If we consider y and w as 'temporary' variables, we may try to prove:
prove(Exists([y], F) == Exists([w], G))
Now, Z3 will return proved. Z3 is essentially showing that for all x and z, there is a y that makes F true if and only if there is a w that makes G true.
Here is the full example.
Remark: when we add quantifiers, we are making the problem much harder for Z3. It may return unknown for problems containing quantifiers.
Apparently, I cannot comment, so I have to add another answer. The process of "disregarding" certain variables is typically called "projection" or "forgetting". I am not familiar with it in contexts going beyond propositional logic, but if direct existential quantification is possible (which Leo described), it is conceptually the simplest way to do it.