Commit 22799dc6 authored by Martin Spoto's avatar Martin Spoto
Browse files

Redo bug fixes (with ugly workarounds)

parent 07ce4b10
......@@ -32,7 +32,7 @@ public class ProloGraalLanguage extends TruffleLanguage<ProloGraalContext> {
public static final String ID = "pl";
public static final String MIME_TYPE = "application/x-prolog";
public static final boolean DEBUG_MODE = true;
public static final boolean DEBUG_MODE = false;
static {
if(DEBUG_MODE) {
......
package ch.heiafr.prolograal.builtins.predicates;
import ch.heiafr.prolograal.runtime.ProloGraalClause;
public abstract class ProloGraalBultinClause extends ProloGraalClause {
public void execute() {
// default behaviour is to do nothing...
}
@Override
public abstract ProloGraalClause copy();
}
......@@ -7,7 +7,7 @@ import java.util.Map;
/**
* @see ProloGraalRuntime
*/
public class ProloGraalVarBuiltin extends ProloGraalClause {
public class ProloGraalVarBuiltin extends ProloGraalBultinClause {
protected static class VarPredicateHead extends ProloGraalStructure {
......@@ -40,4 +40,9 @@ public class ProloGraalVarBuiltin extends ProloGraalClause {
VarPredicateHead head = new VarPredicateHead(getVariables());
setHead(head);
}
@Override
public ProloGraalClause copy() {
return new ProloGraalVarBuiltin();
}
}
......@@ -8,34 +8,24 @@ import java.util.Map;
/**
* @see ProloGraalRuntime
*/
public class ProloGraalWriteBuiltin extends ProloGraalClause {
public class ProloGraalWriteBuiltin extends ProloGraalBultinClause {
private final PrintWriter writer;
private final ProloGraalContext context;
private ProloGraalVariable arg;
private class WritePredicateHead extends ProloGraalStructure {
public WritePredicateHead(Map<ProloGraalVariable, ProloGraalVariable> variables) {
super(variables);
setFunctor(new ProloGraalAtom(variables, "write"));
addSubterm(new ProloGraalVariable(variables, "_"));
arg = new ProloGraalVariable(variables, "_");
addSubterm(arg);
}
@Override
public boolean unify(ProloGraalTerm<?> other) {
if(other instanceof ProloGraalStructure) {
ProloGraalStructure struct = (ProloGraalStructure)other;
if(struct.getFunctor().equals(getFunctor()) && struct.getArity() == 1) {
String str = struct.getArguments().get(0).getRootValue().toString();
if(str.startsWith("'") && str.endsWith("'")) {
// strip single quotes
str = str.substring(1, str.length()-1);
}
writer.print(str);
writer.flush();
return true;
}
}
return false;
return super.unify(other);
}
@Override
......@@ -47,7 +37,25 @@ public class ProloGraalWriteBuiltin extends ProloGraalClause {
public ProloGraalWriteBuiltin(ProloGraalContext context) {
super();
this.writer = new PrintWriter(context.getOutput(), true);
this.context = context;
WritePredicateHead head = new WritePredicateHead(getVariables());
setHead(head);
}
@Override
public void execute() {
String str = arg.getRootValue().toString();
if(str.startsWith("'") && str.endsWith("'")) {
// strip single quotes
str = str.substring(1, str.length()-1);
}
writer.print(str);
writer.flush();
}
@Override
public ProloGraalClause copy() {
return new ProloGraalWriteBuiltin(context);
}
}
package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.ProloGraalLanguage;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalBultinClause;
import ch.heiafr.prolograal.exceptions.ProloGraalExistenceError;
import ch.heiafr.prolograal.runtime.*;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
......@@ -8,6 +9,8 @@ import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@NodeInfo(shortName = "ProofTreeNode")
public class ProloGraalProofTreeNode extends Node {
......@@ -41,43 +44,56 @@ public class ProloGraalProofTreeNode extends Node {
start = branches.pop();
}
for (int i = start; i < possibleClauses.size(); i++) {
ProloGraalClause possibleClause = possibleClauses.get(i).copy();
// filter clauses that are unifiable with the current goal
List<ProloGraalClause> unifiableClauses =
IntStream.range(0, possibleClauses.size())
.filter(x -> {
ProloGraalClause clause = possibleClauses.get(x).copy();
currentGoal.save();
boolean r = clause.getHead().unify(currentGoal);
currentGoal.undo();
return r;
})
.mapToObj(x -> possibleClauses.get(x).copy())
.collect(Collectors.toList());
for (int i = start; i < unifiableClauses.size(); i++) {
ProloGraalClause unifiableClause = unifiableClauses.get(i);
currentGoal.save();
// if the head of the clause is unifiable with the current goal
if (possibleClause.getHead().unify(currentGoal)) {
if (ProloGraalLanguage.DEBUG_MODE) {
System.out.println("Unified " + currentGoal + " with " + possibleClause.getHead());
}
// unify the head with the current goal
unifiableClause.getHead().unify(currentGoal);
if (ProloGraalLanguage.DEBUG_MODE) {
System.out.println("Unified " + currentGoal + " with " + unifiableClause.getHead());
}
// create a copy of the current goals
Deque<ProloGraalTerm<?>> newGoals = new ArrayDeque<>(goals);
if(unifiableClause instanceof ProloGraalBultinClause) {
// if the clause is a built-in, execute its internal behaviour
((ProloGraalBultinClause) unifiableClause).execute();
}
List<ProloGraalTerm<?>> body = possibleClause.getGoals();
// create a copy of the current goals
Deque<ProloGraalTerm<?>> newGoals = new ArrayDeque<>(goals);
// always remove the first goal since it will be replaced
newGoals.pollFirst();
List<ProloGraalTerm<?>> body = unifiableClause.getGoals();
// no need for distinction between facts and regular clauses
// add all the new goals
Collections.reverse(body);
body.forEach(newGoals::addFirst);
// always remove the first goal since it will be replaced
newGoals.pollFirst();
if (new ProloGraalProofTreeNode(clauses, newGoals).execute(branches).asBoolean()) {
if(!branches.isEmpty() || i+1 < possibleClauses.size()) { // skip last possible nodes if empty
if(branches.isEmpty()) {
i = i + 1; // if we're at the bottom go directly to next node
}
branches.push(i); // add the path that gave the success
// no need for distinction between facts and regular clauses
// add all the new goals
Collections.reverse(body);
body.forEach(newGoals::addFirst);
if (new ProloGraalProofTreeNode(clauses, newGoals).execute(branches).asBoolean()) {
if(!branches.isEmpty() || i+1 < unifiableClauses.size()) { // skip last possible nodes if empty
if(branches.isEmpty()) {
i = i + 1; // if we're at the bottom go directly to next node
}
return new ProloGraalSuccess();
}
} else {
if (ProloGraalLanguage.DEBUG_MODE) {
System.out.println("Could not unify " + possibleClause.getHead() + " for goal " + currentGoal);
branches.push(i); // add the path that gave the success
}
return new ProloGraalSuccess();
}
// undo all changes that the unification may have done
currentGoal.undo();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment