Access Control is now enabled for Gitlab Pages so you can now restrict Pages to authorized users only. If needed, make your website publicly available : Navigate to your project's Settings > General > Visibility and select Everyone in pages section.

Commit 541c7b80 authored by Tony Licata's avatar Tony Licata

Is operators are now casted into ProloGraalIsOpTermNode and executed as...

Is operators are now casted into ProloGraalIsOpTermNode and executed as Truffle nodes, can run benchmark again
parent a168fb7e
......@@ -29,22 +29,6 @@ import java.util.function.Function;
@NodeChild(value = "head", type = ProloGraalBuiltinHeadNode.class)
public abstract class ProloGraalBuiltinClause extends ProloGraalClause implements InstrumentableNode {
private static final Map<String, Function<ProloGraalTerm, ProloGraalBuiltinStructure>> builtinsInitializers = fillBuiltinsInitializers();
private static Map<String, Function<ProloGraalTerm, ProloGraalBuiltinStructure>> fillBuiltinsInitializers(){
Map<String, Function<ProloGraalTerm, ProloGraalBuiltinStructure>> initializers = new HashMap<>();
initializers.put("is", ProloGraalBuiltinClause::initializeIs);
return initializers;
}
public static ProloGraalBuiltinStructure initializeIs(ProloGraalTerm isTerm){
if( !(isTerm.isStructure() && isTerm.asStructure().getArity() == 2) )
return null;
List<ProloGraalTerm<?>> isArgs = isTerm.asStructure().getArguments();
ProloGraalIsHeadNode isBuiltinHead = ProloGraalIsHeadNodeGen.create(isTerm,new ProloGraalSimpleTermNode(isArgs.get(0)),new ProloGraalSimpleTermNode(isArgs.get(1)));
return new ProloGraalBuiltinStructure(isTerm.asStructure(),isBuiltinHead);
}
public ProloGraalBuiltinClause() {
super(new HashMap<>());
}
......@@ -70,11 +54,6 @@ public abstract class ProloGraalBuiltinClause extends ProloGraalClause implement
//public abstract ProloGraalObject executeGeneric(VirtualFrame frame);
public static Map<String, Function<ProloGraalTerm, ProloGraalBuiltinStructure>> getBuiltinsInitializers() {
return builtinsInitializers;
}
/**
* We want the built-ins to override this because otherwise they will lose their "ProloGraalBultinClause" status.
* @return a copy of the built-in
......
......@@ -30,8 +30,7 @@ public abstract class ProloGraalIsHeadNode extends ProloGraalBinaryHeadNode {
public ProloGraalBoolean returnValue(VirtualFrame frame, ProloGraalVariable left, ProloGraalStructure right) {
System.out.println("@Specialization: returnValue");
ProloGraalNumber res = ProloGraalIsBuiltin.getOperations().get(right.asStructure().getFunctor()).apply(right.asStructure().getArguments().stream().map(x -> x.asNumber()).collect(Collectors.toList()));
return value.asStructure().getArguments().get(0).unify(res)?new ProloGraalSuccess(value.getVariables()):new ProloGraalFailure();
//return left.unify(res)?new ProloGraalSuccess(left.getVariables()):new ProloGraalFailure();
return left.unify(res)?new ProloGraalSuccess():new ProloGraalFailure();
}
/*
......@@ -44,8 +43,8 @@ public abstract class ProloGraalIsHeadNode extends ProloGraalBinaryHeadNode {
@Specialization
public ProloGraalBoolean testVariable(VirtualFrame frame, ProloGraalTerm left, ProloGraalTerm right) {
System.out.println("@Specialization: testVariable");
return left.unify(right)||right.unify(left)?new ProloGraalSuccess(left.getVariables()):new ProloGraalFailure();
// System.out.println("@Specialization: testVariable");
return left.unify(right)||right.unify(left)?new ProloGraalSuccess():new ProloGraalFailure();
}
@Override
......@@ -53,6 +52,6 @@ public abstract class ProloGraalIsHeadNode extends ProloGraalBinaryHeadNode {
List<Node> childrens = NodeUtil.findNodeChildren(this);
ProloGraalTermNode left = (ProloGraalTermNode) childrens.get(0);
ProloGraalTermNode right = (ProloGraalTermNode) childrens.get(1);
return ProloGraalIsHeadNodeGen.create(value.copy(variables), new ProloGraalSimpleTermNode(left.value.copy(variables)), new ProloGraalSimpleTermNode(right.value.copy(variables)));
return ProloGraalIsHeadNodeGen.create(value.copy(variables), left.copyTermNode(variables), right.copyTermNode(variables));
}
}
package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalIsBuiltin;
import ch.heiafr.prolograal.runtime.ProloGraalNumber;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import ch.heiafr.prolograal.runtime.*;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.NodeUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.function.Function;
@NodeChild(value = "left", type = ProloGraalTermNode.class)
@NodeChild(value = "right", type = ProloGraalTermNode.class)
public abstract class ProloGraalIsOpTermNode extends ProloGraalTermNode {
public abstract class ProloGraalIsOpTermNode extends ProloGraalTermNode {
private final Function<List<ProloGraalNumber>,ProloGraalNumber> operation;
......@@ -29,19 +28,49 @@ public abstract class ProloGraalIsOpTermNode extends ProloGraalTermNode {
return null;
}*/
@Specialization(guards = {"left == null","right == null"})
public ProloGraalNumber computeNoArgs(VirtualFrame frame, ProloGraalNumber left, ProloGraalNumber right){
@Specialization
public ProloGraalNumber computeNoArgs(VirtualFrame frame, ProloGraalAtom left, ProloGraalAtom right){
return operation.apply(new ArrayList<>());
}
@Specialization(guards = "right == null")
public ProloGraalNumber computeUnary(VirtualFrame frame, ProloGraalNumber left, ProloGraalNumber right){
return operation.apply(Arrays.asList(left));
@Specialization
public ProloGraalNumber computeUnary(VirtualFrame frame, ProloGraalTerm left, ProloGraalAtom right){
return operation.apply(Arrays.asList(left.asNumber()));
}
@Specialization
public ProloGraalNumber computeBinary(VirtualFrame frame, ProloGraalNumber left, ProloGraalNumber right){
return operation.apply(Arrays.asList(left,right));
public ProloGraalNumber computeBinary(VirtualFrame frame, ProloGraalTerm left, ProloGraalTerm right){
return operation.apply(Arrays.asList(left.asNumber(),right.asNumber()));
}
@Override
public ProloGraalTermNode copyTermNode(Map<ProloGraalVariable, ProloGraalVariable> variables) {
List<Node> childrens = NodeUtil.findNodeChildren(this);
ProloGraalTermNode right = null;
ProloGraalTermNode left = null;
if(childrens.size()>0)
left = (ProloGraalTermNode) childrens.get(0);
if(childrens.size()>1)
right = (ProloGraalTermNode) childrens.get(1);
return ProloGraalIsOpTermNodeGen.create(value.copy(variables), left!=null?left.copyTermNode(variables):null, right!=null?right.copyTermNode(variables):null);
}
//special node to handle unary and no args operators
public static class ProloGraalEmptyTermNode extends ProloGraalTermNode{
public ProloGraalEmptyTermNode() {
super(new ProloGraalAtom(new HashMap<>(),"emptyNode"));
}
@Override
public ProloGraalTerm executeTerm(VirtualFrame frame) {
return value;
}
@Override
public ProloGraalTermNode copyTermNode(Map<ProloGraalVariable, ProloGraalVariable> variables) {
return this;
}
}
}
......@@ -106,12 +106,6 @@ public class ProloGraalProofTreeNode extends Node {
+ TRACE_BETWEEN_WHITE_SPACE + TRACE_QUESTION_MARK);
}
if(currentGoal instanceof ProloGraalBuiltinStructure){
returnedValue = ((ProloGraalBuiltinStructure)currentGoal).getBuiltin().executeBuiltin(frame);
executeState = ExecuteState.RETURN;
break;
}
// get the list of all possible clauses based on the name of the predicate
List<ProloGraalClause> possibleClauses = clauses.get(currentGoal);
if (possibleClauses == null || possibleClauses.isEmpty()) // if no match, throw an error
......@@ -166,7 +160,13 @@ public class ProloGraalProofTreeNode extends Node {
// only execute built-in the first time we traverse their nodes
if (branches.isEmpty()) {
if (unifiableClause instanceof ProloGraalBuiltinClause) {
if(currentGoal instanceof ProloGraalBuiltinStructure){
if(!((ProloGraalBuiltinStructure)currentGoal).getBuiltin().executeBuiltin(frame).asBoolean()) {
returnedValue = new ProloGraalFailure();
executeState = ExecuteState.RETURN;
break;
}
}else if (unifiableClause instanceof ProloGraalBuiltinClause) {
// if the clause is a built-in, execute its internal behaviour
if (!((ProloGraalBuiltinClause) unifiableClause).executeBuiltin(frame).asBoolean()) {
//if the builtin don't provide a success, return a failure and break the switch case
......
package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import com.oracle.truffle.api.dsl.Specialization;
import ch.heiafr.prolograal.runtime.ProloGraalVariable;
import com.oracle.truffle.api.frame.VirtualFrame;
import java.util.Map;
public class ProloGraalSimpleTermNode extends ProloGraalTermNode {
public ProloGraalSimpleTermNode(ProloGraalTerm value){
......@@ -12,6 +14,11 @@ public class ProloGraalSimpleTermNode extends ProloGraalTermNode {
@Override
public ProloGraalTerm executeTerm(VirtualFrame frame) {
return value;
return value instanceof ProloGraalVariable?value.getRootValue():value;
}
@Override
public ProloGraalTermNode copyTermNode(Map<ProloGraalVariable, ProloGraalVariable> variables) {
return new ProloGraalSimpleTermNode(value.copy(variables));
}
}
......@@ -2,6 +2,7 @@ package ch.heiafr.prolograal.nodes;
import ch.heiafr.prolograal.ProloGraalTypes;
import ch.heiafr.prolograal.runtime.ProloGraalTerm;
import ch.heiafr.prolograal.runtime.ProloGraalVariable;
import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.instrumentation.GenerateWrapper;
......@@ -9,6 +10,8 @@ import com.oracle.truffle.api.instrumentation.InstrumentableNode;
import com.oracle.truffle.api.instrumentation.ProbeNode;
import com.oracle.truffle.api.nodes.NodeInfo;
import java.util.Map;
@TypeSystemReference(ProloGraalTypes.class)
@NodeInfo(shortName = "ProloGraalTermNode")
@GenerateWrapper
......@@ -35,6 +38,8 @@ public abstract class ProloGraalTermNode extends ProloGraalGenericNode implement
return new ProloGraalTermNodeWrapper(this,this, probe);
}
public abstract ProloGraalTermNode copyTermNode(Map<ProloGraalVariable, ProloGraalVariable> variables);
public ProloGraalTerm getValue(){
return value;
}
......
......@@ -2,6 +2,8 @@ package ch.heiafr.prolograal.parser;
import ch.heiafr.prolograal.ProloGraalLanguage;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalBuiltinClause;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalIsBuiltin;
import ch.heiafr.prolograal.nodes.ProloGraalBuiltinHeadNode;
import ch.heiafr.prolograal.nodes.ProloGraalSimpleTermNode;
import ch.heiafr.prolograal.nodes.ProloGraalTermNode;
import ch.heiafr.prolograal.runtime.*;
......@@ -240,12 +242,15 @@ public class ProloGraalListenerImpl extends ProloGraalBaseListener {
}
// check if the current structure is a builtin, and initialize it as a builtin if it is one
if(ProloGraalBuiltinClause.getBuiltinsInitializers().containsKey(struct.getFunctor().getName())){
ProloGraalBuiltinStructure builtinStructure = ProloGraalBuiltinClause.getBuiltinsInitializers().get(struct.getFunctor().getName()).apply(struct);
if(builtinStructure != null){
elements.pop();
elements.push(builtinStructure);
}
ProloGraalStructure builtinStructure = null;
if(ProloGraalBuiltinStructure.getBuiltinsInitializers().containsKey(struct.getFunctor().getName())){
builtinStructure = ProloGraalBuiltinStructure.getBuiltinsInitializers().get(struct.getFunctor().getName()).apply(struct);
}else if(ProloGraalIsBuiltin.getOperations().containsKey(struct.getFunctor())){ //if the structure is an is/2 operator (by functor name), build it
builtinStructure = ProloGraalBuiltinStructure.getBuiltinsInitializers().get("isOp").apply(struct);
}
if(builtinStructure != null){
elements.pop();
elements.push(builtinStructure);
}
// no need to do anything else since it was already in the element stack (we do not remove it here)
}
......
package ch.heiafr.prolograal.runtime;
import ch.heiafr.prolograal.nodes.ProloGraalBuiltinHeadNode;
import ch.heiafr.prolograal.builtins.predicates.ProloGraalBuiltinClause;
import ch.heiafr.prolograal.nodes.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class ProloGraalBuiltinStructure extends ProloGraalStructure{
......@@ -30,4 +33,57 @@ public class ProloGraalBuiltinStructure extends ProloGraalStructure{
this.subterms.forEach(x -> struct.addSubterm(x.copy(variables)));
return struct;
}
/////////////////////////////////////////////////////////////
//TODO: builtins can be atoms, should be ProloGraalBuiltinTerm?
//builtin initialization as ProloGraalTerm. It let us execute them as Truffle Nodes,
//even if builtin clauses are called into regular clauses goals (since goals are a list of terms).
////////////////////////////////////////////////////////////
private static final Map<String, Function<ProloGraalTerm, ProloGraalStructure>> builtinsInitializers = fillBuiltinsInitializers();
private static Map<String, Function<ProloGraalTerm, ProloGraalStructure>> fillBuiltinsInitializers(){
Map<String, Function<ProloGraalTerm, ProloGraalStructure>> initializers = new HashMap<>();
initializers.put("is", ProloGraalBuiltinStructure::initializeIs);
initializers.put("isOp", ProloGraalBuiltinStructure::initializeIsOp);
return initializers;
}
public static ProloGraalBuiltinStructure initializeIs(ProloGraalTerm isTerm){
if( !(isTerm.isStructure() && isTerm.asStructure().getArity() == 2) )
return null;
List<ProloGraalTerm<?>> isArgs = isTerm.asStructure().getArguments();
ProloGraalIsHeadNode isBuiltinHead = ProloGraalIsHeadNodeGen.create(isTerm,buildTermNodeForIsOp(isArgs.get(0)),buildTermNodeForIsOp(isArgs.get(1)));
return new ProloGraalBuiltinStructure(isTerm.asStructure(),isBuiltinHead);
}
public static ProloGraalIsOpStructure initializeIsOp(ProloGraalTerm isOpTerm){
if( !(isOpTerm.isStructure() || isOpTerm.isAtom()) )
return null;
ProloGraalTermNode emptyNode = new ProloGraalIsOpTermNode.ProloGraalEmptyTermNode();
if(isOpTerm.isAtom()){
ProloGraalStructure isOpStruct = new ProloGraalStructure(isOpTerm.getVariables());
isOpStruct.setFunctor(isOpStruct.asAtom());
return new ProloGraalIsOpStructure(isOpStruct, ProloGraalIsOpTermNodeGen.create(isOpStruct,emptyNode,emptyNode));
}
ProloGraalTermNode left = emptyNode;
ProloGraalTermNode right = emptyNode;
List<ProloGraalTerm<?>> isOpArgs = isOpTerm.asStructure().getArguments();
if(isOpArgs.size()>1)
right = buildTermNodeForIsOp(isOpArgs.get(1));
if(isOpArgs.size()>0)
left = buildTermNodeForIsOp(isOpArgs.get(0));
ProloGraalIsOpTermNode isOpBuiltinHead = ProloGraalIsOpTermNodeGen.create(isOpTerm,left,right);
return new ProloGraalIsOpStructure(isOpTerm.asStructure(),isOpBuiltinHead);
}
private static ProloGraalTermNode buildTermNodeForIsOp(ProloGraalTerm opArg){
if(opArg instanceof ProloGraalIsOpStructure)
return ((ProloGraalIsOpStructure)opArg).getIsOpTermNode();
return new ProloGraalSimpleTermNode(opArg);
}
public static Map<String, Function<ProloGraalTerm, ProloGraalStructure>> getBuiltinsInitializers() {
return builtinsInitializers;
}
}
\ No newline at end of file
package ch.heiafr.prolograal.runtime;
import ch.heiafr.prolograal.nodes.ProloGraalIsOpTermNode;
import java.util.HashMap;
import java.util.Map;
public class ProloGraalIsOpStructure extends ProloGraalStructure {
private final ProloGraalIsOpTermNode isOpTermNode;
public ProloGraalIsOpStructure(ProloGraalIsOpTermNode isOpTermNode){
super(new HashMap<>());
this.isOpTermNode = isOpTermNode;
}
public ProloGraalIsOpStructure(ProloGraalStructure copiedStruct, ProloGraalIsOpTermNode isOpTermNode) {
super(copiedStruct);
this.isOpTermNode = isOpTermNode;
}
public ProloGraalIsOpTermNode getIsOpTermNode(){
return isOpTermNode;
}
@Override
public ProloGraalIsOpStructure copy(Map<ProloGraalVariable, ProloGraalVariable> variables) {
ProloGraalIsOpStructure struct = new ProloGraalIsOpStructure((ProloGraalIsOpTermNode) isOpTermNode.copyTermNode(variables));
struct.setFunctor(this.functor.copy(variables));
this.subterms.forEach(x -> struct.addSubterm(x.copy(variables)));
return struct;
}
}
Markdown is supported
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