Commit 07ce4b10 authored by Martin Spoto's avatar Martin Spoto
Browse files

Redo implementation (buggy)

parent f1951ce3
......@@ -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 = false;
public static final boolean DEBUG_MODE = true;
static {
if(DEBUG_MODE) {
......
......@@ -15,92 +15,128 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.stream.Collectors;
public class ProloGraalInterpreterNode extends RootNode {
private final ProloGraalLanguage language;
private final ProloGraalContext context;
private final ProloGraalLanguage language;
private final ProloGraalContext context;
public ProloGraalInterpreterNode(ProloGraalLanguage language) {
super(language);
this.language = language;
this.context = language.getContextReference().get();
}
public ProloGraalInterpreterNode(ProloGraalLanguage language) {
super(language);
this.language = language;
this.context = language.getContextReference().get();
}
@Override
public Object execute(VirtualFrame frame) {
PrintWriter writer = new PrintWriter(context.getOutput(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(context.getInput(), StandardCharsets.UTF_8));
@Override
public Object execute(VirtualFrame frame) {
PrintWriter writer = new PrintWriter(context.getOutput(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(context.getInput(), StandardCharsets.UTF_8));
while (true) {
Deque<Integer> currentBranches = new ArrayDeque<>();
ProloGraalRuntime lastRuntime = null;
boolean skipParsing = false;
try {
while (true) {
writer.print("?- ");
writer.flush();
String line = reader.readLine();
writer.println();
if (line == null) {
break;
}
if (line.equals("exit.")) {
writer.println("Exiting.");
break;
} else if (line.equals("listing.")) {
writer.println(context.getRuntime().getClauses().values());
continue;
} else if (line.startsWith("listing ")) {
String filter = line.split("[ .]")[1];
writer.println(
context.getRuntime()
.getClauses()
.values()
.stream()
.filter(x -> x.get(0)
.getHead()
.toString()
.startsWith(filter))
.collect(Collectors.toList()));
continue;
} else if (line.equals("redo.")) {
if(lastRuntime == null) {
writer.println("no");
continue;
}
skipParsing = true;
}
Source source = null;
if (!skipParsing) {
// count the line as a list of goals to resolve
line = "goals :- " + line;
currentBranches.clear();
source = Source.newBuilder("pl", line, null).build();
}
ProloGraalRuntime runtime;
try {
writer.print("?- ");
writer.flush();
String line = reader.readLine();
writer.println();
if (line == null) {
break;
}
if (line.equals("exit.")) {
writer.println("Exiting.");
break;
} else if (line.equals("listing.")) {
writer.println(context.getRuntime().getClauses().values());
continue;
} else if (line.startsWith("listing ")) {
String filter = line.split("[ .]")[1];
writer.println(context.getRuntime().getClauses().values().stream().filter(x -> x.get(0).getHead().toString().startsWith(filter)).collect(Collectors.toList()));
continue;
}
// count the line as a list of goals to resolve
line = "goals :- " + line;
Source source = Source.newBuilder("pl", line, null).build();
try {
ProloGraalRuntime runtime = ProloGraalParserImpl.parseProloGraal(language, source);
try {
ProloGraalBoolean callResult = (ProloGraalBoolean) Truffle.getRuntime().createCallTarget(context.getResolverNode()).call(runtime);
writer.println();
if(callResult.asBoolean()) {
ProloGraalSuccess success = (ProloGraalSuccess)callResult;
for(ProloGraalVariable variable : success.getVariables().values()) {
if(variable.isBound()) {
ProloGraalTerm<?> root = variable.getRootValue();
String rootStr;
if(root instanceof ProloGraalStructure) {
rootStr = ((ProloGraalStructure) root).toRootString();
} else {
rootStr = root.toString();
}
writer.println(variable.getName() + " = " + rootStr);
}
}
}
writer.println();
writer.println(callResult);
} catch(ProloGraalExistenceError existenceError) {
writer.println("Error : no clause for goal '" + existenceError.getMessage() + "'");
}
} catch(ProloGraalParseError parseError) {
writer.println(parseError.getMessage());
}
} catch ( IOException ex) {
break;
}
}
try {
reader.close();
} catch(IOException ex) {
// ignored
}
return new ProloGraalSuccess();
}
if (!skipParsing) {
runtime = ProloGraalParserImpl.parseProloGraal(language, source);
lastRuntime = runtime;
} else {
runtime = lastRuntime;
}
} catch (ProloGraalParseError parseError) {
lastRuntime = null;
writer.println(parseError.getMessage());
continue;
}
ProloGraalBoolean callResult;
try {
skipParsing = false;
callResult =
(ProloGraalBoolean) Truffle.getRuntime().createCallTarget(context.getResolverNode()).call(runtime, currentBranches);
if(currentBranches.isEmpty()) {
lastRuntime = null;
}
} catch (ProloGraalExistenceError existenceError) {
writer.println("Error : no clause for goal '" + existenceError.getMessage() + "'");
continue;
}
writer.println();
if (callResult.asBoolean()) {
ProloGraalSuccess success = (ProloGraalSuccess) callResult;
for (ProloGraalVariable variable : success.getVariables().values()) {
if (variable.isBound()) {
ProloGraalTerm<?> root = variable.getRootValue();
String rootStr;
if (root instanceof ProloGraalStructure) {
rootStr = ((ProloGraalStructure) root).toRootString();
} else {
rootStr = root.toString();
}
writer.println(variable.getName() + " = " + rootStr);
}
}
}
writer.println();
writer.println(callResult);
}
reader.close();
} catch (IOException ex) {
// ignored
}
return new ProloGraalSuccess();
}
}
\ No newline at end of file
......@@ -14,8 +14,6 @@ public class ProloGraalProofTreeNode extends Node {
private final Map<ProloGraalTerm<?>, List<ProloGraalClause>> clauses;
private final Deque<ProloGraalTerm<?>> goals;
@Children
private ProloGraalProofTreeNode[] branches;
public ProloGraalProofTreeNode(Map<ProloGraalTerm<?>, List<ProloGraalClause>> clauses, Deque<ProloGraalTerm<?>> goals) {
this.clauses = clauses;
......@@ -23,7 +21,7 @@ public class ProloGraalProofTreeNode extends Node {
}
@TruffleBoundary
public ProloGraalBoolean execute() {
public ProloGraalBoolean execute(Deque<Integer> branches) {
if(ProloGraalLanguage.DEBUG_MODE) {
System.out.println("ProofTreeNode : " + goals);
......@@ -38,15 +36,18 @@ public class ProloGraalProofTreeNode extends Node {
if(possibleClauses == null || possibleClauses.isEmpty()) // if no match, throw an error
throw new ProloGraalExistenceError(currentGoal);
List<ProloGraalProofTreeNode> branches = new ArrayList<>();
int start = 0;
if(branches.size() > 0) {
start = branches.pop();
}
for(ProloGraalClause possibleClauseOriginal : possibleClauses) {
ProloGraalClause possibleClause = possibleClauseOriginal.copy();
for (int i = start; i < possibleClauses.size(); i++) {
ProloGraalClause possibleClause = possibleClauses.get(i).copy();
currentGoal.save();
// if the head of the clause is unifiable with the current goal
if(possibleClause.getHead().unify(currentGoal)) {
if (possibleClause.getHead().unify(currentGoal)) {
if (ProloGraalLanguage.DEBUG_MODE) {
System.out.println("Unified " + currentGoal + " with " + possibleClause.getHead());
}
......@@ -64,7 +65,13 @@ public class ProloGraalProofTreeNode extends Node {
Collections.reverse(body);
body.forEach(newGoals::addFirst);
if(new ProloGraalProofTreeNode(clauses, newGoals).execute().asBoolean()) {
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
}
return new ProloGraalSuccess();
}
} else {
......@@ -75,16 +82,6 @@ public class ProloGraalProofTreeNode extends Node {
// undo all changes that the unification may have done
currentGoal.undo();
}
/*
this.branches = new ProloGraalProofTreeNode[branches.size()];
// insert tree branches to the AST
this.branches = this.insert(branches.toArray(this.branches));
for (ProloGraalProofTreeNode branch : branches) {
ProloGraalBoolean r = branch.execute(frame);
if(r.asBoolean())
return r;
}*/
return new ProloGraalFailure();
}
......
......@@ -6,10 +6,7 @@ import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.nodes.RootNode;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.*;
@NodeInfo(language = "Prolog", description = "Root node that spawns a proof tree")
public final class ProloGraalResolverNode extends RootNode {
......@@ -29,17 +26,20 @@ public final class ProloGraalResolverNode extends RootNode {
@Override
public Object execute(VirtualFrame frame) {
ProloGraalRuntime goalRuntime = (ProloGraalRuntime) frame.getArguments()[0];
@SuppressWarnings("unchecked")
Deque<Integer> branches = (Deque<Integer>) frame.getArguments()[1];
if (ProloGraalLanguage.DEBUG_MODE) {
System.out.println("Executing : " + goalRuntime.getFirstClause());
System.out.println("Branches : " + branches);
}
ProloGraalClause clause = goalRuntime.getFirstClause();
ProloGraalClause clause = goalRuntime.getFirstClause().copy();
Deque<ProloGraalTerm<?>> goals = new ArrayDeque<>(clause.getGoals());
ProloGraalProofTreeNode proofTreeNode = new ProloGraalProofTreeNode(clauses, goals);
treeNode = this.insert(proofTreeNode); // FIXME handle multiples goals
treeNode = this.insert(proofTreeNode);
ProloGraalBoolean r = treeNode.execute();
ProloGraalBoolean r = treeNode.execute(branches);
if(r.asBoolean()) {
r = new ProloGraalSuccess(clause.getVariables());
......
package ch.heiafr.prolograal.runtime;
import ch.heiafr.prolograal.builtins.ProloGraalBuiltinAtoms;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import ch.heiafr.prolograal.builtins.ProloGraalBuiltinAtoms;
public class ProloGraalList extends ProloGraalStructure {
......@@ -83,10 +82,10 @@ public class ProloGraalList extends ProloGraalStructure {
@Override
public ProloGraalList copy(Map<ProloGraalVariable, ProloGraalVariable> variables) {
ProloGraalList list = new ProloGraalList(variables);
list.tail = this.tail.copy(variables);
for(ProloGraalTerm<?> item : this.items) {
list.addItem(item.copy(variables));
}
list.tail = this.tail.copy(variables);
list.buildInteralRepresentation();
return list;
}
......
multifacts(X).
redo.
redo.
redo.
listPrefix([a,b,c,d], X).
redo.
redo.
redo.
redo.
redo.
testWrite.
redo.
\ No newline at end of file
% multifacts(X).
X = a
yes
% redo.
X = b
yes
% redo.
X = c
yes
% redo.
no
% listPrefix([a,b,c,d], X).
X = [a, b, c, d]
yes
% redo.
X = [a, b, c]
yes
% redo.
X = [a, b]
yes
% redo.
X = [a]
yes
% redo.
X = []
yes
% redo.
no
% testWrite.
abc
yes
% redo.
d
yes
% EOF
yes
\ No newline at end of file
multifacts(a).
multifacts(b).
multifacts(c).
% --- listPrefix(+L, ?P) : P is a prefix of L
listPrefix([X|Xs],[X|Ys]) :- listPrefix(Xs,Ys).
listPrefix(_, []).
testWrite :-
t(X),
write(X),
end(X).
t(a).
t(b).
t(c).
t(d).
end(c).
end(d).
\ No newline at end of file
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