Commit 6fe83e28 authored by Martin Spoto's avatar Martin Spoto
Browse files

Still broken clauses impl

parent a3ca64e1
......@@ -50,6 +50,13 @@ public class ProloGraalInterpreterNode extends RootNode {
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;
}
Source source = Source.newBuilder("pl", line, null).build();
......
package ch.heiafr.prolograal.nodes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
......@@ -13,28 +12,6 @@ import ch.heiafr.prolograal.runtime.*;
public final class ProloGraalResolverNode extends RootNode {
private static class AugmentedArrayList<T> extends ArrayList<T> {
private static final long serialVersionUID = 1L;
public T pop() {
T obj = this.get(this.size()-1);
this.remove(this.size()-1);
return obj;
}
}
private static class ProloGraalResolveState {
private int index = 0;
public void setIndex(int index) {
this.index = index;
}
public int getIndex() {
return this.index;
}
}
private final ProloGraalContext context;
private final Map<ProloGraalTerm<?>, List<ProloGraalClause>> clauses;
......@@ -51,66 +28,60 @@ public final class ProloGraalResolverNode extends RootNode {
if (ProloGraalLanguage.DEBUG_MODE)
System.out.println("Executing : " + goalRuntime.getFirstClause());
/*
* List<ProloGraalTerm> filteredTerms = terms.stream().filter(x ->
* goal.equals(x)).collect(Collectors.toList());
*
* if(filteredTerms.size() == 0) throw new ProloGraalExistenceError();
*/
states = new AugmentedArrayList<>();
return resolve(goalRuntime.getFirstClause().getHead(), 0);
return resolve(goalRuntime.getFirstClause().getHead());
}
private List<ProloGraalResolveState> states;
public ProloGraalBoolean resolve(ProloGraalTerm<?> goal) {
private void cleanClauseGoals(ProloGraalClause clause) {
clause.getGoals().stream()
.filter(x -> x instanceof ProloGraalStructure)
.flatMap(x -> ((ProloGraalStructure)x).getVariables().values().stream())
.forEach(ProloGraalVariable::unbind);
}
public ProloGraalBoolean resolve(ProloGraalTerm<?> goal, int depth) {
System.out.println("Resolving : " + goal + " at depth " + depth);
// get all possible predicates
List<ProloGraalClause> possibleClauses = clauses.get(goal);
ProloGraalResolveState state;
if(states.size() > depth) {
state = states.get(depth);
} else {
state = new ProloGraalResolveState();
states.add(state);
}
if(possibleClauses == null)
if(possibleClauses.isEmpty()) // if no match, throw an error
throw new ProloGraalExistenceError();
for(int i = 0; i < possibleClauses.size(); i++) {
ProloGraalClause clause = possibleClauses.get(i);
if(goal.isUnifiable(clause.getHead())) {
// for each possible clause
for(ProloGraalClause clause : possibleClauses) {
// save current states
goal.save();
clause.getHead().save();
// if the head of the clause is unifiable with the current goal
if(clause.getHead().isUnifiable(goal)) {
if(clause.isFact()) {
System.out.println("New success with : ");
return new ProloGraalSuccess(clause);
// if the clause is a fact, we just need to restore the state !! of the clause !! and return a success
clause.getHead().undo();
System.out.println("Success for goal : " + goal);
return new ProloGraalSuccess();
} else {
for(int j = 0; j < clause.getGoalCount(); j++) {
ProloGraalTerm<?> newGoal = clause.getGoals().get(j);
System.out.println("New resolve goal : " + newGoal + " at depth " + (depth+1));
ProloGraalBoolean result = resolve(newGoal, depth+1);
if(!result.asBoolean()) {
cleanClauseGoals(clause);
// if the clause is a complex clause, we need to iterate over each goals
for(int i = 0; i < clause.getGoalCount(); i++) {
ProloGraalTerm<?> subGoal = clause.getGoals().get(i);
subGoal.save();
if(!resolve(subGoal).asBoolean()) {
// if one of the goals cannot be unified, then this branch is a failure
// we need to restore the state of the processed goals
for(int j = 0; j <= i; j++) {
clause.getGoals().get(j).undo();
}
// and signal the failure
System.out.println("Failure for goal : " + goal);
return new ProloGraalFailure();
}
}
if(depth == 0)
cleanClauseGoals(clause);
return new ProloGraalSuccess(clause);
// if we got to this point, every goal has been successfully unified, we can restore the state of every goal and return a success
clause.getGoals().forEach(ProloGraalTerm::undo);
System.out.println("Success for goal : " + goal);
return new ProloGraalSuccess();
}
} else {
clause.getHead().undo(); // undo all changes that the unification may have done
goal.undo();
}
state.setIndex(i+1);
clause.getVariables().values().forEach(ProloGraalVariable::unbind);
}
System.out.println("Failure for " + goal + " at depth " + depth);
// we tried every clauses but none was successful
// no need to restore any state
System.out.println("Failure for goal : " + goal);
return new ProloGraalFailure();
}
......
......@@ -124,4 +124,16 @@ public class ProloGraalList extends ProloGraalTerm<ProloGraalList> {
return list;
}
// save current state
@Override
public void save() {
this.internal.save();
}
// go back to previous state
@Override
public void undo() {
this.internal.undo();
}
}
\ No newline at end of file
......@@ -96,4 +96,15 @@ public final class ProloGraalStructure extends ProloGraalTerm<ProloGraalStructur
this.subterms.forEach(x -> subterms.add(x.copy()));
return new ProloGraalStructure(this.functor.copy(), subterms, variables);
}
// save current state
@Override
public void save() {
this.subterms.forEach(ProloGraalTerm::save);
}
@Override
public void undo() {
this.subterms.forEach(ProloGraalTerm::undo);
}
}
\ No newline at end of file
......@@ -15,5 +15,16 @@ public abstract class ProloGraalTerm<T extends ProloGraalTerm<T>> implements Tru
public abstract boolean isUnifiable(ProloGraalTerm<?> other);
// save current state
public void save() {
}
// go back to previous state
public void undo() {
}
public abstract T copy();
}
\ No newline at end of file
package ch.heiafr.prolograal.runtime;
import java.util.ArrayDeque;
import java.util.Deque;
import ch.heiafr.prolograal.ProloGraalLanguage;
public final class ProloGraalVariable extends ProloGraalTerm<ProloGraalVariable> {
// all variables have the same hash for table lookup purposes
private static final int hash = "VARIABLE".hashCode();
private Deque<ProloGraalVariable> states = new ArrayDeque<>();
private static int anonymousVariableSuffix = 0;
private final String name;
private boolean isBound = false;
private ProloGraalTerm<?> boundValue;
public ProloGraalVariable(String name) {
if(name.startsWith("_")) {
if (name.startsWith("_")) {
name = "_" + anonymousVariableSuffix++;
}
this.name = name;
this.hashCode = hash;
this.hashCode = name.hashCode();
}
public ProloGraalVariable(ProloGraalVariable other) {
this.name = other.name;
this.isBound = other.isBound;
this.boundValue = other.boundValue.copy();
}
public ProloGraalTerm<?> getValue() {
if(isBound)
if (isBound)
return boundValue;
else
return this;
}
public void bind(ProloGraalTerm<?> other) {
if(other instanceof ProloGraalVariable) {
ProloGraalVariable otherVar = (ProloGraalVariable)other;
if(otherVar.isBound && otherVar.boundValue == this) {
//throw new RuntimeException("Recursive binding for variables " + this.name + " and " + otherVar.name);
if (other instanceof ProloGraalVariable) {
ProloGraalVariable otherVar = (ProloGraalVariable) other;
if (otherVar.isBound && otherVar.boundValue == this) {
// throw new RuntimeException("Recursive binding for variables " + this.name + "
// and " + otherVar.name);
return;
}
}
this.isBound = true;
this.boundValue = other;
if(ProloGraalLanguage.DEBUG_MODE)
if (ProloGraalLanguage.DEBUG_MODE)
System.out.println(name + " = " + other);
}
......@@ -47,15 +57,15 @@ public final class ProloGraalVariable extends ProloGraalTerm<ProloGraalVariable>
@Override
public boolean equals(Object obj) {
return obj != null && obj instanceof ProloGraalVariable && this.name.equals(((ProloGraalVariable)obj).name);
return obj != null && obj instanceof ProloGraalVariable && this.name.equals(((ProloGraalVariable) obj).name);
}
@Override
public String toString() {
if(this.isBound) {
if(boundValue instanceof ProloGraalVariable) {
ProloGraalVariable otherVar = (ProloGraalVariable)boundValue;
if(otherVar.isBound) {
if (this.isBound) {
if (boundValue instanceof ProloGraalVariable) {
ProloGraalVariable otherVar = (ProloGraalVariable) boundValue;
if (otherVar.isBound) {
return this.name + " = " + otherVar.boundValue.toString();
}
}
......@@ -65,13 +75,14 @@ public final class ProloGraalVariable extends ProloGraalTerm<ProloGraalVariable>
@Override
public boolean isUnifiable(ProloGraalTerm<?> other) {
if(other instanceof ProloGraalVariable && (ProloGraalVariable)other == this) // can always unify to itself
if (other instanceof ProloGraalVariable && (ProloGraalVariable) other == this) // can always unify to itself
return true;
if(this.isBound) {
if(other instanceof ProloGraalVariable) {
ProloGraalVariable otherVar = (ProloGraalVariable)other;
if(otherVar.isBound) {
return this.boundValue.isUnifiable(otherVar.boundValue); // FIXME maybe this will cause infinite loops
if (this.isBound) {
if (other instanceof ProloGraalVariable) {
ProloGraalVariable otherVar = (ProloGraalVariable) other;
if (otherVar.isBound) {
return this.boundValue.isUnifiable(otherVar.boundValue); // FIXME maybe this will cause infinite
// loops
} else {
otherVar.bind(this);
return true;
......@@ -87,15 +98,27 @@ public final class ProloGraalVariable extends ProloGraalTerm<ProloGraalVariable>
@Override
public ProloGraalVariable copy() {
ProloGraalVariable var = new ProloGraalVariable(this.name);
var.isBound = this.isBound;
if(this.isBound) {
var.boundValue = this.boundValue.copy();
}
return var;
return new ProloGraalVariable(this);
}
public boolean isBound() {
return isBound;
}
// save current state
@Override
public void save() {
System.out.println("Saving state for " + this);
states.push(this.copy());
}
// go back to previous state
@Override
public void undo() {
System.out.print("Restoring state for " + this);
ProloGraalVariable previous = states.pop();
this.isBound = previous.isBound;
this.boundValue = previous.boundValue;
System.out.println(" | is now : " + this);
}
}
\ 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