I have proved some purely existential lemmas (with no out-results) in a similar constructive way to this one:
https://rise4fun.com/Dafny/Wvly
lemma DivModExistsUnique_Lemma (x:nat, y:nat)
requires y != 0
ensures exists q:nat, r:nat :: x == y*q + r && r < y
{
var q:nat, r:nat := 0, x;
while r >= y
invariant x == y*q + r
{
q := q + 1;
r := r - y;
}
assert x == y*q + r && r < y;
}
I can’t think why this post-condition is not inferred from the last assertion in the proof.
There is some additional hint that can be given to Dafny?
Nice proof! The problem is that the quantifier in the postcondition has no "matching pattern" (also known as "trigger") that involves r. Dafny gives a warning about this. So what does that mean?
To prove an existential quantifier, the verifier attempts to find a witness. In searching for a witness, the verifier is not going to try every possible term in mathematics, and it's not even going to try every term that appears elsewhere in your program. Instead, the verifier limits its attention to terms that both appear elsewhere in the proof context and have the shape of a "matching pattern" for the quantifier. In the Dafny IDE (VS Code or Emacs), you can place the cursor over the quantifier and the IDE will show you the triggers that Dafny selected. (Again, in your case, it will instead say "No triggers".)
There are certain rules about what triggers can and cannot be (see the Dafny FAQ or many answered questions on StackOverflow). For q, the verifier will select the term y*q as the trigger. It is allowed, because Dafny allows * to appear in triggers. However, the only possibly useful triggers for r would be ... + r and r < ..., neither of which is allowed because triggers are not allowed to mention + or <. Therefore, Dafny finds no trigger for the quantifier, which essentially means that it will never find witnesses that prove the existential quantifier.
To work around this problem, you can introduce a function that involves the quantified variables. For example,
function MulAdd(a: nat, b: nat, c: nat): nat {
a*b + c
}
lemma DivModExistsUnique_Lemma(x:nat, y:nat)
requires y != 0
ensures exists q:nat, r:nat :: x == MulAdd(y, q, r) && r < y
{
var q:nat, r:nat := 0, x;
while r >= y
invariant x == MulAdd(y, q, r)
{
q := q + 1;
r := r - y;
}
}
will prove your program. The IDE will then also show you that Mul(y, q, r) is selected as a trigger.
Quantifiers without triggers tend to be ones that only use "built-in symbols" like + and < and &&. When your problems have other functions, the verifier can usually find triggers.
For your proof, the most elegant solution to my taste is to use lemma out-parameters. That means the lemma can just "return" the q and r it computes. It also makes the lemma easier to use, because the caller of the lemma would otherwise typically need to Skolemize the quantifier (which you do in Dafny with the assign-such-that operator :| -- which also involves triggers, by the way). But you said you're (for some reason) trying to avoid out-parameters. If so, then the MulAdd function will do the trick.
Related
I have an expression whose outcome is a real number, but is composed of imaginary terms (that cancel one another). A significantly more simple example than the one I am considering would be something like,
z = a + 1/[sqrt(a-b) - a] - f[sqrt(a-b)] = a
where a and b are real numbers and f is some function that statisfies the above expression. It would not surprise you that in some cases, say for b > a (which does not always occur, but could occur in some cases), the above expression returns nan, since some of its terms are imaginary.
Sometimes, it is possible to work out the algebra and write out this not-really-complex expression using real numbers only. However, in my case, the algebra is very messy (so messy that even Matlab's symbolic package and Mathematica are unable to trivially simplify).
I am wondering if there is some other way to work out expressions you know to be real, but are partly imaginary.
PS: not important for this question, but for more info about the expression I am dealing with, please see another question I previously asked.
tl;dr for the comment thread:
If you know you're doing something that will involve imaginary numbers, just use std::complex.
You can't avoid getting NaN if you insist on asking for a real result to something (sqrt, say) that you know will have an imaginary component. There is no real answer it can give you.
At the end of your computation, if imag(result) is zero (or within a suitable epsilon), then your imaginary parts cancelled out and you have a real(result).
As a concrete example:
#include <complex>
#include <iostream>
int main()
{
std::complex<double> a{-5, 0}; // -5 + 0i
std::complex<double> b{ 5, 0}; // +5 + 0i
auto z = b + sqrt(a) - sqrt(a);
std::cout << "z = " << real(z) << " + " << imag(z) << "i\n";
}
prints
z = 5 + 0i
With your new example
z = a + 1/(sqrt(a-b) - a) - f(sqrt(a-b)) = a
it'll be useful to make a of type std::complex in the first place, and to use a complex 1+0i for the numerator as well. This is because of the way overloaded operators are resolved:
using cx = std::complex<double>;
cx f(cx); // whatever this does, it also needs to handle complex inputs
cx foo(cx a, cx b)
{
return a + cx{1}/(sqrt(a-b) - a) - f(sqrt(a-b));
}
auto
I'd like to understand what's wrong with this simple exercise.
let even n = (n % 2) = 0
let rec even_sqr (n:nat {even n}) : Lemma (even (n * n)) =
match n with
| 0 -> ()
| _ -> even_sqr (n - 2)
FStar returns '(Error) Unknown assertion failed'.
An "Unknown assertion failed" error means that Z3 did not give F* any reason for the proof failing. Usually, this is either evidence for the need for a more detailed proof, or that the statement is false. In this particular case, the statement is true, it is just that Z3 is not great at non-linear arithmetic (and this example combines both multiplication and modulo operators).
In such a case, some small amount of hand-holding helps. You can do this by adding some assertions that might help point it in the right direction.
In this particular case, I added a new assertion that expands n*n in terms of n-2, and the proof then goes through:
let rec even_sqr (n:nat {even n}) : Lemma (even (n * n)) =
match n with
| 0 -> ()
| _ ->
assert (n * n == (n - 2) * (n - 2) + 4 * n - 4); (* OBSERVE *)
even_sqr (n - 2)
Notice that I am not adding any complex proofs, but merely surfacing some properties that might be helpful for the solver to go along. Sometimes with non-linear proofs, however, this may not be enough, and you may require writing a few lemmas, at which point, a good resource is FStar.Math.Lemmas in the standard library.
In my tool, I use conditions that compare constants to integer variables (for example y < 100). Often, there are multiple conditions for one variable and I want to simplify those cases. For example: y < 100 && y != 99 should become y < 99. The simplify tactic does not do this and none of the arguments for simplify sound like they can help.
In Code:
context c;
goal g(c);
expr x = c.int_const("x");
expr y = c.int_const("y");
solver s(c);
expr F = y < 100 && y != 99;
g.add(F);
tactic t = tactic(c, "simplify");
apply_result r = t(g);
for (unsigned i = 0; i < r.size(); i++) {
std::cout << "subgoal " << i << "\n" << r[i] << "\n";
}
The output in the end returns: subgoal 0
(goal
(not (<= 100 y))
(not (= y 99)))
and not subgoal 0(goal(not(<= 99 y)) or something similar as I want it to be.
Therefore I want to implement my own simplify tactic. Unfortunately I cannot find how to do this. I am aware, that the tactic needs to be implemented in C++, but how can I introduce my tactic to Z3?
The Z3 tactics are stored in the directory: src/tactic. The arithmetic related tactics are in the subdirectory arith. You should use an existing tactic as a "template" for implementing your tactic.
A good example is
https://z3.codeplex.com/SourceControl/latest#src/tactic/arith/normalize_bounds_tactic.cpp
To make the new tactic available in the API and SMT 2.0 front-end, we have to include a comment containing a ADD_TACTIC command. This command instructs the Z3 mk_make script to glue everything together. The arguments are: name of the tactic, description, and C++ code for creating the tactic.
/*
ADD_TACTIC("normalize-bounds",
"replace a variable x with lower bound k <= x with x' = x - k.",
"mk_normalize_bounds_tactic(m, p)")
*/
BTW, you may also try to implement the new feature by extending an existing tactic such as:
https://z3.codeplex.com/SourceControl/latest#src/tactic/arith/propagate_ineqs_tactic.cpp
I'm new to OpenModelica and I've a few questions regarding the code of 'BouncingBall.mo' which is distributed with the software as example code.
1) what's the difference between 'when' and 'if'?
2)what's the purpose of variable 'foo' in the code?
3)in line(15) - "when {h <= 0.0 and v <= 0.0,impact}",, shouldn't the expression for 'when' be enough as "{h <= 0.0 and v <= 0.0}" because this becomes TRUE when impact occurs, what's the purpose of impact(to me its redundant here) and what does the comma(,) before impact means?
model BouncingBall
parameter Real e = 0.7 "coefficient of restitution";
parameter Real g = 9.81 "gravity acceleration";
Real h(start = 1) "height of ball";
Real v "velocity of ball";
Boolean flying(start = true) "true, if ball is flying";
Boolean impact;
Real v_new;
Integer foo;
equation
impact = h <= 0.0;
foo = if impact then 1 else 2;
der(v) = if flying then -g else 0;
der(h) = v;
when {h <= 0.0 and v <= 0.0,impact} then
v_new = if edge(impact) then -e * pre(v) else 0;
flying = v_new > 0;
reinit(v, v_new);
end when;
end BouncingBall;
OK, that's quite a few questions. Let me attempt to answer them:
What is the difference between when and if.
The questions inside a when clause are only "active" at the instant that the conditional expressions used in the when clause becomes active. In contrast, equations inside an if statement are true as long as the conditional expression stays true.
What's the purpose of foo?
Probably for visualization. It has no clear impact on the model that I can see.
Why is impact listed in the when clause.
One of the problems you have so-called Zeno systems like this is that it will continue to bounce indefinitely with smaller and smaller intervals. I suspect the impact flag here is meant to indicate when the system has stopped bouncing. This is normally done by checking to make sure that the conditional expression h<=0.0 actually becomes false at some point. Because event detection includes numerical tolerancing, at some point the height of the bounces never gets outside of the tolerance range and you need to detect this or the ball never bounces again and just continues to fall. (it's hard to explain without actually running the simulation and seeing the effect).
What does the , do in the when clause.
Consider the following: when {a, b} then. The thing is, if you want to have a when clause trigger when either a or b become true, you might think you'll write it as when a or b then. But that's not correct because that will only trigger when the first one becomes true. To see this better, consider this code:
a = time>1.0;
b = time>2.0;
when {a, b} then
// Equation set 1
end when;
when a or b then
// Equation set 2
end when;
So equation set 1 will get executed twice here because it will get executed when a becomes true and then again when b becomes true. But equation set 2 will only get executed once when a becomes true. That's because the whole expression a or b only becomes true at one instant.
These are common points of confusion about when. Hopefully these explanations help.
What would be the most efficient algorithm to solve a linear equation in one variable given as a string input to a function? For example, for input string:
"x + 9 – 2 - 4 + x = – x + 5 – 1 + 3 – x"
The output should be 1.
I am considering using a stack and pushing each string token onto it as I encounter spaces in the string. If the input was in polish notation then it would have been easier to pop numbers off the stack to get to a result, but I am not sure what approach to take here.
It is an interview question.
Solving the linear equation is (I hope) extremely easy for you once you've worked out the coefficients a and b in the equation a * x + b = 0.
So, the difficult part of the problem is parsing the expression and "evaluating" it to find the coefficients. Your example expression is extremely simple, it uses only the operators unary -, binary -, binary +. And =, which you could handle specially.
It is not clear from the question whether the solution should also handle expressions involving binary * and /, or parentheses. I'm wondering whether the interview question is intended:
to make you write some simple code, or
to make you ask what the real scope of the problem is before you write anything.
Both are important skills :-)
It could even be that the question is intended:
to separate those with lots of experience writing parsers (who will solve it as fast as they can write/type) from those with none (who might struggle to solve it at all within a few minutes, at least without some hints).
Anyway, to allow for future more complicated requirements, there are two common approaches to parsing arithmetic expressions: recursive descent or Dijkstra's shunting-yard algorithm. You can look these up, and if you only need the simple expressions in version 1.0 then you can use a simplified form of Dijkstra's algorithm. Then once you've parsed the expression, you need to evaluate it: use values that are linear expressions in x and interpret = as an operator with lowest possible precedence that means "subtract". The result is a linear expression in x that is equal to 0.
If you don't need complicated expressions then you can evaluate that simple example pretty much directly from left-to-right once you've tokenised it[*]:
x
x + 9
// set the "we've found minus sign" bit to negate the first thing that follows
x + 7 // and clear the negative bit
x + 3
2 * x + 3
// set the "we've found the equals sign" bit to negate everything that follows
3 * x + 3
3 * x - 2
3 * x - 1
3 * x - 4
4 * x - 4
Finally, solve a * x + b = 0 as x = - b/a.
[*] example tokenisation code, in Python:
acc = None
for idx, ch in enumerate(input):
if ch in '1234567890':
if acc is None: acc = 0
acc = 10 * acc + int(ch)
continue
if acc != None:
yield acc
acc = None
if ch in '+-=x':
yield ch
elif ch == ' ':
pass
else:
raise ValueError('illegal character "%s" at %d' % (ch, idx))
Alternative example tokenisation code, also in Python, assuming there will always be spaces between tokens as in the example. This leaves token validation to the parser:
return input.split()
ok some simple psuedo code that you could use to solve this problem
function(stinrgToParse){
arrayoftokens = stringToParse.match(RegexMatching);
foreach(arrayoftokens as token)
{
//now step through the tokens and determine what they are
//and store the neccesary information.
}
//Use the above information to do the arithmetic.
//count the number of times a variable appears positive and negative
//do the arithmetic.
//add up the numbers both positive and negative.
//return the result.
}
The first thing is to parse the string, to identify the various tokens (numbers, variables and operators), so that an expression tree can be formed by giving operator proper precedences.
Regular expressions can help, but that's not the only method (grammar parsers like boost::spirit are good too, and you can even run your own: its all a "find and recourse").
The tree can then be manipulated reducing the nodes executing those operation that deals with constants and by grouping variables related operations, executing them accordingly.
This goes on recursively until you remain with a variable related node and a constant node.
At the point the solution is calculated trivially.
They are basically the same principles that leads to the production of an interpreter or a compiler.
Consider:
from operator import add, sub
def ab(expr):
a, b, op = 0, 0, add
for t in expr.split():
if t == '+': op = add
elif t == '-': op = sub
elif t == 'x': a = op(a, 1)
else : b = op(b, int(t))
return a, b
Given an expression like 1 + x - 2 - x... this converts it to a canonical form ax+b and returns a pair of coefficients (a,b).
Now, let's obtain the coefficients from both parts of the equation:
le, ri = equation.split('=')
a1, b1 = ab(le)
a2, b2 = ab(ri)
and finally solve the trivial equation a1*x + b1 = a2*x + b2:
x = (b2 - b1) / (a1 - a2)
Of course, this only solves this particular example, without operator precedence or parentheses. To support the latter you'll need a parser, presumable a recursive descent one, which would be simper to code by hand.