use of suite.node.Node in project suite by stupidsing.
the class CompileBinderImpl method binder.
public Bind_ binder(Node node) {
FunCreator<Bind_> fc = FunCreator.of(Bind_.class, false);
return fc.create(new BinOp<>() {
private FunExpr env, trail, b;
public FunExpr apply(FunExpr bindEnv, FunExpr target) {
this.env = bindEnv.field("env");
this.trail = bindEnv.field("trail");
return f.declare(ok, b -> {
this.b = b;
return compile_(node, target);
});
}
private FunExpr compile_(Node node, FunExpr target) {
FunExpr br = bind(f.object_(node, Node.class), target);
FunExpr brc = bindClone(node, target);
return new //
SwitchNode<FunExpr>(//
node).applyIf(Atom.class, n -> {
return f.ifEquals(target, f.object(node), ok, br);
}).applyIf(Int.class, n -> {
return f.ifInstance(Int.class, target, i -> f.ifEquals(i.field("number"), f.int_(n.number), ok, fail), br);
}).applyIf(Reference.class, n -> {
FunExpr ref = env.field("refs").index(f.int_(mapper().computeIndex(n)));
return f.invokeStatic(Binder.class, "bind", target, ref.cast_(Node.class), trail);
}).applyIf(Str.class, n -> {
return f.ifInstance(Str.class, target, s -> f.object(n.value).invoke("equals", s.field("value").cast_(Object.class)), br);
}).applyIf(Tree.class, tree -> {
return f.declare(f.invokeStatic(Tree.class, "decompose", target, f.object(tree.getOperator())), t -> {
Node lt = tree.getLeft();
Node rt = tree.getRight();
return f.ifNonNull(t, compile_(lt, t.invoke("getLeft"), compile_(rt, t.invoke("getRight"), ok)), brc);
});
}).applyIf(Tuple.class, n -> {
return f.ifInstance(Tuple.class, target, tuple -> f.declare(tuple.field("nodes"), targets -> {
Node[] nodes = n.nodes;
FunExpr fe = ok;
for (int i = 0; i < nodes.length; i++) fe = compile_(nodes[i], targets.index(f.int_(i)), fe);
return f.if_(targets.length(), fe, brc);
}), brc);
}).applyIf(Node.class, n -> {
Clone_ cloner = cloner(n);
return f.invokeStatic(Binder.class, "bind", target, f.object(cloner).invoke("apply", env), trail);
}).nonNullResult();
}
private FunExpr compile_(Node node, FunExpr target, FunExpr cps) {
return f.assign(b, compile_(node, target), f.if_(b, cps, fail));
}
private FunExpr bindClone(Node node, FunExpr target) {
if (isBindTrees)
return bind(f.object(cloner(node)).apply(env), target);
else
return fail;
}
private FunExpr bind(FunExpr node, FunExpr target) {
return f.ifInstanceAnd(Reference.class, target, ref -> f.seq(trail.invoke("addBind", ref, node), ok));
}
}).apply(Map.ofEntries());
}
use of suite.node.Node in project suite by stupidsing.
the class CompileClonerImpl method cloner.
@Override
public Clone_ cloner(Node node) {
FunCreator<Clone_> fc = FunCreator.of(Clone_.class, false);
return fc.create(new Iterate<>() {
private FunExpr env;
public FunExpr apply(FunExpr env) {
this.env = env;
return compile_(node);
}
private FunExpr compile_(Node node_) {
return new //
SwitchNode<FunExpr>(//
node_).applyIf(Atom.class, n -> {
return f.object(node_);
}).applyIf(Dict.class, n -> {
FunExpr[] exprs = //
Read.from2(//
n.map).map(//
(key, value) -> f.invokeStatic(Pair.class, "of", compile_(key), compile_(value))).toArray(FunExpr.class);
return f.invokeStatic(Dict.class, "of", f.array(Pair.class, exprs));
}).applyIf(Int.class, n -> {
return f.object(node_);
}).applyIf(Reference.class, n -> {
return env.field("refs").index(f.int_(vm.computeIndex(n)));
}).applyIf(Str.class, n -> {
return f.object(node_);
}).applyIf(Tree.class, tree -> {
FunExpr fe0 = compile_(tree.getLeft()).cast_(Node.class);
FunExpr fe1 = compile_(tree.getRight()).cast_(Node.class);
return f.invokeStatic(Tree.class, "of", f.object(tree.getOperator()), fe0, fe1);
}).applyIf(Tuple.class, n -> {
FunExpr[] exprs = Read.from(n.nodes).map(this::compile_).toArray(FunExpr.class);
return f.invokeStatic(Tuple.class, "of", f.array(Node.class, exprs));
}).nonNullResult();
}
}).apply(Map.ofEntries());
}
use of suite.node.Node in project suite by stupidsing.
the class CompileProverImpl method prover.
@Override
public Prove_ prover(Node node) {
FunExpr rt = f.input();
Fun<FunExpr, ProveRt> cf = cps -> FunCreator.of(ProveRt.class, false).create(rt_ -> cps).apply(Map.ofEntries());
FunExpr compiled = new Object() {
private FunExpr compile_(Node node, FunExpr cps) {
return new //
SwitchNode<FunExpr>(//
node).match(".0, .1", m -> {
return compile_(m[0], compile_(m[1], cps));
}).match(".0; .1", m -> {
FunExpr cps1;
if (Boolean.TRUE) {
ProveRt proveRt_ = cf.apply(cps);
cps1 = f.object(proveRt_).invoke("test", rt);
} else
cps1 = cps;
FunExpr f0 = compile_(m[0], cps1);
FunExpr f1 = compile_(m[1], cps1);
return f.seq(f0, f1);
}).match("fail", m -> {
return f._void();
}).match("yes", m -> {
return cps;
}).nonNullResult();
}
}.compile_(node, rt.fieldSet("ok", ok));
ProveRt proveRt = cf.apply(compiled);
return proverConfig -> {
Runtime_ rt_ = new Runtime_();
rt_.proverConfig = proverConfig;
proveRt.test(rt_);
return rt_.ok;
};
}
use of suite.node.Node in project suite by stupidsing.
the class ProveTracer method expandWithTrace.
public Node expandWithTrace(Node query, Prover prover, Iterate<Node> expand) {
Node query1 = new Cloner().clone(query);
if (currentDepth < 64) {
Record record0 = currentRecord;
int depth0 = currentDepth;
Record record = new Record(record0, query1, currentDepth + 1);
Data<Source<Boolean>> enter = new Data<>(() -> {
currentRecord = record;
currentDepth = record.depth;
record.start = records.size();
records.add(record);
return Boolean.TRUE;
});
Data<Source<Boolean>> leaveOk = new Data<>(() -> {
currentRecord = record0;
currentDepth = depth0;
record.nOkays++;
return Boolean.TRUE;
});
Data<Source<Boolean>> leaveFail = new Data<>(() -> {
currentRecord = record0;
currentDepth = depth0;
record.end = records.size();
return Boolean.FALSE;
});
Node alt = prover.getAlternative();
Node rem = prover.getRemaining();
prover.setAlternative(Tree.of(TermOp.OR____, leaveFail, alt));
prover.setRemaining(Tree.of(TermOp.AND___, leaveOk, rem));
query = expand.apply(query);
query = Tree.of(TermOp.AND___, enter, query);
} else
query = expand.apply(query);
return query;
}
use of suite.node.Node in project suite by stupidsing.
the class Prover method prove0.
public boolean prove0(Node query) {
rem = OK;
alt = FAIL;
while (true) {
// logUtil.info(Formatter.dump(query));
query = query.finalNode();
if (query instanceof Tree) {
Tree tree = (Tree) query;
Node left = tree.getLeft(), right = tree.getRight();
switch((TermOp) tree.getOperator()) {
case OR____:
int pit = trail.getPointInTime();
Node bt = new Data<Source<Boolean>>(() -> {
trail.unwind(pit);
return Boolean.TRUE;
});
alt = andTree(bt, orTree(andTree(right, rem), alt));
query = left;
continue;
case AND___:
rem = andTree(right, rem);
query = left;
continue;
case EQUAL_:
query = isSuccess(bind(left, right));
break;
default:
}
} else if (query instanceof Data) {
query = isSuccess(Data.<Source<Boolean>>get(query).source());
continue;
}
Boolean b = systemPredicates.call(query);
if (b != null)
query = isSuccess(b);
// not handled above
if (query == OK)
if (rem != OK) {
query = rem;
rem = OK;
} else
return true;
else if (query == FAIL)
if (alt != FAIL) {
query = alt;
alt = FAIL;
rem = OK;
} else
return false;
else {
boolean isTrace = config.isTrace();
if (isTrace) {
Set<String> whites = Suite.tracePredicates;
Set<String> blacks = Suite.noTracePredicates;
Prototype prototype = Prototype.of(query);
Node head = prototype != null ? prototype.head : null;
Atom atom = head instanceof Atom ? (Atom) head : null;
String name = atom != null ? atom.name : null;
isTrace &= whites == null || whites.contains(name);
isTrace &= blacks == null || !blacks.contains(name);
}
if (!isTrace)
query = expand(query);
else
query = tracer.expandWithTrace(query, this, this::expand);
}
}
}
Aggregations