/*
tetralemma - Some Logic
These algorithms create logical sentences in a certain random manner.
Julian Rohrhuber, 2006
*/

// english

(
a = ["either % or %", "both % and %", "neither % nor %"];
x = { |i, x=("true"), y=("false")| format(a[i], x, y) };
f = { #[0, 1, 2].scramble.keep(2) };
g = { |i=0, n=1, s1, s2| 
	var k, l;
	#k, l = f.value;
	if(n>1) {
		x.(
			i,
			g.(k, n-1, s1, s2),
			g.(l, n-1, s1, s2)
		)
		
	} {
		x.(i, s1, s2)
	}
};

z = {|n=1, s1, s2|
	var r = g.([0, 1, 2].choose, n, s1, s2);
	r[0] = r[0].toUpper;
	quote(r ++ ".")
}
);

z.(1)
z.(2)
z.(3)

// or in numbers:

z.(1, 0, 1)
z.(2, 0, 1)
z.(3, 0, 1)

// if you don't think this kind of logic has its applications:

z.(1, "hungry", "tired");
z.(2, "hungry", "tired");
z.(3, "hungry", "tired");

// boolean logic formulation
a = ["(% xor: %)", "(% and: %)", "(not(%) and: not(%))"];

r = ("{|x,y| " ++ g.(1, 3, "x", "y") ++ "}").postln.interpret

r.(true, true)
r.(true, false)
r.(false, false)
r.(false, true)

// truth table:
(
var k = {|c| if(c) { "T" } { "F" } }.flop;
{: [x, y, r.(x, y)], x<-[true, false], y<-[true, false] }.do {|c| postf("%\t%\t%\n", *k.(c)) };
)

// sonification.
(
var n = 3; // number of levels
var j = -1;

g = { |i=0, n=1, s1, s2| 
	var k, l;
	#k, l = f.value;
	if(n>1) {
		k = g.(k, n-1, s1, s2);
		l = g.(l, n-1, s1, s2);
		
		format("(u = %; Out.kr(%, u); u)", x.(i, k, l), j = j + 1)
		
	} {
		format("(u = %; Out.kr(%, u); u)", x.(i, s1, s2), j = j + 1)	
	}
};
a = [
	"{ m = %; l = %; (((l < 1) * m) + ((m < 1) * l)) > 0 }.value", 
	"(% * %)", 
	"((% < 1) * (% < 1))"
];
r = ("{|x,y| var u, m, l; " ++ g.([0, 1, 2].choose, n, "x", "y") ++ " }").postln.interpret;
(
{
var a, b, x, amps, u;
a = LFPulse.kr(MouseX.kr(0.1, 100, 1), 0, 0.5);
b = LFPulse.kr(MouseY.kr(0.1, 100, 1), 0, 0.5);
r.(a, b);
amps = [a, b] ++ In.kr(0, j);
u = amps.collect { |a, i|
	var freq = i.linexp(0, amps.size-1, 300, 6000);
	a = a * AmpCompA.ir(freq);
	SinOsc.ar(freq, 0, a)
};
Splay.ar(u) * (1/n)
}.play;
);
)

// german version
(
a = ["entweder % oder %", "sowohl % als auch %", "weder % noch %"];
x = { |i, x=("wahr"), y=("falsch")| format(a[i], x, y) };
f = { #[0, 1, 2].scramble.keep(2) };
g = { |i=0, n=1, s1, s2| 
	var k, l;
	#k, l = f.value;
	if(n>1) {
		x.(
			i,
			g.(k, n-1, s1, s2),
			g.(l, n-1, s1, s2)
		)
		
	} {
		x.(i, *[s1, s2].scramble)
	}
};
z = {|n=1, s1, s2|
	var r = g.([0, 1, 2].choose, n, s1, s2);
	r[0] = r[0].toUpper;
	quote(r ++ ".")
}
)

z.(1)
z.(2)
z.(3)

// the buddhist tetralemma (catuskoti) extrapolation
/*
http://ccbs.ntu.edu.tw/FULLTEXT/JR-PHIL/richard2.htm

[46] "Everything is either true, or not true, or 
both true and not true, or neither true nor 
not true; that is the Buddhas teaching." 
*/

(
a = ["either % or %", "both % and %", "neither % nor %"];
x = { |i, x=("true"), y=("false")| format(a[i], x, y) };
f = { #[0, 1, 2].scramble.keep(2) };
g = { |i=0, n=1, s1, s2| 
	var k, l;
	#k, l = f.value;
	if(n>1) {
		x.(
			i,
			g.(k, n-1, s1, s2),
			g.(l, n-1, s1, s2)
		)
		
	} {
		x.(i, s1, s2)
	}
};

z = {|n=1, s1="true", s2="false"|
	var r = g.([0, 1, 2].choose, n, s1, s2);
	r[0] = r[0].toUpper;
	quote(r ++ ".")
}
);

z.(1, "true", "not true")
z.(2)
z.(3)