I have 2 functions, all is for checking how many values that are the same values and same index in 2 sequences, example:
requires there's no duplicates in the sequence
s:= [1,3,2,5,6]
u:= [2,3,4,5,1]
==> bullspec(s,u) = 2
So both my 2 functions return the right value but the assertion of one is true, other is false
Here are my 2 functions:
function bullspec(s:seq<nat>, u:seq<nat>): nat
requires 0 < |s| <= 10
requires 0 < |u| <= 10
requires |s| <= |u|
// Remove duplicates
requires forall i, j | 0 <= i < |s| && 0 <= j < |s| && i != j :: s[i] != s[j] && s[i] <= 10
requires forall i, j | 0 <= i < |u| && 0 <= j < |u| && i != j :: u[i] != u[j] && u[i] <= 10
{
if |s| == 1 then (
if s[0] in u && s[0] == u[0]
then 1 else 0
) else (
if s[|s|-1] in u && s[|s|-1]==u[|s|-1]
then (1 + bullspec(s[..|s|-1], u))
else bullspec(s[..|s|-1],u)
)
}
and
function bullspec2(s:seq<nat>, u:seq<nat>): nat
requires 0 < |s| <= 10
requires 0 < |u| <= 10
requires |s| <= |u|
// Remove duplicates
requires forall i, j | 0 <= i < |s| && 0 <= j < |s| && i != j :: s[i] != s[j] && s[i] <= 10
requires forall i, j | 0 <= i < |u| && 0 <= j < |u| && i != j :: u[i] != u[j] && u[i] <= 10
{
if |s| == 1 then (
if s[0] in u && s[0] == u[0]
then 1 else 0
) else (
if s[0] in u && s[0] == u[0]
then (1 + bullspec2(s[1..], u))
else bullspec2(s[1..], u)
)
}
I have a method Main below:
method Main()
{
var sys:seq<nat> := [4,2,9,3,1];
var usr:seq<nat> := [1,2,3,4,5];
assert bullspec(sys, usr) == 1; //Assertion might not hold
assert bullspec2(sys, usr) == 1; //This is good
}
The difference between 2 functions is the loop recusive, one start from the beginning, other start from the end, and somehow the backward make assertion works well
I try to write some ensures statements but there's no working.
First, please be aware that you are using a static analyzer, not a run-time tester. So the assertion might hold at run-time, but the static analyzer can't prove it.
The fact that the static analyzer can prove the second one is pretty astounding already. But I would always advise you switch the order of assertions, because an assertion after a first unproven one is always proved with the condition that the unproven one is true. In your case, it's still bullspec that can't be resolved, no matter what.
The reason why it currently fail to verify is that the axiom that indirectly serves at evaluating a sequence's length in the presence of a sequence literal without consuming fuel is not implemented yet. See this similar issue. That means that, for your second example, "evaluating" the function using axioms does not consume "fuel" (I'll go back to that later), but for the first failing example, it cannot unroll the function enough to do the computation.
What you can do for now is:
Create a lemma and prove it (hard)
lemma bullspec2equalsBullspec(s:seq<nat>, u:seq<nat>): nat
ensures bullspec2(sys, usr) == bullspec(sys, usr)
{
// TODO
}
and then write:
assert bullspec2(sys, usr) == 1;
assert bullspec(sys, usr) == 1 by {
bullspec2equalsBullspec(sys, usr);
}
Pass the sequence's length as a ghost parameter in bullspec
function bullspec(s:seq<nat>, u:seq<nat>, length: nat): nat
requires |s| == length
requires 0 < |s| <= 10
requires 0 < |u| <= 10
requires |s| <= |u|
// Remove duplicates
requires forall i, j | 0 <= i < |s| && 0 <= j < |s| && i != j :: s[i] != s[j] && s[i] <= 10
requires forall i, j | 0 <= i < |u| && 0 <= j < |u| && i != j :: u[i] != u[j] && u[i] <= 10
{
if length == 1 then (
if s[0] in u && s[0] == u[0]
then 1 else 0
) else (
if s[length-1] in u && s[length-1]==u[length-1]
then (1 + bullspec(s[..length-1], u,length-1))
else bullspec(s[..length-1],u,length-1)
)
}
/// ...
method Main()
{
var sys:seq<nat> := [4,2,9,3,1];
var usr:seq<nat> := [1,2,3,4,5];
assert bullspec2(sys, usr) == 1; //This is good
assert bullspec(sys, usr, 5) == 1; //This is good
}
verifies because now it can unroll the function applied to literals without fuel.
Unroll bullspec by verification debugging to see where it blocks.
If this assertion should hold, what should hold before? You can unroll the function's definition and assert intermediate results. If you assert something non-trivial that Dafny can finally prove, all the rest will be proven. I unrolled the function for 3 steps only.
method Main()
{
var sys:seq<nat> := [4,2,9,3,1];
var usr:seq<nat> := [1,2,3,4,5];
assert bullspec2(sys, usr) == 1; //This is good
var sys1 := sys[..|sys|-1];
var sys2 := sys1[..|sys1|-1];
var sys3 := sys2[..|sys2|-1];
var sys4 := sys3[..|sys3|-1];
var sys5 := sys4[..|sys4|-1];
assert bullspec(sys3, usr) == 1;
assert bullspec(sys2, usr) == 1;
assert bullspec(sys1, usr) == 1;
assert bullspec(sys, usr) == 1; //Assertion might not hold
}
Give more fuel to your function (best in your case)
By just changing the definition of your function, you can give it more fuel for the verifier to instantiate it. For your case, a fuel of 3 is sufficient.
function {:fuel 10} bullspec(s:seq<nat>, u:seq<nat>): nat
Is there a better way to perform this logic in one line?
- (BOOL)isValueInRange {
return ((level.integerValue > 100) || (level.integerValue < 0)) ? NO : YES;
}
You can do:
return level.integerValue >= 0 && level.integerValue <= 100;
This will return true if the value is in the range, false if it is not.
I don't think you can escape having to repeat level.integerValue twice.
return !((level.integerValue > 100) || (level.integerValue < 0))
You can also use NSLocationInRange:
NSLocationInRange(level.integerValue, NSMakeRange(0, 100)
Im trying to make a while loop that checks to see if a user inputted character is correct. If the character is incorrect, the loop is supposed to run until it is. However, when i enter this loop I cannot exit, even if i input the correct value. Any help would be appreciated!
if (userInputCheck == 'U' || userInputCheck == 'D' || userInputCheck == 'R' || userInputCheck == 'L'){
return userInputCheck;
}
else
while(userInputCheck != 'U' || userInputCheck != 'D' || userInputCheck != 'R' || userInputCheck != 'L'){
System.out.println("ERROR. Please enter U for up, D for down, R for right, or L for left");
String temp = keyboard.next();
userInputCheck = temp.charAt(0);
}
return userInputCheck;
A test like x != 'U' || x != 'D' will ALWAYS be true -- think about it. If the chracter entered is U the first test will be false, but the second will be true, so the whole thing will be true. You want use && instead of ||:
while(userInputCheck != 'U' && userInputCheck != 'D' && ...
Once you do this, there's also no need for the first if...
So I have a bunch of input textfields to calculate some stuff. These are doubles. I want that every time its not all filled in, it will display "Please enter all values" Below mentioned code does this for all fields, except the last one, here nitrogen. If i change them around to make another variable last this does not work. Instead it just makes the app give the result when the last field is entered.
So for example, no fields got a value, but when I type something into nitrogen it gives me the result. If I type something else into any of the other fields (Nitrogen blank) i get the correct message "Please enter all values."
How do I make it account for all fields, not just all except the last one?
if (temprature,methane,ethane,propane,nbutane,ibutane,oxygen,npetane,ipetane,nhexane,nitrogen == 0)
{
outputText.text = #"Please enter all values";
} else
{
outputText.text = resultString;
}
Try this, this should work if any of the fields are empty.
if (temprature == 0 || methane == 0 || ethane == 0 || propane == 0 || nbutane == 0 || ibutane == 0 || oxygen == 0 || npetane == 0 || ipetane == 0 || nhexane == 0 || nitrogen == 0)
{
outputText.text = #"Please enter all values";
} else
{
outputText.text = resultString;
}
I wrote this:
if( a == -11 && b == -1 ){
{
if( a == -1) AND ( b == -1)...
But neither work, and I have the same problem with OR. How do I write expressions that include OR or AND?
You use && for “and”, and || for “or”.
(a == -11 && b == -1) is fine and correct. Objective-C uses all of the same logical operators as C. || is the logical-or operator.
if (a==-11 && b==-1) {
if perfectly legal in C, and therefore Objective-C.
Your second example is not C or Objective-C