axiomantic semantic..what are the weakest preconditon? - semantics

i was studying axiomantic semantic which is really pain in my ass. everything was so far great untill i met these questions. i was stuck at the 2 Question which has 'and' in the postcondition.
what are the weakest precondition?
1)
if (x > y)
c = x * 2 + 4
else
a = x + 4;
{a > 4 and c < 6}
2)if (x > y)
e = x * 2 + 4
else
f = x + 5;
{f > 4 and e > 6}
i've never seen postcondition with the 'and' , it was pretty confusing.
because when i tried to figure out the first one
(precondition for if)
a>4 and 2x+4<6
a>4 and 2x<2
a>4 and x<1
(pre condtion for else)
x+4 >4 and c<6
x>0 and c<6
i couldn't apply the rule of consequence because there are three variables and x has different direction of comparison symbol , which is hard to figure out which one is the stronger one, or weaker.
can anyone help this poor computer noob :( ?

Related

How to convert the following if conditions to Linear integer programming constraints?

These are the conditions:
if(x > 0)
{
y >= a;
z <= b;
}
It is quite easy to convert the conditions into Linear Programming constraints if x were binary variable. But I am not finding a way to do this.
You can do this in 2 steps
Step 1: Introduce a binary dummy variable
Since x is continuous, we can introduce a binary 0/1 dummy variable. Let's call it x_positive
if x>0 then we want x_positive =1. We can achieve that via the following constraint, where M is a very large number.
x < x_positive * M
Note that this forces x_positive to become 1, if x is itself positive. If x is negative, x_positive can be anything. (We can force it to be zero by adding it to the objective function with a tiny penalty of the appropriate sign.)
Step 2: Use the dummy variable to implement the next 2 constraints
In English: if x_positive = 1, then y >= a
However, if x_positive = 0, y can be anything (y > -inf)
y > a - M (1 - x_positive)
Similarly,
if x_positive = 1, then z <= b
z <= b + M * (1 - x_positive)
Both the linear constraints above will kick in if x>0 and will be trivially satisfied if x <=0.

Prolog: how to optimize this code(Solving 123456789=100 puzzle)

So there was a puzzle:
This equation is incomplete: 1 2 3 4 5 6 7 8 9 = 100. One way to make
it accurate is by adding seven plus and minus signs, like so: 1 + 2 +
3 – 4 + 5 + 6 + 78 + 9 = 100.
How can you do it using only 3 plus or minus signs?
I'm quite new to Prolog, solved the puzzle, but i wonder how to optimize it
makeInt(S,F,FinInt):-
getInt(S,F,0,FinInt).
getInt(Start, Finish, Acc, FinInt):-
0 =< Finish - Start,
NewAcc is Acc*10 + Start,
NewStart is Start +1,
getInt(NewStart, Finish, NewAcc, FinInt).
getInt(Start, Finish, A, A):-
0 > Finish - Start.
itCounts(X,Y,Z,Q):-
member(XLastDigit,[1,2,3,4,5,6]),
FromY is XLastDigit+1,
numlist(FromY, 7, ListYLastDigit),
member(YLastDigit, ListYLastDigit),
FromZ is YLastDigit+1,
numlist(FromZ, 8, ListZLastDigit),
member(ZLastDigit,ListZLastDigit),
FromQ is ZLastDigit+1,
member(YSign,[-1,1]),
member(ZSign,[-1,1]),
member(QSign,[-1,1]),
0 is XLastDigit + YSign*YLastDigit + ZSign*ZLastDigit + QSign*9,
makeInt(1, XLastDigit, FirstNumber),
makeInt(FromY, YLastDigit, SecondNumber),
makeInt(FromZ, ZLastDigit, ThirdNumber),
makeInt(FromQ, 9, FourthNumber),
X is FirstNumber,
Y is YSign*SecondNumber,
Z is ZSign*ThirdNumber,
Q is QSign*FourthNumber,
100 =:= X + Y + Z + Q.
Not sure this stands for an optimization. The code is just shorter:
sum_123456789_eq_100_with_3_sum_or_sub(L) :-
append([G1,G2,G3,G4], [0'1,0'2,0'3,0'4,0'5,0'6,0'7,0'8,0'9]),
maplist([X]>>(length(X,N), N>0), [G1,G2,G3,G4]),
maplist([G,F]>>(member(Op, [0'+,0'-]),F=[Op|G]), [G2,G3,G4], [F2,F3,F4]),
append([G1,F2,F3,F4], L),
read_term_from_codes(L, T, []),
100 is T.
It took me a while, but I got what your code is doing. It's something like this:
itCounts(X,Y,Z,Q) :- % generate X, Y, Z, and Q s.t. X+Y+Z+Q=100, etc.
generate X as a list of digits
do the same for Y, Z, and Q
pick the signs for Y, Z, and Q
convert all those lists of digits into numbers
verify that, with the signs, they add to 100.
The inefficiency here is that the testing is all done at the last minute. You can improve the efficiency if you can throw out some possible solutions as soon as you pick one of your numbers, that is, testing earlier.
itCounts(X,Y,Z,Q) :- % generate X, Y, Z, and Q s.t. X+Y+Z+Q=100, etc.
generate X as a list of digits, and convert it to a number
if it's so big or small the rest can't possibly bring the sum back to 100, fail
generate Y as a list of digits, convert to number, and pick it sign
if it's so big or so small the rest can't possibly bring the sum to 100, fail
do the same for Z
do the same for Q
Your function is running pretty fast already, even if I search all possible solutions. It only picks 6 X's; 42 Y's; 224 Z's; and 15 Q's. I don't think optimizing will be worth your while.
But if you really wanted to: I tested this by putting a testing function immediately after selecting an X. It reduced the 6 X's to 3 (all before finding the solution); 42 Y's to 30; 224 Z's to 184; and 15 Q's to 11. I believe we could reduce it further by testing immediately after a Y is picked, to see whether X YSign Y is already so large or small there can be no solution.
In PROLOG programs that are more computationally intensive, putting parts of the 'test' earlier in 'generate and test' algorithms can help a lot.

Prolog Program to Find Square of Natural Numbers

My code below is meant to generate the square of natural numbers in order
(i.e sq(X). -> X=0; X=1; X=4; X=9; X=16; ...)
nat(0).
nat(X) :- nat(Y), Z is Y+1, X is Z*Z.
but the answer I am getting is:
1
0 ?- nat(X).
X = 0 ;
X = 1 ;
X = 4 ;
X = 25 ;
X = 676
Should be a quick fix, but I've spent longer on this than I'd like to say. Any help is greatly appreciated!
your nat/1 really seems to return a different sequence. Should be
nat(0).
nat(X) :- nat(Y), X is Y+1.
and then, a different predicate for square
sq(X) :- % call nat/1, square it...
please complete the code

Hoare Logic, while loop with '<= '

I'm working on some Hoare logic and I am wondering whether my approach is the right one.
I have the following program P:
s = 0
i = 1
while (i <= n) {
s = s + i
i = i + 1
}
It should satisfy the hoare triple {n >= 0}P{s = n*(n+1)/2} (so it just takes the sum). Now, initially I had |s = i*(i-1)/2| as my invariant, which works fine. However, I had a problem from going to the end of my loop, to my desired postcondition. Because for the impliciation
|s = i*(i-1)/2 & i > n|
=>
| s = n * (n+1) / 2 |
to hold, I need to prove that i is n+1, and not just any i bigger than n. So what I thought of is to add a (i <= n + 1) to the invariant, so that it becomes :
|s = i * (i-1)/2 & i <= n+1|
Then I can prove the program so I think it should be correct.
Nonetheless, I find the invariant to be a bit, less "invariantly" :). And not like anything I've seen in the course or in the exercises so far, so I was wondering if there was a more elegant solution here?
So what I thought of is to add a (i <= n + 1) to the invariant, so that it becomes :
|s = i * (i-1)/2 & i <= n+1|
Nonetheless, I find the invariant to be a bit, less "invariantly" :). And not like anything I've seen in the course or in the exercises so far, so I was wondering if there was a more elegant solution here?
Nope, given the way the code is written, that's exactly the way to go. (I can tell from experience since I've been teaching Hoare logic during several semesters in two different courses and since it's part of my graduate studies.)
Using i <= n is common practice when programming. In your particular program, you could just as well have written i != n+1 instead, in which case your first invariant (which indeed looks cleaner) would have sufficed since you get
| s=i*(i-1)/2 & i=n+1 |
=>
| s=n*(n+1)/2 |
which evidently holds.
There is another way to reason,given a more appropriate invariant (and other code)...searh n for final value of i...
I : s = i*(i+1)/2 and 0 <= i <=n
B : i < n
Now,evidently you have for post condition:
I and i >= n => s = i*(i+1)/2 and i=n => s = n*(n+1)/2
The code now becomes
s = 0
i = 0
while (i < n) {
s = s + (i+1)
i = i + 1
}
The invariant holds at init and keeps after each loop,since rewriting I as 2s=i*(i+1) we have to proof
I and i<n => 2(s + (i+1)) = (i+1)*(i+2)
2(s + (i+1) )=
2s + 2(i+1) =
i*(i+1) + 2(i+1)= (since I holds)
(i+1)(i+2)
Qed.

What will be the value of i in the following pseudocode?

I got this question in a programming test. Do you think this question is even correct? Look at the answer choices. (2^x means 2 raised to x)
Consider the following pseudocode.
x := 1;
i := 1;
while (x >= 1000)
begin
x := 2^x;
i := i + 1;
end;
What is the value of i at the end of the pseudocode?
a) 4
b) 5
c) 6
d) 7
e) 8
I am sure that the value of i will 1. I told the examiner of the discrepancy and he advised me the leave the question unanswered if I felt it was incorrect. What else could I have done?
1
X < 1000, so it doesn't enter the while.
Or there is an error in the Question (and X should be <= 1000 and not >=1000)
If it's <= 1000 it should be 5:
2 - 4 - 16 - 65K
2 - 3 - 4 - 5
This question tests two things:
can you read code
can you communicate / interact
Since you asked about the discrepancy, you showed 1. to be true. I'm not so sure if you passed 2, it depends too much on the situation / expectations.
I believe I would have left a note on the answer sheet stating 'none of the given'.
Not an easy situation!
As written, the answer would be 1.
Had the test on the while been reversed (i.e. x < 1000), then the series is:
At the end of each loop iteration
i = 2, x = 2
i = 3, x = 2^2 = 4
i = 4, x = 2^4 = 16
i = 5, x = 2^16 = 65,536
So i would be 5
If I where you, I would say that it is none of the above and basically say that since x is less than 1000 when the while loop starts, the value of i is never modified. I think that it is a bad thing to leave blank answers in a quiz, it is always better to write something which you think is relevant. If you think that there is a mistake, you can always state an assumption before stating your answer, so in this case you can either say that the while loop never works, or else, you explicitly state an assumption, in this case, it would be something like "Assuming that there is a mistake in the question, and that "while (x >= 1000)" should in fact be "while (x <= 1000)"...
Then, you proceed with your working.