Public
Edited
Jan 20, 2024
Insert cell
Insert cell
numFilled = fnNamesList.filter((x) => x.repr).length
Insert cell
Insert cell
Object.values(intersections).filter((arr) => arr.label === "terns")
Insert cell
Object.entries(intersections).length
Insert cell
intersections = {
let Bins = [Impl, If, Eq, Or];
let binFns = Bins.map((Bin) => Bin(Var, Var));
let items = {};
let Terns = [
Or,
Eq,
Neq,
Odd,
// Even,
CountEq(1),
CountNeq(1),
CountLeq(1),
// CountGeq(2),
Mux,
EquivImpl,
NEquivImpl
];
let ternFns = Terns.map((Tern) => Tern(Var, Var, Var)).concat([
// andOr,
// orAnd,
andEq,
// orEq,
// eqAnd,
eqOr
// xorAnd,
// xorOr
]);

function check(Fn, label) {
let fn = Fn(Var, Var, Var, Var);
let idx = codeToClassMap[getCode(4, fn)];
if (!fnNamesList[idx].repr) {
if (!items[idx]) {
items[idx] = [];
items[idx].label = label;
}
items[idx].push(fn.format(..."abcd"));
}
}
for (let ternFn of ternFns) {
for (let i of [0, 1, 2]) {
for (let binFn of binFns) {
let Fn = makeCombinationFunction(
(args) => ternFn(...args.slice(0, 3)) && binFn(args[i], args[3]),
(args) =>
`${ternFn.format(...args.slice(0, 3))} && ${binFn.format(
args[i],
args[3]
)}`
);
check(Fn);
}
}
for (let [i, j] of [
[0, 1],
[0, 2],
[1, 2]
]) {
for (let binFn1 of binFns) {
for (let binFn2 of binFns) {
let Fn = makeCombinationFunction(
(args) =>
ternFn(...args.slice(0, 3)) &&
binFn1(args[i], args[3]) &&
binFn2(args[j], args[3]),
(args) =>
`${ternFn.format(...args.slice(0, 3))} && ${binFn1.format(
args[i],
args[3]
)} && ${binFn2.format(args[j], args[3])}`
);
check(Fn);
}
}
}
let [i, j, k] = [0, 1, 2];
for (let binFn1 of binFns) {
for (let binFn2 of binFns) {
for (let binFn3 of binFns) {
let Fn = makeCombinationFunction(
(args) =>
ternFn(...args.slice(0, 3)) &&
binFn1(args[i], args[3]) &&
binFn2(args[j], args[3]) &&
binFn3(args[k], args[3]),
(args) =>
`${ternFn.format(...args.slice(0, 3))} && ${binFn1.format(
args[i],
args[3]
)} && ${binFn2.format(args[j], args[3])} && ${binFn3.format(
args[k],
args[3]
)}`
);
check(Fn);
}
}
}
}

let fullTerns = ternFns
.concat([andOr, orAnd, orEq, eqAnd, xorAnd, xorOr])
.concat([Even, CountGeq(2)].map((F) => F(Var, Var, Var)));

for (let ternFn of fullTerns) {
for (let ternFn2 of fullTerns) {
for (let i = 0; i < 2 ** 4; i++) {
let Fn = makeCombinationFunction(
([a, b, c, d]) =>
ternFn(a, b, c) && applyNegations(ternFn2, i)(a, b, d),
([a, b, c, d]) =>
`${ternFn.format(a, b, c)} && ${ternFn2.format(a, b, d)}`
);
check(Fn, "terns");
}
for (let ternFn3 of fullTerns) {
let Fn = makeCombinationFunction(
([a, b, c, d]) =>
ternFn(a, b, c) && ternFn2(a, b, d) && ternFn3(a, c, d),
([a, b, c, d]) =>
`${ternFn.format(a, b, c)} && ${ternFn2.format(
a,
b,
d
)} && ${ternFn3.format(a, c, d)}`
);
check(Fn, "terns");
for (let ternFn4 of fullTerns) {
let Fn = makeCombinationFunction(
([a, b, c, d]) =>
ternFn(a, b, c) &&
ternFn2(a, b, d) &&
ternFn3(a, c, d) &&
ternFn4(b, c, d),
([a, b, c, d]) =>
`${ternFn.format(a, b, c)} && ${ternFn2.format(
a,
b,
d
)} && ${ternFn3.format(a, c, d)} && ${ternFn4.format(b, c, d)}`
);
check(Fn, "terns");
}
}
}
}

return items;
}
Insert cell
Impl = makeCombinationFunction(
([p, q]) => !p || q,
([p, q]) => `${p} => ${q}`
)
Insert cell
If = makeCombinationFunction(
([p, q]) => p || !q,
([p, q]) => `${p} <= ${q}`
)
Insert cell
{
let idx =
codeToClassMap[getCode(4, (a, b, c, d) => (a || b || c) && (a && b) == d)];
return [idx, fnNamesList[idx].repr || intersections[idx][0]];
}
Insert cell
incompleteClasses = foundClasses.filter((x) =>
Object.values(x.fnNames).some((list) => list.length !== 1)
)
Insert cell
foundClasses = fnNamesList.filter((x) => x.repr)
Insert cell
fnNamesList = {
let list = quartClasses.map((classList) => {
return {
fnNames: Object.fromEntries([...classList].map((code) => [code, []]))
};
});
function setList(fn) {
let code = getCode(4, fn);
let index = codeToClassMap[code];
list[index].fnNames[code].push(fn.format("a", "b", "c", "d"));
}
function setAsRepr(fn) {
let code = getCode(4, fn);
let index = codeToClassMap[code];
list[index].repr = fn.format("a", "b", "c", "d");
}

populateNullary(setAsRepr, setList);
populateUnary(setAsRepr, setList, 4);
populateBinary(setAsRepr, setList, 4);
populateTernary(setAsRepr, setList, 4);

setRepsQuartenary(setAsRepr);
fillQuartenary(setList);
return list;
}
Insert cell
function setRepsQuartenary(setAsRepr) {
for (let fn of [
// withFormat(
// (a, b, c, d) => a == b && b == c && (!c || d),
// (a, b, c, d) => `${a} == ${b} == ${c} => ${d}`
// ),
// withFormat(
// (a, b, c, d) => a == b && (!b || c) && (!c || d),
// (a, b, c, d) => `${a} == ${b} => ${c} => ${d}`
// ),
// withFormat(
// (a, b, c, d) => (!a || b) && (!b || c) && (!c || d),
// (a, b, c, d) => `${a} => ${b} => ${c} => ${d}`
// ),
// withFormat(
// (a, b, c, d) => (!a || b) && b == c && (!c || d),
// (a, b, c, d) => `${a} => ${b} == ${c} => ${d}`
// ),
// withFormat(
// (a, b, c, d) => a == b && (!b || c) && c == d,
// (a, b, c, d) => `${a} == ${b} => ${c} == ${d}`
// ),
// withFormat(
// (a, b, c, d) => (a || !b) && (!b || c) && (!c || d),
// (a, b, c, d) => `${a} <= ${b} => ${c} => ${d}`
// ),
// withFormat(
// (a, b, c, d) => (a || !b) && (!b || c) && (c || !d),
// (a, b, c, d) => `${a} <= ${b} => ${c} <= ${d}`
// ),
// withFormat(
// (a, b, c, d) => (a || !b) && (!b || c) && c == d,
// (a, b, c, d) => `${a} <= ${b} => ${c} == ${d}`
// ),
// withFormat(
// (a, b, c, d) => (!a || b) && (!b || d) && (!a || c) && (!c || d),
// (a, b, c, d) => `${a} => {${b}, ${c}} => ${d}`
// ),
andFn,
oddFn,
eqFn,
countEq1,
countEq2,
countLeq1,
countEq02,
countEq03,
countEq12,
orOfAnds,
andOrAnd,
eqOfAnds,
andOfEqs,
orOfAndEq,
eqOrAnd,
andEqAnd,
andOrEq,
eqAndEq,
orAnd3,
eqAnd3,
andOdd3,
andEq3,
xorEq3,
andCountEq1,
orCountEq1,
eqCountEq1,
andCountLeq1,
eqCountLeq1,
and3Or,
and3Eq,
odd3And,
eq3And,
eq3Or,
eq3Xor,
countEq1And,
countEq1Or,
countEq1Eq,
countLeq1And,
countLeq1Eq,
andMux,
andCMux,
eqMux,
eqCMux,
muxAnd,
muxEq,
andEquivImpl,
andCEquivImpl,
orEquivImpl,
orCEquivImpl,
eqEquivImpl,
eqCEquivImpl,
equivImplAnd,
equivImplOr,
equivImplEq
]) {
setAsRepr(fn);
}
}
Insert cell
function fillQuartenary(setList) {
// commutative functions
setList(oddFn);
setList(evenFn);
for (let i = 0; i < 2 ** 4; i++) {
for (let fn of [
andFn,
orFn,
countEq1,
countNeq1,
countLeq1,
countLeq2,
countEq02,
countNeq02,
countEq03,
countNeq03,
countEq12,
countNeq12
]) {
setList(applyNegations(fn, i));
}
}

for (let i = 0; i < 2 ** 4; i++) {
let bitCount = countBits(i);
if (bitCount < 2 || (bitCount === 2 && i % 2 === 0)) {
for (let fn of [eqFn, neqFn, countEq2, countNeq2]) {
setList(applyNegations(fn, i));
}
}
}

for (let order of permutations(_.range(4))) {
for (let i = 0; i < 2 ** 3; i++) {
for (let fn of [muxAnd, muxOr]) {
setList(permuteFn(applyNegations(fn, i << 1), order));
}
}
for (let i = 0; i < 2 ** 2; i++) {
for (let fn of [muxEq]) {
setList(permuteFn(applyNegations(fn, i << 1), order));
}
}
if (order[0] < order[1]) {
for (let i = 0; i < 2 ** 4; i++) {
for (let fn of [
andOrAnd,
orAndOr,
andOrEq,
andEqAnd,
andEqOr,
andEquivImpl,
andNEquivImpl,
orEquivImpl,
orNEquivImpl,
equivImplAnd,
equivImplOr,
nEquivImplAnd,
nEquivImplOr,
equivImplEq
]) {
setList(permuteFn(applyNegations(fn, i), order));
}
}
for (let i = 0; i < 2 ** 4; i += 2) {
for (let fn of [eqAndOr, eqOrAnd, eqAndEq, eqEquivImpl, eqNEquivImpl]) {
setList(permuteFn(applyNegations(fn, i), order));
}
}
}

if (order[2] < order[3]) {
for (let i = 0; i < 2 ** 4; i++) {
for (let fn of [andCMux, orCMux]) {
setList(permuteFn(applyNegations(fn, i), order));
}
}
for (let i = 0; i < 2 ** 3; i++) {
setList(permuteFn(applyNegations(eqCMux, i), order));
}
}

if (order[0] < order[1] && order[2] < order[3]) {
for (let i = 0; i < 2 ** 3; i++) {
for (let fn of [orOfAndEq, andOfOrEq, eqCEquivImpl, eqCNEquivImpl]) {
setList(permuteFn(applyNegations(fn, i), order));
}
}
for (let i = 0; i < 2 ** 4; i++) {
for (let fn of [
orAnd3,
andOr3,
andEq3,
andNeq3,
andCountEq1,
andCountNeq1,
orCountEq1,
orCountNeq1,
andCountLeq1,
andCountGeq2,
andMux,
orMux,
andCEquivImpl,
andCNEquivImpl,
orCEquivImpl,
orCNEquivImpl
]) {
setList(permuteFn(applyNegations(fn, i), order));
}
}
for (let i = 0; i < 2 ** 4; i += 2) {
setList(permuteFn(applyNegations(eqAnd3, i), order));
setList(permuteFn(applyNegations(eqOr3, i), order));
setList(permuteFn(applyNegations(eqCountEq1, i), order));
setList(permuteFn(applyNegations(eqCountNeq1, i), order));
setList(permuteFn(applyNegations(eqCountLeq1, i), order));
setList(permuteFn(applyNegations(eqMux, i), order));
}
for (let i = 0; i < 2 ** 2; i++) {
setList(permuteFn(applyNegations(andOdd3, i), order));
setList(permuteFn(applyNegations(andEven3, i), order));
setList(permuteFn(applyNegations(xorEq3, i << 2), order));
setList(permuteFn(applyNegations(xorNeq3, i << 2), order));
}
}
}

// A is fixed, all others permute
for (let order of cycle([1, 2, 3])) {
order = [0, ...order];
for (let i = 0; i < 2 ** 4; i++) {
for (let fn of [andOfOrs, orOfAnds, eqOfAnds, neqOfAnds]) {
setList(permuteFn(applyNegations(fn, i), order));
}
}
for (let i of [0, 0b0010, 0b1000, 0b1010]) {
setList(permuteFn(applyNegations(andOfEqs, i), order));
setList(permuteFn(applyNegations(orOfEqs, i), order));
}
}
for (let order of cycle(_.range(4))) {
for (let i = 0; i < 2 ** 4; i++) {
for (let fn of [
and3Or,
or3And,
and3Eq,
countEq1And,
countNeq1Or,
countEq1Or,
countNeq1And,
countEq1Eq,
countLeq1And,
countLeq1Or
]) {
setList(permuteFn(applyNegations(fn, i), order));
}
if (countBits(i % 2 ** 3) <= 1) {
for (let fn of [eq3And, neq3Or, eq3Or, neq3And, eq3Xor]) {
setList(permuteFn(applyNegations(fn, i), order));
}
}
}
for (let i = 0; i < 2 ** 3; i++) {
setList(permuteFn(applyNegations(countLeq1Eq, i), order));
}
for (let i = 0; i < 2 ** 2; i++) {
for (let fn of [odd3And, odd3Or]) {
setList(permuteFn(applyNegations(fn, i << 2), order));
}
}
}
}
Insert cell
## (A ? B) ? (C ? D)
Insert cell
orOfAnds = Or(And(Var, Var), And(Var, Var))
Insert cell
andOfOrs = And(Or(Var, Var), Or(Var, Var))
Insert cell
eqOfAnds = Eq(And(Var, Var), And(Var, Var))
Insert cell
neqOfAnds = Xor(And(Var, Var), And(Var, Var))
Insert cell
andOfEqs = And(Eq(Var, Var), Eq(Var, Var))
Insert cell
orOfEqs = Or(Eq(Var, Var), Eq(Var, Var))
Insert cell
orOfAndEq = Or(And(Var, Var), Eq(Var, Var))
Insert cell
andOfOrEq = And(Or(Var, Var), Eq(Var, Var))
Insert cell
Insert cell
Insert cell
orAnd3 = And(Or(Var, Var), Var, Var)
Insert cell
andOr3 = Or(And(Var, Var), Var, Var)
Insert cell
eqAnd3 = And(Eq(Var, Var), Var, Var)
Insert cell
eqOr3 = Or(Eq(Var, Var), Var, Var)
Insert cell
andOdd3 = Odd(And(Var, Var), Var, Var)
Insert cell
andEven3 = Even(And(Var, Var), Var, Var)
Insert cell
andEq3 = Eq(And(Var, Var), Var, Var)
Insert cell
andNeq3 = Neq(And(Var, Var), Var, Var)
Insert cell
xorEq3 = Eq(Xor(Var, Var), Var, Var)
Insert cell
xorNeq3 = Neq(Xor(Var, Var), Var, Var)
Insert cell
andCountEq1 = CountEq(1)(And(Var, Var), Var, Var)
Insert cell
andCountNeq1 = CountNeq(1)(And(Var, Var), Var, Var)
Insert cell
orCountEq1 = CountEq(1)(Or(Var, Var), Var, Var)
Insert cell
orCountNeq1 = CountNeq(1)(Or(Var, Var), Var, Var)
Insert cell
eqCountEq1 = CountEq(1)(Eq(Var, Var), Var, Var)
Insert cell
eqCountNeq1 = CountNeq(1)(Eq(Var, Var), Var, Var)
Insert cell
andCountLeq1 = CountLeq(1)(And(Var, Var), Var, Var)
Insert cell
andCountGeq2 = CountGeq(2)(And(Var, Var), Var, Var)
Insert cell
eqCountLeq1 = CountLeq(1)(Eq(Var, Var), Var, Var)
Insert cell
Insert cell
andMux = Mux(And(Var, Var), Var, Var)
Insert cell
orMux = Mux(Or(Var, Var), Var, Var)
Insert cell
andCMux = Mux(Var, Var, And(Var, Var))
Insert cell
orCMux = Mux(Var, Var, Or(Var, Var))
Insert cell
eqMux = Mux(Eq(Var, Var), Var, Var)
Insert cell
eqCMux = Mux(Var, Var, Eq(Var, Var))
Insert cell
andEquivImpl = EquivImpl(And(Var, Var), Var, Var)
Insert cell
andNEquivImpl = NEquivImpl(And(Var, Var), Var, Var)
Insert cell
andCEquivImpl = EquivImpl(Var, Var, And(Var, Var))
Insert cell
andCNEquivImpl = NEquivImpl(Var, Var, And(Var, Var))
Insert cell
orEquivImpl = EquivImpl(Or(Var, Var), Var, Var)
Insert cell
orNEquivImpl = NEquivImpl(Or(Var, Var), Var, Var)
Insert cell
orCEquivImpl = EquivImpl(Var, Var, Or(Var, Var))
Insert cell
orCNEquivImpl = NEquivImpl(Var, Var, Or(Var, Var))
Insert cell
eqEquivImpl = EquivImpl(Eq(Var, Var), Var, Var)
Insert cell
eqNEquivImpl = NEquivImpl(Eq(Var, Var), Var, Var)
Insert cell
eqCEquivImpl = EquivImpl(Var, Var, Eq(Var, Var))
Insert cell
eqCNEquivImpl = NEquivImpl(Var, Var, Eq(Var, Var))
Insert cell
Insert cell
Insert cell
and3Or = Or(And(Var, Var, Var), Var)
Insert cell
or3And = And(Or(Var, Var, Var), Var)
Insert cell
and3Eq = Eq(And(Var, Var, Var), Var)
Insert cell
odd3And = And(Odd(Var, Var, Var), Var)
Insert cell
odd3Or = Or(Odd(Var, Var, Var), Var)
Insert cell
eq3And = And(Eq(Var, Var, Var), Var)
Insert cell
neq3Or = Or(Neq(Var, Var, Var), Var)
Insert cell
eq3Or = Or(Eq(Var, Var, Var), Var)
Insert cell
neq3And = And(Neq(Var, Var, Var), Var)
Insert cell
eq3Xor = Xor(Eq(Var, Var, Var), Var)
Insert cell
countEq1And = And(CountEq(1)(Var, Var, Var), Var)
Insert cell
countNeq1Or = Or(CountNeq(1)(Var, Var, Var), Var)
Insert cell
countEq1Or = Or(CountEq(1)(Var, Var, Var), Var)
Insert cell
countEq1Eq = Eq(CountEq(1)(Var, Var, Var), Var)
Insert cell
countNeq1And = And(CountNeq(1)(Var, Var, Var), Var)
Insert cell
countLeq1And = And(CountLeq(1)(Var, Var, Var), Var)
Insert cell
countLeq1Or = Or(CountLeq(1)(Var, Var, Var), Var)
Insert cell
countLeq1Eq = Eq(CountLeq(1)(Var, Var, Var), Var)
Insert cell
Insert cell
muxAnd = And(Mux(Var, Var, Var), Var)
Insert cell
muxOr = Or(Mux(Var, Var, Var), Var)
Insert cell
muxEq = Eq(Mux(Var, Var, Var), Var)
Insert cell
equivImplAnd = And(EquivImpl(Var, Var, Var), Var)
Insert cell
nEquivImplOr = Or(NEquivImpl(Var, Var, Var), Var)
Insert cell
equivImplOr = Or(EquivImpl(Var, Var, Var), Var)
Insert cell
nEquivImplAnd = And(NEquivImpl(Var, Var, Var), Var)
Insert cell
equivImplEq = Eq(EquivImpl(Var, Var, Var), Var)
Insert cell
Insert cell
andOrAnd = And(Or(And(Var, Var), Var), Var)
Insert cell
orAndOr = Or(And(Or(Var, Var), Var), Var)
Insert cell
eqOrAnd = And(Or(Eq(Var, Var), Var), Var)
Insert cell
eqAndOr = Or(And(Eq(Var, Var), Var), Var)
Insert cell
andEqAnd = And(Eq(And(Var, Var), Var), Var)
Insert cell
andEqOr = Or(Eq(And(Var, Var), Var), Var)
Insert cell
andOrEq = Eq(Or(And(Var, Var), Var), Var)
Insert cell
eqAndEq = Eq(And(Eq(Var, Var), Var), Var)
Insert cell
## 4-ary Commutative
Insert cell
countEq1 = CountEq(1)(Var, Var, Var, Var)
Insert cell
countNeq1 = CountNeq(1)(Var, Var, Var, Var)
Insert cell
countEq2 = CountEq(2)(Var, Var, Var, Var)
Insert cell
countNeq2 = CountNeq(2)(Var, Var, Var, Var)
Insert cell
countLeq1 = CountLeq(1)(Var, Var, Var, Var)
Insert cell
countLeq2 = CountLeq(2)(Var, Var, Var, Var)
Insert cell
countEq02 = CountEq(0, 2)(Var, Var, Var, Var)
Insert cell
countNeq02 = CountNeq(0, 2)(Var, Var, Var, Var)
Insert cell
countEq03 = CountEq(0, 3)(Var, Var, Var, Var)
Insert cell
countNeq03 = CountNeq(0, 3)(Var, Var, Var, Var)
Insert cell
countEq12 = CountEq(1, 2)(Var, Var, Var, Var)
Insert cell
countNeq12 = CountNeq(1, 2)(Var, Var, Var, Var)
Insert cell
codeToClassMap = getClassIndexMap(quartClasses)
Insert cell
quartClasses = getConjugacyClasses(4)
Insert cell
function getClassIndexMap(equivClasses) {
let map = [];
for (let [idx, cls] of equivClasses.entries()) {
for (let item of cls) {
map[item] = idx;
}
}
return map;
}
Insert cell
import {
populateTernary,
Mux,
EquivImpl,
NEquivImpl,
// tern functions
andOr,
orAnd,
andEq,
orEq,
eqAnd,
eqOr,
xorAnd,
xorOr
} from "@tesseralis/ternary-functions"
Insert cell
import {
permutations,
getConjugacyClasses,
combinationsWithRepeats,
makeCombinationFunction,
getIndex,
getCode,
widen,
countBits,
applyNegations,
compose,
permuteFn,
negateFn,
withFormat,
cycle,
populateNullary,
populateUnary,
populateBinary,
trueFn,
falseFn,
idFn,
notFn,
andFn,
orFn,
evenFn,
oddFn,
eqFn,
neqFn,
CountEq,
CountNeq,
CountGeq,
CountLeq,
xor2,
eq2,
Var,
And,
Or,
Xor,
Odd,
Even,
Eq,
Neq
} from "@tesseralis/boolean-functions"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more