## Explanation for Bell's theorem modeling program

Today I will explain in detail the code from last time and show how can you change it to experiment with Bell's theorem. The code below needs only a text editor to make modifications and requires only a web browser to run. In other words, it is trivial to play with provided you understand the basics of HTML and Java Script. For elementary introductions to those topics see here and here.

In a standard HTML page we start in the body section with 3 entrees responsible to plot the graph in the end.

<body>
<script src="http://jsxgraph.uni-bayreuth.de/distrib/jsxgraphcore.js" type="text/javascript"></script>

Then we have the following HTML table

<table border="4" style="width: 50%px;">
<tr><td style="width: 25%;">
<br />
Number of experiments: <input id="totAngMom" type="text" value="100" />
<br />
Number of directions: <input id="totTestDir" type="text" value="100" />
<br />

<input onclick="clearInput();" type="button" value="Clear Data" />

<input onclick="generateRandomData();" type="button" value="Generate Shared Random Data" />
<br />

<textarea cols="65" id="in_data" rows="7">
</textarea>
<br />

<input onclick="clearTestDir();" type="button" value="Clear data" />

<input onclick="generateTestDir();" type="button" value="Generate Random Alice Bob directions (x,y,z,x,y,z)" />
<textarea cols="65" id="in_test" rows="4">
</textarea>
<br />
<input onclick="clearOutput();" type="button" value="Clear Data" />

<input onclick="generateData();" type="button" value="Generate Data from shared randomness" />
<br />
Legend: Direction index|Data index|Measurement Alice|Measurement Bob
<textarea cols="65" id="out_measurements" rows="4">
</textarea>
<input onclick="clearBoard();" type="button" value="Clear Graph" />
<input onclick="plotData();" type="button" value="Plot Data" />

</td>
</tr>
<tr>
<td>
<div class="jxgbox" id="jxgboxCorrelations" style="height: 400px; width: 550px;">
</div>

</td></tr>
</table>

and we close the body:

</body>

The brain of the page is encapsulated by script tags:

<script type="text/javascript">
</script>

which can be placed anywhere inside the HTML page. Here are the functions which are declared inside the script tags:

//Dot is the scalar product of 2 3D vectors
function Dot(a, b)
{
return a*b + a*b + a*b;
};

This simply computes the dot product of two vectors in ordinary 3D Euclidean space. As a Java Script reminder, the arrays start at index zero and go to N-1. Also in Java Script comments start with two double slash // and lines end in semicolon ;

Next there is a little utility function which computes the magnitude of a vector:

//Norm computes the norm of a 3D vector
function GetNorm(vect)
{
return Math.sqrt(Dot(vect, vect));
};

This is followed by another utility function which normalizes a vector:

//Normalize generates a unit vector out of a vector
function Normalize(vect)
{
//declares the variable
var ret = new Array(3);
//computes the norm
var norm = GetNorm(vect);

//scales the vector
ret = vect/norm;
ret = vect/norm;
ret = vect/norm;
return ret;
};

To create an random oriented vector we use the function below which first randomly generates a point in a cube of side 2, eliminated the points outside a unit sphere, and then normalizes the vector:

//RandomDirection create a 3D unit vector of random direction
function RandomDirection()
{
//declares the variable
var ret = new Array(3);

//fills a 3D cube with coordinates from -1 to 1 on each direction
ret = 2*(Math.random()-0.5);
ret = 2*(Math.random()-0.5);
ret = 2*(Math.random()-0.5);

//excludes the points outside of a unit sphere (tries again)
if(GetNorm(ret) > 1)
return RandomDirection();
return Normalize(ret);
};

The rest of the code is this:

