use of com.googlecode.prolog_cafe.lang.StructureTerm in project gerrit by GerritCodeReview.
the class PrologTestCase method load.
protected void load(String pkg, String prologResource, Module... modules) throws CompileException, IOException {
ArrayList<Module> moduleList = new ArrayList<>();
moduleList.add(new PrologModule.EnvironmentModule());
moduleList.addAll(Arrays.asList(modules));
envFactory = Guice.createInjector(moduleList).getInstance(PrologEnvironment.Factory.class);
PrologEnvironment env = envFactory.create(newMachine());
consult(env, getClass(), prologResource);
this.pkg = pkg;
hasSetup = has(env, "setup");
hasTeardown = has(env, "teardown");
StructureTerm head = new StructureTerm(":", SymbolTerm.intern(pkg), new StructureTerm(test_1, new VariableTerm()));
tests = new ArrayList<>();
for (Term[] pair : env.all(Prolog.BUILTIN, "clause", head, new VariableTerm())) {
tests.add(pair[0]);
}
assertThat(tests).isNotEmpty();
machine = PrologMachineCopy.save(env);
}
use of com.googlecode.prolog_cafe.lang.StructureTerm in project gerrit by GerritCodeReview.
the class PrologTestCase method runPrologBasedTests.
public void runPrologBasedTests() throws Exception {
int errors = 0;
long start = TimeUtil.nowMs();
for (Term test : tests) {
PrologEnvironment env = envFactory.create(machine);
setUpEnvironment(env);
env.setEnabled(Prolog.Feature.IO, true);
System.out.format("Prolog %-60s ...", removePackage(test));
System.out.flush();
if (hasSetup) {
call(env, "setup");
}
List<Term> all = env.all(Prolog.BUILTIN, "call", test);
if (hasTeardown) {
call(env, "teardown");
}
System.out.println(all.size() == 1 ? "OK" : "FAIL");
if (all.size() > 0 && !test.equals(all.get(0))) {
for (Term t : all) {
Term head = ((StructureTerm) removePackage(t)).args()[0];
Term[] args = ((StructureTerm) head).args();
System.out.print(" Result: ");
for (int i = 0; i < args.length; i++) {
if (0 < i) {
System.out.print(", ");
}
System.out.print(args[i]);
}
System.out.println();
}
System.out.println();
}
if (all.size() != 1) {
errors++;
}
}
long end = TimeUtil.nowMs();
System.out.println("-------------------------------");
System.out.format("Prolog tests: %d, Failures: %d, Time elapsed %.3f sec", tests.size(), errors, (end - start) / 1000.0);
System.out.println();
assertThat(errors).isEqualTo(0);
}
use of com.googlecode.prolog_cafe.lang.StructureTerm in project gerrit by GerritCodeReview.
the class PRED_current_user_2 method createUser.
public Term createUser(Prolog engine, Term key) {
if (!(key instanceof StructureTerm) || key.arity() != 1 || !((StructureTerm) key).functor().equals(user)) {
throw new IllegalTypeException(this, 1, "user(int)", key);
}
Term idTerm = key.arg(0);
CurrentUser user;
if (idTerm instanceof IntegerTerm) {
Map<Account.Id, IdentifiedUser> cache = StoredValues.USERS.get(engine);
Account.Id accountId = new Account.Id(((IntegerTerm) idTerm).intValue());
user = cache.get(accountId);
if (user == null) {
IdentifiedUser.GenericFactory userFactory = userFactory(engine);
IdentifiedUser who = userFactory.create(accountId);
cache.put(accountId, who);
user = who;
}
} else if (idTerm.equals(anonymous)) {
user = StoredValues.ANONYMOUS_USER.get(engine);
} else {
throw new IllegalTypeException(this, 1, "user(int)", key);
}
return new JavaObjectTerm(user);
}
use of com.googlecode.prolog_cafe.lang.StructureTerm in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method resultsToSubmitRecord.
/**
* Convert the results from Prolog Cafe's format to Gerrit's common format.
*
* <p>can_submit/1 terminates when an ok(P) record is found. Therefore walk the results backwards,
* using only that ok(P) record if it exists. This skips partial results that occur early in the
* output. Later after the loop the out collection is reversed to restore it to the original
* ordering.
*/
public SubmitRecord resultsToSubmitRecord(Term submitRule, List<Term> results) {
checkState(!results.isEmpty(), "the list of Prolog terms must not be empty");
SubmitRecord resultSubmitRecord = new SubmitRecord();
resultSubmitRecord.labels = new ArrayList<>();
for (int resultIdx = results.size() - 1; 0 <= resultIdx; resultIdx--) {
Term submitRecord = results.get(resultIdx);
if (!(submitRecord instanceof StructureTerm) || 1 != submitRecord.arity()) {
return invalidResult(submitRule, submitRecord);
}
if (!"ok".equals(submitRecord.name()) && !"not_ready".equals(submitRecord.name())) {
return invalidResult(submitRule, submitRecord);
}
// the change to be submittable when at least one result is OK.
if ("ok".equals(submitRecord.name())) {
resultSubmitRecord.status = SubmitRecord.Status.OK;
} else if ("not_ready".equals(submitRecord.name()) && resultSubmitRecord.status == null) {
resultSubmitRecord.status = SubmitRecord.Status.NOT_READY;
}
// Unpack the one argument. This should also be a structure with one
// argument per label that needs to be reported on to the caller.
//
submitRecord = submitRecord.arg(0);
if (!(submitRecord instanceof StructureTerm)) {
return invalidResult(submitRule, submitRecord);
}
for (Term state : ((StructureTerm) submitRecord).args()) {
if (!(state instanceof StructureTerm) || 2 != state.arity() || !"label".equals(state.name())) {
return invalidResult(submitRule, submitRecord);
}
SubmitRecord.Label lbl = new SubmitRecord.Label();
resultSubmitRecord.labels.add(lbl);
lbl.label = checkLabelName(state.arg(0).name());
Term status = state.arg(1);
try {
if ("ok".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.OK;
appliedBy(lbl, status);
} else if ("reject".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.REJECT;
appliedBy(lbl, status);
} else if ("need".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.NEED;
} else if ("may".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.MAY;
} else if ("impossible".equals(status.name())) {
lbl.status = SubmitRecord.Label.Status.IMPOSSIBLE;
} else {
return invalidResult(submitRule, submitRecord);
}
} catch (UserTermExpected e) {
return invalidResult(submitRule, submitRecord, e.getMessage());
}
}
if (resultSubmitRecord.status == SubmitRecord.Status.OK) {
break;
}
}
Collections.reverse(resultSubmitRecord.labels);
return resultSubmitRecord;
}
use of com.googlecode.prolog_cafe.lang.StructureTerm in project gerrit by GerritCodeReview.
the class RulesCache method consultRules.
private PrologMachineCopy consultRules(String name, Reader rules) throws CompileException {
BufferingPrologControl ctl = newEmptyMachine(systemLoader);
PushbackReader in = new PushbackReader(rules, Prolog.PUSHBACK_SIZE);
try {
if (!ctl.execute(Prolog.BUILTIN, "consult_stream", SymbolTerm.intern(name), new JavaObjectTerm(in))) {
return null;
}
} catch (SyntaxException e) {
throw new CompileException(e.toString(), e);
} catch (TermException e) {
Term m = e.getMessageTerm();
if (m instanceof StructureTerm && "syntax_error".equals(m.name()) && m.arity() >= 1) {
StringBuilder msg = new StringBuilder();
if (m.arg(0) instanceof ListTerm) {
msg.append(Joiner.on(' ').join(((ListTerm) m.arg(0)).toJava()));
} else {
msg.append(m.arg(0).toString());
}
if (m.arity() == 2 && m.arg(1) instanceof StructureTerm && "at".equals(m.arg(1).name())) {
Term at = m.arg(1).arg(0).dereference();
if (at instanceof ListTerm) {
msg.append(" at: ");
msg.append(prettyProlog(at));
}
}
throw new CompileException(msg.toString(), e);
}
throw new CompileException("Error while consulting rules from " + name, e);
} catch (RuntimeException e) {
throw new CompileException("Error while consulting rules from " + name, e);
}
return save(ctl);
}
Aggregations