Axiomatic Semantics - How to calculate a weakest precondition - semantics

Here is example:
x = y + 1;
y = y - 2;
{y < 3}
What is weakest precondition of this example?
I think maybe y < 3 is an answer.
If not, can you tell me why, in detail?

Here is my first mistaken attempt at an answer based on a quick read of Predicate transformer semantics
WP( x := y + 1; y := y - 2, y < 3 ) # Initial problem
= WP( x := y + 1, WP( y := y - 2, y < 3 ) ) # Sequence rule
= WP( x := y + 1, y < 5 ) # Assignment rule
= WP( x - 1 = y, y < 5 ) # solve for y <--- this is wrong!
= WP( x - 1 < 5 ) # Assignment rule
= x < 6 # solve for x
However as pointed out by Kris since x := y + 1 is an assignment to x which doesn't affect y the weakest precondition for y should just be y < 5 so the correct answer should be
WP( x := y + 1; y := y - 2, y < 3 ) # Initial problem
= WP( x := y + 1, WP( y := y - 2, y < 3 ) ) # Sequence rule
= WP( x := y + 1, y < 5 ) # Assignment rule
= y < 5
Thanks also to philipxy for identifying errors in my syntax especially := vs = since that made it easier to mistake assignments for equations which was part of my initial confusion.

Related

Modelling if-then-else-logic in MILP/MIP

I would like to model the following for a mixed-integer linear programming problem:
Let y be a binary and x1 and x2 be continuous variables, whereas k1 is an invariant parameter.
if y == 1 then:
x2 = k1*x1
else (y == 0):
x2 = 0
First idea that comes to mind is to do something like:
x2 >= k1*x1 - M*(1-y)
x2 <= k1*x1 - M*(1-y)
But here M would have to be k1*x1 and is therefore not an invariant parameter anymore. Does anyone have a better idea. Thank you!
Per your problem :
y : binary_variable
x1 : continous_variable
x2 : continous_variable
Please see equations below:
x2 <= u*y
x2 <= k1*x1
x2 >= k1*x1 − u*(1 − y)
x2 >= 0
u is the upper bound on k1*x1
0 <= k1*x1 <= u
you don't require a big M over here.
when y == 1 => x2 == k1*x1
when y == 0 => x2 == 0

Google Cloud BigQuery

I have a set of data (x, y) where x = 1 to 5 , y = 1 to 10
e.g. extract from them one by one where (1,1),(1,2),(1,3)…(1,10)…(2,5)…(5,10)
BEGIN
DECLARE
x,y INT64 DEFAULT 0;
LOOP
SET
x = x + 1;
IF
x <= Max(x) THEN
LOOP
SET
y = y + 1;
IF
y <= Max(y) THEN
CALL
data(x,y);
ELSE
BREAK;
END IF;
END LOOP;
END IF;
END LOOP;
END
Does anyone help me ?
I think CROSS JOIN with GENERATE_ARRAY will works better for you
SELECT * FROM UNNEST(GENERATE_ARRAY(1,5)) x, UNNEST(GENERATE_ARRAY(1,10)) y
Is it?

Simulate data for repeated binary measures