var generateData = function()
{
clearBoard();
clearOutput();
//gets the data
var angMom = new Array();
var t = document.getElementById('in_data').value;
var data = t.split('\n');
for (var i=0;i<data.length;i++)
{
var vect = data[i].split(',');
if(vect.length == 3)
angMom[i] = data[i].split(',');
}

var newTotAngMom = angMom.length;
clearBoard();
var varianceLinear = 0;
var varianceCosine = 0;
var totTestDirs = document.getElementById('totTestDir').value;

var abDirections = new Array();
var AliceDirections = new Array();
var BobDirections = new Array();
var t2 = document.getElementById('in_test').value;
var data2 = t2.split('\n');
for (var k = 0; k < data2.length; k++)
{
var vect2 = data2[k].split(',');
if (vect2.length == 6)
{
abDirections[k] = data2[k].split(',');
AliceDirections[k] = data2[k].split(',');
BobDirections[k] = data2[k].split(',');

AliceDirections[k] = abDirections[k];
AliceDirections[k] = abDirections[k];
AliceDirections[k] = abDirections[k];
BobDirections[k]   = abDirections[k];
BobDirections[k]   = abDirections[k];
BobDirections[k]   = abDirections[k];
}
}

var TempOutput = "";

//computes the output
for(var j=0; j<totTestDirs; j++)
{
var a = AliceDirections[j];
var b = BobDirections[j];
for(var i=0; i<newTotAngMom; i++)
{
TempOutput = TempOutput + (j+1);
TempOutput = TempOutput + ",";
TempOutput = TempOutput + (i+1);
TempOutput = TempOutput + ",";
TempOutput = TempOutput + (GenerateAliceOutputFromSharedRandomness(a, angMom[i]));
TempOutput = TempOutput + ",";
TempOutput = TempOutput + (GenerateBobOutputFromSharedRandomness(b, angMom[i]));
if(i != newTotAngMom-1 || j != totTestDirs-1)
TempOutput = TempOutput + " \n";
}
}

apendResults(TempOutput);
};

var plotData = function()
{
clearBoard();
boardCorrelations.suspendUpdate();
//gets the data
var angMom = new Array();
var t = document.getElementById('in_data').value;
var data = t.split('\n');
for (var i=0;i<data.length;i++)
{
var vect = data[i].split(',');
if(vect.length == 3)
angMom[i] = data[i].split(',');
}

var newTotAngMom = angMom.length;
var varianceLinear = 0;
var varianceCosine = 0;
var totTestDirs = document.getElementById('totTestDir').value;

//extract directions
var abDirections = new Array();
var AliceDirections = new Array();
var BobDirections = new Array();
var t2 = document.getElementById('in_test').value;
var data2 = t2.split('\n');
for (var k = 0; k < data2.length; k++)
{
var vect2 = data2[k].split(',');
if (vect2.length == 6)
{
abDirections[k] = data2[k].split(',');
AliceDirections[k] = data2[k].split(',');
BobDirections[k] = data2[k].split(',');

AliceDirections[k] = abDirections[k];
AliceDirections[k] = abDirections[k];
AliceDirections[k] = abDirections[k];
BobDirections[k]   = abDirections[k];
BobDirections[k]   = abDirections[k];
BobDirections[k]   = abDirections[k];
}
}

var tempLine = new Array();
var Data_Val = document.getElementById('out_measurements').value;
var data_rows = Data_Val.split('\n');

var directionIndex = 1;
var beginNewDirection = false;

var a = new Array(3);
a = AliceDirections;
a = AliceDirections;
a = AliceDirections;
var b = new Array(3);
b = BobDirections;
b = BobDirections;
b = BobDirections;
var sum = 0;

for (var ii=0;ii<data_rows.length;ii++)
{
//parse the input line
var vect = data_rows[ii].split(',');
if(vect.length == 4)
tempLine = data_rows[ii].split(',');

//see if a new direction index is starting
if (directionIndex != tempLine)
{
beginNewDirection = true;
}

if(!beginNewDirection)
{
var sharedRandomnessIndex = tempLine;
var sharedRandomness = angMom[sharedRandomnessIndex];
var aliceOutcome = tempLine;
var bobOutcome = tempLine;
sum = sum + aliceOutcome*bobOutcome;
}

if (beginNewDirection)
{
//finish computation
var epsilon = sum/newTotAngMom;
var angle = Math.acos(Dot(a, b));
boardCorrelations.createElement('point', [angle,epsilon],{size:0.1,withLabel:false});

var diffLinear = epsilon - (-1+2/Math.PI*angle);
varianceLinear = varianceLinear + diffLinear*diffLinear;
var diffCosine = epsilon + Math.cos(angle);
varianceCosine = varianceCosine + diffCosine*diffCosine;

//reset and start a new cycle
directionIndex = tempLine;
a = AliceDirections[directionIndex-1];
a = AliceDirections[directionIndex-1];
a = AliceDirections[directionIndex-1];
b = BobDirections[directionIndex-1];
b = BobDirections[directionIndex-1];
b = BobDirections[directionIndex-1];
sum = 0;
var sharedRandomnessIndex = tempLine;
var sharedRandomness = angMom[sharedRandomnessIndex];
var aliceOutcome = tempLine;
var bobOutcome = tempLine;
sum = sum + aliceOutcome*bobOutcome;
beginNewDirection = false;
}

}
//finish computation for last element of the loop above
var epsilon = sum/newTotAngMom;
var angle = Math.acos(Dot(a, b));
boardCorrelations.createElement('point', [angle,epsilon],{size:0.1,withLabel:false});
var diffLinear = epsilon - (-1+2/Math.PI*angle);
varianceLinear = varianceLinear + diffLinear*diffLinear;
var diffCosine = epsilon + Math.cos(angle);
varianceCosine = varianceCosine + diffCosine*diffCosine;
//display total fit
boardCorrelations.createElement('text',[2.0, -0.7, 'Linear Fitting: ' + varianceLinear],{});
boardCorrelations.createElement('text',[2.0, -0.8, 'Cosine Fitting: ' + varianceCosine],{});
boardCorrelations.createElement('text',[2.0, -0.9, 'Cosine/Linear: ' + varianceCosine/varianceLinear],{});
boardCorrelations.unsuspendUpdate();
};

