Commit cce8d7ff authored by Martin Spoto's avatar Martin Spoto
Browse files

Add var and write builtins

parent 848b93b4
package ch.heiafr.prolograal.builtins.predicates;
import ch.heiafr.prolograal.runtime.*;
import java.util.Map;
/**
* @see ProloGraalRuntime
*/
public class ProloGraalVarBuiltin extends ProloGraalClause {
protected static class VarPredicateHead extends ProloGraalStructure {
public VarPredicateHead(Map<ProloGraalVariable, ProloGraalVariable> variables) {
super(variables);
setFunctor(new ProloGraalAtom(variables, "var"));
addSubterm(new ProloGraalVariable(variables, "_"));
}
@Override
public boolean unify(ProloGraalTerm<?> other) {
if(other instanceof ProloGraalStructure) {
ProloGraalStructure struct = (ProloGraalStructure)other;
if(struct.getFunctor().equals(getFunctor()) && struct.getArity() == 1) {
//arg.unify(struct.getArguments().get(0));
return struct.getArguments().get(0).getRootValue() instanceof ProloGraalVariable;
}
}
return false;
}
@Override
public ProloGraalStructure copy(Map<ProloGraalVariable, ProloGraalVariable> variables) {
return new VarPredicateHead(variables);
}
}
public ProloGraalVarBuiltin() {
super();
VarPredicateHead head = new VarPredicateHead(getVariables());
setHead(head);
}
}
package ch.heiafr.prolograal.builtins.predicates;
import ch.heiafr.prolograal.runtime.*;
import java.io.PrintWriter;
import java.util.Map;
/**
* @see ProloGraalRuntime
*/
public class ProloGraalWriteBuiltin extends ProloGraalClause {
private final PrintWriter writer;
private class WritePredicateHead extends ProloGraalStructure {
public WritePredicateHead(Map<ProloGraalVariable, ProloGraalVariable> variables) {
super(variables);
setFunctor(new ProloGraalAtom(variables, "write"));
addSubterm(new ProloGraalVariable(variables, "_"));
}
@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;
}
@Override
public ProloGraalStructure copy(Map<ProloGraalVariable, ProloGraalVariable> variables) {
return new WritePredicateHead(variables);
}
}
public ProloGraalWriteBuiltin(ProloGraalContext context) {
super();
this.writer = new PrintWriter(context.getOutput(), true);
WritePredicateHead head = new WritePredicateHead(getVariables());
setHead(head);
}
}
......@@ -59,28 +59,28 @@ public class ProloGraalInterpreterNode extends RootNode {
Source source = Source.newBuilder("pl", line, null).build();
try {
ProloGraalRuntime runtime = ProloGraalParserImpl.parseProloGraal(language, source);
if(runtime.getClauses().size() == 1) {
try {
ProloGraalBoolean callResult = (ProloGraalBoolean) Truffle.getRuntime().createCallTarget(context.getResolverNode()).call(runtime);
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);
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(callResult);
} catch(ProloGraalExistenceError existenceError) {
writer.println("Error : no clause for goal '" + runtime.getFirstClause() + "'");
}
writer.println();
writer.println(callResult);
} catch(ProloGraalExistenceError existenceError) {
writer.println("Error : no clause for goal '" + runtime.getFirstClause() + "'");
}
} catch(ProloGraalParseError parseError) {
writer.println(parseError.getMessage());
......
......@@ -3,10 +3,13 @@ package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.ProloGraalLanguage;
import ch.heiafr.prolograal.exceptions.ProloGraalExistenceError;
import ch.heiafr.prolograal.runtime.*;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeInfo;
import java.util.*;
@NodeInfo(shortName = "ProofTreeNode")
public class ProloGraalProofTreeNode extends Node {
private final Map<ProloGraalTerm<?>, List<ProloGraalClause>> clauses;
......@@ -19,6 +22,7 @@ public class ProloGraalProofTreeNode extends Node {
this.goals = goals;
}
@TruffleBoundary
public ProloGraalBoolean execute() {
if(ProloGraalLanguage.DEBUG_MODE) {
......@@ -56,9 +60,9 @@ public class ProloGraalProofTreeNode extends Node {
newGoals.pollFirst();
// no need for distinction between facts and regular clauses
for (ProloGraalTerm<?> term : body) {
newGoals.addFirst(term); // add all the new goals
}
// add all the new goals
Collections.reverse(body);
body.forEach(newGoals::addFirst);
if(new ProloGraalProofTreeNode(clauses, newGoals).execute().asBoolean()) {
return new ProloGraalSuccess();
......
......@@ -57,6 +57,6 @@ public class ProloGraalParserImpl {
if(ProloGraalLanguage.DEBUG_MODE)
listener.debug();
return new ProloGraalRuntime(listener.getClauses());
return new ProloGraalRuntime(listener.getClauses(), language.getContextReference().get());
}
}
\ No newline at end of file
package ch.heiafr.prolograal.runtime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalVarBuiltin;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalWriteBuiltin;
import java.util.*;
public final class ProloGraalRuntime {
private final Map<ProloGraalTerm<?>, List<ProloGraalClause>> clauses;
private final ProloGraalContext context;
private ProloGraalClause firstClause;
public ProloGraalRuntime(List<ProloGraalClause> clauseList) {
public ProloGraalRuntime(List<ProloGraalClause> clauseList, ProloGraalContext context) {
this.context = context;
clauses = new HashMap<>();
if(clauseList.size() > 0) {
firstClause = clauseList.get(0);
}
for (int i = 0; i < clauseList.size(); i++) {
clauses.putIfAbsent(clauseList.get(i).getHead(), new ArrayList<>());
List<ProloGraalClause> clauses1 = clauses.get(clauseList.get(i).getHead());
clauses1.add(clauseList.get(i));
}
installBuiltins();
}
private void installBuiltins() {
ProloGraalClause varBuiltin = new ProloGraalVarBuiltin();
clauses.put(varBuiltin.getHead(), Collections.singletonList(varBuiltin));
ProloGraalClause writeBuiltin = new ProloGraalWriteBuiltin(context);
clauses.put(writeBuiltin.getHead(), Collections.singletonList(writeBuiltin));
}
public final Map<ProloGraalTerm<?>, List<ProloGraalClause>> getClauses() {
......@@ -23,7 +40,8 @@ public final class ProloGraalRuntime {
}
public final ProloGraalClause getFirstClause() {
return clauses.values().stream().findFirst().orElseThrow(RuntimeException::new).get(0);
if(firstClause == null) throw new RuntimeException();
return firstClause;
}
}
\ No newline at end of file
var(A).
var(a).
isVar(A).
isVar(a).
linkTest(X).
linkTest2(X).
write(a).
write('test').
write(A).
testWrite.
\ No newline at end of file
% var(A).
yes
% var(a).
no
% isVar(A).
yes
% isVar(a).
no
% linkTest(X).
no
% linkTest2(X).
X = 3
yes
% write(a).
a
yes
% write('test').
test
yes
% write(A).
A
yes
% testWrite.
abc
yes
% EOF
yes
\ No newline at end of file
isVar(X) :-
var(X).
linkTest(X) :-
test(X),
var(X).
linkTest2(X) :-
var(X),
test(X).
test(3).
testWrite :-
t(X),
write(X),
end(X).
t(a).
t(b).
t(c).
end(c).
\ 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