I can generate a binary variable y as follows:
clear
set more off
gen y =.
replace y = rbinomial(1, .5)
How can I generate n variables y_1, y_2, ..., y_n with a correlation of rho?
This is #pjs's solution in Stata for generating pairs of variables:
clear
set obs 100
set seed 12345
generate x = rbinomial(1, 0.7)
generate y = rbinomial(1, 0.7 + 0.2 * (1 - 0.7)) if x == 1
replace y = rbinomial(1, 0.7 * (1 - 0.2)) if x != 1
summarize x y
Variable | Obs Mean Std. Dev. Min Max
-------------+---------------------------------------------------------
x | 100 .72 .4512609 0 1
y | 100 .67 .4725816 0 1
correlate x y
(obs=100)
| x y
-------------+------------------
x | 1.0000
y | 0.1781 1.0000
And a simulation:
set seed 12345
tempname sim1
tempfile mcresults
postfile `sim1' mu_x mu_y rho using `mcresults', replace
forvalues i = 1 / 100000 {
quietly {
clear
set obs 100
generate x = rbinomial(1, 0.7)
generate y = rbinomial(1, 0.7 + 0.2 * (1 - 0.7)) if x == 1
replace y = rbinomial(1, 0.7 * (1 - 0.2)) if x != 1
summarize x, meanonly
scalar mean_x = r(mean)
summarize y, meanonly
scalar mean_y = r(mean)
corr x y
scalar rho = r(rho)
post `sim1' (mean_x) (mean_y) (rho)
}
}
postclose `sim1'
use `mcresults', clear
summarize *
Variable | Obs Mean Std. Dev. Min Max
-------------+---------------------------------------------------------
mu_x | 100,000 .7000379 .0459078 .47 .89
mu_y | 100,000 .6999094 .0456385 .49 .88
rho | 100,000 .1993097 .1042207 -.2578483 .6294388
Note that in this example I use p = 0.7 and rho = 0.2 instead.
This is #pjs's solution in Stata for generating a time-series:
clear
set seed 12345
set obs 1
local p = 0.7
local rho = 0.5
generate y = runiform()
if y <= `p' replace y = 1
else replace y = 0
forvalues i = 1 / 99999 {
set obs `= _N + 1'
local rnd = runiform()
if y[`i'] == 1 {
if `rnd' <= `p' + `rho' * (1 - `p') replace y = 1 in `= `i' + 1'
else replace y = 0 in `= `i' + 1'
}
else {
if `rnd' <= `p' * (1 - `rho') replace y = 1 in `= `i' + 1'
else replace y = 0 in `= `i' + 1'
}
}
Results:
summarize y
Variable | Obs Mean Std. Dev. Min Max
-------------+---------------------------------------------------------
y | 100,000 .70078 .4579186 0 1
generate id = _n
tsset id
corrgram y, lags(5)
-1 0 1 -1 0 1
LAG AC PAC Q Prob>Q [Autocorrelation] [Partial Autocor]
-------------------------------------------------------------------------------
1 0.5036 0.5036 25366 0.0000 |---- |----
2 0.2567 0.0041 31955 0.0000 |-- |
3 0.1273 -0.0047 33576 0.0000 |- |
4 0.0572 -0.0080 33903 0.0000 | |
5 0.0277 0.0032 33980 0.0000 | |
Correlation is a pairwise measure, so I'm assuming that when you talk about binary (Bernoulli) values Y1,...,Yn having a correlation of rho you're viewing them as a time series Yi: i = 1,...,n, of Bernoulli values having a common mean p, variance p*(1-p), and a lag 1 correlation of rho.
I was able to work it out using the definition of correlation and conditional probability. Given it was a bunch of tedious algebra and stackoverflow doesn't do math gracefully, I'm jumping straight to the result, expressed in pseudocode:
if Y[i] == 1:
generate Y[i+1] as Bernoulli(p + rho * (1 - p))
else:
generate Y[i+1] as Bernoulli(p * (1 - rho))
As a sanity check you can see that if rho = 0 it just generates Bernoulli(p)'s, regardless of the prior value. As you already noted in your question, Bernoulli RVs are binomials with n = 1.
This works for all 0 <= rho, p <= 1. For negative correlations, there are constraints on the relative magnitudes of p and rho so that the parameters of the Bernoullis are always between 0 and 1.
You can analytically check the conditional probabilities to confirm correctness. I don't use Stata, but I tested this pretty thoroughly in the JMP statistical software and it works like a charm.
IMPLEMENTATION (Python)
import random
def Bernoulli(p):
return 1 if random.random() <= p else 0 # yields 1 w/ prob p, 0 otherwise
N = 100000
p = 0.7
rho = 0.5
last_y = Bernoulli(p)
for _ in range(N):
if last_y == 1:
last_y = Bernoulli(p + rho * (1 - p))
else:
last_y = Bernoulli(p * (1 - rho))
print(last_y)
I ran this and redirected the results to a file, then imported the file into JMP. Analyzing it as a time series produced:
The sample mean was 0.69834, with a standard deviation of 0.4589785 [upper right of the figure]. The lag-1 estimates for autocorrelation and partial correlation are 0.5011 [bottom left and right, respectively]. These estimated values are all excellent matches to a Bernoulli(0.7) with rho = 0.5, as specified in the demo program.
If the goal is instead to produce (X,Y) pairs with the specified correlation, revise the loop to:
for _ in range(N):
x = Bernoulli(p)
if x == 1:
y = Bernoulli(p + rho * (1 - p))
else:
y = Bernoulli(p * (1 - rho))
print(x, y)

what to do with fraction as index number

given these inputs x = 4, S = [1 2 3 4 5 6 7 8 9 10], and n = 10
search (x,S,n) {
i = 1
j = n
while i < j {
m = [(i+j)/2]
if x > Sm then i=n+1
else j = m
end
if x = Si then location = i
else location = 0
This code is not from any particular language its just from my discrete math hw, but I'm confused as to what Sm would equal on the first iteration because m would be 11/2. If i use a fraction as the index do I round down? Is there a general rule for this? Am I making any sense? Help pls

VB.NET - Grouping statements on one line

I want to put several statements on one line, including conditional statements that need to be grouped together.
I can do this:
x += 20 : y += 10 : If x > 400 Then x = 0
I want to have more than one statement under 'if'. It balks when I try to do this:
x += 20 : y += 10 : (If x > 400 Then x = 0 : y = 0)
or this:
x += 20 : y += 10 : If x > 400 Then (x = 0 : y = 0)
Is there a way?
x += 20 : y += 10 : If x > 400 Then x = 0 : y = 0
But I wouldn't recommend putting it on one line. It's a bit nasty to readability.