var clearBoard = function()
{
JXG.JSXGraph.freeBoard(boardCorrelations);
boardCorrelations = JXG.JSXGraph.initBoard('jxgboxCorrelations',{boundingbox:[-0.20, 1.25, 3.4, -1.25],axis:true,

boardCorrelations.create('functiongraph', [function(t){ return -Math.cos(t); }, -Math.PI*10, Math.PI*10],{strokeColor:

"#66ff66", strokeWidth:2,highlightStrokeColor: "#66ff66", highlightStrokeWidth:2});
boardCorrelations.create('functiongraph', [function(t){ return -1+2/Math.PI*t; }, 0, Math.PI],{strokeColor: "#6666ff",

strokeWidth:2,highlightStrokeColor: "#6666ff", highlightStrokeWidth:2});
};

var clearInput = function()
{
document.getElementById('in_data').value = '';
};

var clearTestDir = function()
{
document.getElementById('in_test').value = '';
};

var clearOutput = function()
{
document.getElementById('out_measurements').value = '';
};

var generateTestDir = function()
{
clearBoard();
var totTestDir = document.getElementById('totTestDir').value;
var testDir = new Array(totTestDir);
var strData = "";
for(var i=0; i<totTestDir; i++)
{
//first is Alice, second is Bob
testDir[i] = RandomDirection();
strData = strData + testDir[i] + ", " + testDir[i] + ", " + testDir[i]+ ", " ;
testDir[i] = RandomDirection();
strData = strData + testDir[i] + ", " + testDir[i] + ", " + testDir[i] + '\n';
}

document.getElementById('in_test').value = strData;
};

var generateRandomData = function()
{
clearBoard();
var totAngMoms = document.getElementById('totAngMom').value;
var angMom = new Array(totAngMoms);
var strData = "";
for(var i=0; i<totAngMoms; i++)
{
angMom[i] = RandomDirection();
strData = strData + angMom[i] + ", " + angMom[i] + ", " + angMom[i] + '\n';
}

document.getElementById('in_data').value = strData;
};

var apendResults= function(newData)
{
var existingData = document.getElementById('out_measurements').value;
existingData = existingData + newData;
document.getElementById('out_measurements').value = existingData;
};

function GenerateAliceOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
//replace this with your own function returning +1 or -1
if (Dot(direction, sharedRandomness3DVector) > 0)
return +1;
else
return -1;
};

function GenerateBobOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
//replace this with your own function returning +1 or -1
if (Dot(direction, sharedRandomness3DVector) < 0)
return +1;
else
return -1;
};

var boardCorrelations = JXG.JSXGraph.initBoard('jxgboxCorrelations', {axis:true, boundingbox: [-0.25, 1.25, 3.4, -1.25], showCopyright:false});

clearBoard();
generateRandomData();
generateTestDir();
generateData();
plotData();

clearBoard();
generateRandomData();
generateTestDir();
generateData();
plotData();

The key to the whole exercise are the following two functions:

function GenerateAliceOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
//replace this with your own function returning +1 or -1
if (Dot(direction, sharedRandomness3DVector) > 0)
return +1;
else
return -1;
};

function GenerateBobOutputFromSharedRandomness(direction, sharedRandomness3DVector) {
//replace this with your own function returning +1 or -1
if (Dot(direction, sharedRandomness3DVector) < 0)
return +1;
else
return -1;
};

To experiment with various hidden variable models all you have to do is replace the two functions above with your own concoction of hidden variable which uses the shared variable "sharedRandomness3DVector".

There are certain models for which if we return zero (which in the correlation computation is equivalent with discarding the data since the correlations are computed by this line in the code: sum = sum + aliceOutcome*bobOutcome;) a certain number of times as a function of the angle between direction and sharedRandomness3DVector, then one can obtain the quantum mechanics correlation curve. This is the famous detection loophole (or (un)fair sampling) for Bell's theorem.

If we talk about the detection loophole the paper to read is an old one by Philip Pearle: http://journals.aps.org/prd/abstract/10.1103/PhysRevD.2.1418 In there Pearle found an entire class of solutions able to generate the quantum correlations. The original paper is hard to double check (it took me more than a week and I was still not done completely), but Richard Gill did manage to extract a useful workable detection loophole model out of it: https://arxiv.org/pdf/1505.04431.pdf

Manipulating the generating functions above one can easily test various ideas about hidden variable models. For example an isotropic model of opposite spins generates -1/3 a.b correlations. It is not that hard to double check the math in this case: a simple integrals will do the trick. in particular this shows that the spins do not exist independent of measurement.

More manipulations using the detection loophole are even able to generate super-quantum Popescu-Rohrlich box correlations, but I let the user to experiment with this and discover how to do it for themselves. Happy computer modeling!

## Playing with Bell's theorem

In this post I'll write just a little text because editing is done straight in the HTML view which is very tedious. Below I have a Java script program which illustrates Bell's theorem. If you want to play with this code just right click on the page to view the source and extract it from there. If you do not know how to do that then you are not going to understand it in a few sentences. Next time I'll describe the code and how to experiment with various hidden variable models.
This is about an EPR-B Alice-Bob experiment where each ("measurement") generate a deterministic +1 or -1 outcome for a particular measurement direction using a shared piece of information: a random vector. Then the correlations are computed and plotted. No matter what deterministic model you try the correlation near the origin you generate a straight line vs. a curve of zero slope in the case of quantum mechanics. For this particular program, given a measurement direction specified as a unite vector in Cartesian coordinates I am computing the scalar product and I return +1 if positive I and -1 if negative. The experiment is repeated a number of times on various random measurement directions.
If you do not trust the randomly generated data, you can enter you own random Alice-Bob shared secret and your own measurement directions. Part of the credit for this program goes to Ovidiu Stoica.
 Number of experiments: Number of directions: Legend: Direction index|Data index|Measurement Alice|Measurement Bob

## A sinister mystification

Once in a while, events in the society at large overshadow all other considerations. I will put on hold the series about Bell's theorem for this week because, such an event occurred: Mother Teresa was proclaimed to be a saint. So what? What is the big deal?

Growing up in Romania, all I heard about her was that she was the symbol of selfless devotion to the poor, a truly remarkable person symbolizing all that it is good in mankind. Coming to US, the public perception was on similar lines and her 1979 Nobel piece prize seemed well deserved. Her recent sainthood was only the realization of a natural public expectation.

However things are not always what they appear and in this case the truth it is complete opposite with the perception. The sainthood outcome is the result of public gullibility masterly exploited by a morally bankrupt Catholic Church in collusion with dirty politicians, media, corrupt businessman, a dictatorship monarchy, and at the center of it all a pure evil person advancing a religious fanatic agenda for the benefit of the Catholic Church and her own perverted pleasure: Mother Teresa.

The person who blew the whistle on Mother Teresa's con artist mystification was a remarkable person: Christopher Hitchens with his book: The Missionary Position. I never heard of Mr. Hitchens until a year ago when I discovered by accident his anti theistic stance. Coming from a country which suffered under communism for decades, I was turned off by his hints of admiration for Marxist ideas. It took me some time to properly asses his integrity and the value of his arguments. In the end I found him a very sharp clear thinker with a courageous attitude. I was surprised to discover he was a mini celebrity in the left political circles in US who alienated part of that audience due to his hawkish attitude and support for the Iraq war and who was also a personal friend of late Justice Scalia-the most conservative member of the US Supreme Court.

