Skip to content

Commit

Permalink
class based implementation starting to work
Browse files Browse the repository at this point in the history
  • Loading branch information
mcnuttandrew committed Jan 30, 2024
1 parent e6df6d4 commit 93d1585
Show file tree
Hide file tree
Showing 4 changed files with 598 additions and 58 deletions.
11 changes: 6 additions & 5 deletions lint-language-sketching.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,23 @@ Pair functions: contrast, deltaE
Reduces: count, range
Value functions: sim, name, space

Program: e
Program: p => T | F
e

Expressions (e) => T | F | (e, e) => T | F
e = NOT e | AND e[] | OR e[] | p | Q (v[] | colors) p | T | F | if e e e
e = NOT e | AND e[] | OR e[] | p v v | Q (v[] | colors) p | T | F | if e e e

Values
v' = n | c | var
v = v' | c[] | var[] | m v[] | r v[] | pf v' v'
a = n | c | var | pf v' v' | r v[] --- (atomic values)
v = a[] | m v[]

Quantifiers:
Q = ∀ | ∃ | ∀_SEQ

Maps:
m = filter vf | extent vf | sort vf | map vf

Reduces
Reduces (v[]) => v
r = count | range | sum | min | max | mean | median | mode | std --- range is wrong

Predicates (v, v) => T | F
Expand Down
107 changes: 74 additions & 33 deletions src/lib/LintLanguage.test.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,84 @@
import { expect, test } from "vitest";
import LLEval from "./lint-language";
import { LLEval, prettyPrintLL } from "./ugh";

test("LintLanguage basic eval ", async () => {
const colors = [
{ nodeType: "Color", value: "#005ebe" },
{ nodeType: "Color", value: "#5260d1" },
{ nodeType: "Color", value: "#005ebe" },
];
const exampleProgramWithAnnotations = {
nodeType: "Predicate",
type: "gt",
left: {
nodeType: "Reduce",
type: "count",
input: {
nodeType: "Variable",
value: "colors",
},
function: {
nodeType: "ValueFunction",
type: "channel",
space: "string",
input: {
nodeType: "Color",
value: "lab",
test("LintLanguage basic eval ", () => {
const colors = ["#005ebe", "#5260d1", "#005ebe"];
// eval with no references
const prog1 = { "<": { left: { count: colors }, right: 2 } };
expect(LLEval(prog1, colors)).toBe(false);
expect(prettyPrintLL(prog1)).toBe("count([#005ebe, #5260d1, #005ebe]) < 2");

const prog2 = { "<": { left: { count: colors }, right: 10 } };
expect(LLEval(prog2, colors)).toBe(true);
expect(prettyPrintLL(prog2)).toBe("count([#005ebe, #5260d1, #005ebe]) < 10");

// eval with main reference
const prog3 = { "<": { left: { count: "colors" }, right: 2 } };
expect(LLEval(prog3, colors)).toBe(false);
expect(prettyPrintLL(prog3)).toBe("count(colors) < 2");

const prog4 = { "<": { left: { count: "colors" }, right: 10 } };
expect(LLEval(prog4, colors)).toBe(true);
expect(prettyPrintLL(prog4)).toBe("count(colors) < 10");
});

test.only("LintLanguage Quantifiers", () => {
const colorBlind = {
all: {
input: "colors",
value: "a",
predicate: {
all: {
input: "colors",
value: "b",
predicate: {
not: {
"==": {
left: { cvd_sim: "a", type: "deuteranopia" },
right: { cvd_sim: "b", type: "deuteranopia" },
},
},
},
},
},
},
right: {
nodeType: "LLNumber",
value: 2,
},
};
const result = LLEval(exampleProgramWithAnnotations, colors);
expect(result).toBe(false);
// const colorBlind = {
// not: {
// exist: {
// input: "colors",
// value: "a",
// predicate: {
// exist: {
// input: "colors",
// value: "b",
// predicate: {
// not: {
// "!=": {
// left: { cvd_sim: "a", type: "deuteranopia" },
// right: { cvd_sim: "b", type: "deuteranopia" },
// },
// },
// },
// },
// },
// },
// },
// };
expect(LLEval(colorBlind, ["#005ebe", "#5260d1", "#005ebe"])).toBe(false);
});

// YAML VERSION
// <:
// left: {count: colors}
// right: {value: 10}
// all:
// input: colors,
// value: 'a',
// predicate:
// all:
// colors,
// value: 'b',
// predicate:
// not:
// equal:
// left: {cvd_sim: 'a', type: 'deuteranopia'}
// right: {cvd_sim: 'b', type: 'deuteranopia'}
// JSON VERSION
49 changes: 29 additions & 20 deletions src/lib/lint-language.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ interface Predicate {
interface Quantifier {
nodeType: "Quantifier";
type: "exists" | "forall" | "forall-seq";
input: Value;
input: Value[];
predicate: Predicate;
value: Variable;
}
Expand Down Expand Up @@ -123,16 +123,7 @@ const evalPredicate: Evaluator<Predicate> = (predicate, env) => {
return [evalValue(left, env) <= evalValue(right, env), env];
}
};
const evalQuantifier: Evaluator<Quantifier> = (quantifier, env) => {
switch (quantifier.type) {
case "exists":
return evalExists(quantifier, env);
case "forall":
return evalForAll(quantifier, env);
case "forall-seq":
return evalForAllSeq(quantifier, env);
}
};

// this is wrong circle back
const evalValue: Evaluator<Value> = (value, env: Environment) => [
value.value,
Expand All @@ -143,11 +134,24 @@ const evalVariable: Evaluator<Variable> = (variable, env) => [
env.variables[variable.value],
env,
];

const evalQuantifier: Evaluator<Quantifier> = (quantifier, env) => {
switch (quantifier.type) {
case "exists":
return evalExists(quantifier, env);
case "forall":
return evalForAll(quantifier, env);
case "forall-seq":
return evalForAllSeq(quantifier, env);
}
};
const evalExists: Evaluator<Quantifier> = (quantifier, env) => {
const inputEval = evalValue(input, env);
const predicate = quantifier.predicate;
const predicateEval = evalPredicate(predicate, env, inputEval, value);
return [predicateEval, env];
const inputEval = quantifier.input.map((x) => evaluate(x, env));
const variable = quantifier.value.value;
const result = inputEval.some(
(x) => evalPredicate(quantifier.predicate, setVar(variable, x, env))[0]
);
return [result, env];
};

const evalForAll: Evaluator<Quantifier> = (_q, env) => {
Expand All @@ -160,9 +164,14 @@ const evalForAllSeq: Evaluator<Quantifier> = (_q, env) => {
};
const evalConditional: Evaluator<Conditional> = (expression, env) => {
const condition = evalExpression(expression.condition, env);
const result = evalExpression(
condition[0] ? expression.then : expression.else,
env
);
return [result, env];
return evalExpression(condition[0] ? expression.then : expression.else, env);
};

const setVar = (
varName: string,
value: Value,
env: Environment
): Environment => ({
...env,
variables: { ...env.variables, [varName]: value },
});
Loading

0 comments on commit 93d1585

Please sign in to comment.