Now I don't think I will change the minds of the devout Catholics about Mother Theresa, so if you are such a person either take the blue pill and stop reading the rest of this post or take the red pill and keep reading to be shaken from your intellectual complacency and maybe stop buying the bridge the church keeps selling you.

To start I encourage you to watch the following videos:

It's too long to explain the whole mystification story but here is the gist:

Mother Teresa was not a friend of the poor but of poverty and suffering. She derived a perverted gratification from witnessing and encouraging suffering because she thought this would bring her closer to her salvation. This is the mark of a psychopath which derives meaning and pleasure from other's suffering. The places she established were not designed to alleviate suffering but decrepit places of abject poverty and suffering were people were simply brought to die. Young people were denied simple medical care which could have easily saved their lives because their suffering was sanctioned by a fanatical religious agenda.

So maybe Mother Teresa applied the same principles on herself. Not at all. When she was ill no expenses were spared and she took advantage of the latest medical advances. What a cosmic hypocrite. But where did the money come from to establish her places of suffering? Among other sources from the brutal Duvalier dictatorship family in Haiti responsible for the deaths of tens of thousands of people over decades, and from a corrupt business person convicted of stealing the life savings of thousands of people. But perhaps the Catholic Church upon learning about this returned the blood and dirty money to the victims? After all Mother Teresa acted with the full blessing of the church. Think again.

Hitchens has a simple but true position: religion poisons everything. It takes time to evaluate his claims and try to refute it if you can. It is much more convenient to ignore it, but then I assume that if you reached this paragraph you took the red pill. Many religious figures and "religious scholars" tried debating with  Hitchens only to be shamefully debunked. None won the debates. Hitchslap is now an urban dictionary verb.

On Mother Teresa Hitchens put it like this: "It is a certainty that millions of people died because of her work. And millions more were made poorer, or stupider, more sick, more diseased, more fearful, and more ignorant."

Her sainthood is a scandal due to a sinister and cynical mystification perpetuated by many people over decades for their own benefits. The shame list includes the Catholic Church with all its popes who sanctioned Mother Teresa fanatical religious agenda, politicians like Ronald Reagan, public figures like Princess Dianna, the Nobel Peace prize committee, media like CNN, all who exploited public opinions for their own agendas, as well as corrupt businessman and dictators who provided the money in exchange of whitewashing their public image.

## but quantum correlations are not like Bertlmann's socks

It finally happened. I was too careless and I stupidly challenged Lubos to "Show me a non-factorizable state in CM for spatially separated physical systems!!!"

And he indeed presented one:

"Bertlemann's socks? The state is described by the probability distribution that has 0%,50%,50%,0% for left-and-right-green, left-green right-red, left-red right-green, left-and-right-read. The state, P(colorLEFT, colorRIGHT) isn't factorized. "

This is obscurely written but it is ultimately correct. Glup, glup, glup, he sank my battleship, bruised my ego, won the battle, but not the war :) I will attempt to show that quantum correlations are not like Bertlmann's socks correlations because quantum correlations depend in an essential way on the observer. First let me clarify Lubos example and why he is right in his example.

First what is this business of Bertlmann's socks? This came from a famous Bell paper:

Mr Bertlmann is a real person who uses to wear socks of different colors. The moment you see that one of his socks is pink you know that his other sock is not pink. (Lubos is using red and green) and there is a correlation between the sock colors. In general, you learn from statistic 101 that a joint probability $$P(A, B)$$ factorizes: $$P(A,B)=P(A)P(B)$$ if the two probabilities are independent. Therefore it was blatantly stupid on my part to ask Lubos for a non-factorizable example. But I had something else in mind for which I carelessly skipped the essential details and now I will explain it properly.

The Bell theorem factorization condition is not on independent probabilities but on residual probabilities:

$$P(A,B, \lambda) = P(A, \lambda) P(B, \lambda)$$

In the case of Bertlmann's socks there are no residual probabilities! But what does this mean?

Correlations can be generated due to physical interaction between two systems or because they share a common cause. One way people explain this is by inventing silly games where two players agree in advance on a strategy but they are not allowed to communicate during the actual game. For example consider this: Alice and Bob each have a coin and they flip it heads or tails. Then they both have to guess the result of each other and they win the game when successful. If they guess randomly the best odds of wining the game is 25% of the time. However there are two strategies they can agree beforehand which increases their odds of winning to 50%. (Can you guess what those strategies might be?). Strategies, common causes and interactions, outcome filtering, all generate correlations and ruin the factorization condition.

But quantum mechanics is probabilistic and even if you account for all interactions the outcome is still random. After accounting for all those factors in the form of a generic variable $$\lambda$$, the remaining probability is called a residual probability. Lambda can be a variable, or a set of variables of an unspecified format. The point is that after accounting for all common causes, if the physical systems A and B are spatially separated, they cannot communicate and in the quantum case it seems reasonable to demand $$P(A,B, \lambda) = P(A, \lambda) P(B, \lambda)$$.

But such a factorization is at odds with both quantum mechanics predictions, and experimental results. This is the basis on which people in foundations of quantum mechanics call nature nonlocal.

I think I know how Lubos may attack this. I bet he will say that $$\lambda$$ is basically a hidden variable and quantum mechanics does not admit hidden variables. This line of argument is faulty. Carefully read (several times) Bell's paper from the link above and you see that $$\lambda$$ represents the coding of the usual way correlations are  accounted by this common $$\lambda$$ which is present in all 3 factors.

Let me spell out better Bell's argument following a well written paper by Bernard d'Espagnat. Bell considers the singlet state and in there you have Alice and Bob in two spatially separated labs measuring the spins on directions a, and b and obtaining the outcomes A, and B respectively, Let $$\lambda$$ represent a common source of the correlation between A and B. Then one can write the standard rule of statistics: $$P(M,N) = P(M|N)P(N)$$ like this:

$$P(A,B|a,b,\lambda) = P(A|a,b,B,\lambda)P(B|a,b,\lambda)$$

then because what happens at Alice's side does not depend on what happens on Bob side and the other way around:

$$P(A|a,b,B,\lambda) = P(A|a, \lambda)$$
$$P(B|a,b,\lambda) = P(B|b, \lambda)$$

yields:

$$P(A,B|a,b,\lambda) = P(A|a, \lambda) P(B|b,\lambda)$$

From this the usual Bell theorem follows and disagreement with experiment is used to point out that what happens at Alice's side does depend on what happens on Bob side. In other words, nonlocality.

I disagree (with good arguments) with several points of view:

• I disagree with Lubos that nature does not follow the logic of projectors and follows the Boolean logic instead. (measurements project on a Hilbert subspace and quantum OR and quantum NOT are different than their classical counterparts)
• I disagree with Tim Maudlin who best defends the point that Bell proved nonlocality based on the argument above (Quantum mechanics is contextual and because of that: $$P(A|a,b,B,\lambda) \ne P(A|a, \lambda)$$ . As such Bell's factorization condition is not justified. Only if you think in terms of classical Boolean logic avoiding contextuality the nonlocality conclusion is inescapable. )
• I disagree with Lubos that quantum correlations are like Bertlmann's socks. To eliminate thinking about lambda as a hidden variable, picture it as fixing all conceivable sources of correlations (Bertlmann's socks type or any other type). Now add locality independence, Boolean logic, and you get correlations at odds with experiments. Pick your poison: give up locality or give up Boolean logic. The one to give up is Boolean logic. Unlike Bertlmann's socks correlations, quantum correlations depend in an essential way on the observer.
• I disagree with giving up on locality and that the Bohmian position represents a valid description of nature (what happens with he quantum potential of a particle after the particle encounters its antiparticle? Both vanish or not vanish result in predictions incompatible with observations)

Bell himself provided 4 possible explanations of quantum mechanics' correlations:
-quantum mechanics is wrong sometimes
-superdeterminism (lack of free will)
-faster than light causal influences
-non-realism

My take on this is that quantum mechanics is the complete and correct description of nature, there is free will, there are no faster than light causal influences, realism is incorrect, and what people call nonlocality is actually a manifestation of contextuality because the observer (but not consciousness) does play an active role in generating the experimental outcome. This active role happens even when parts of the composed system are out of causal reach because quantum mechanics is blind to space-time separations.