|
From: <jom...@us...> - 2013-09-09 00:53:43
|
Revision: 1748
http://sourceforge.net/p/jason/svn/1748
Author: jomifred
Date: 2013-09-09 00:53:39 +0000 (Mon, 09 Sep 2013)
Log Message:
-----------
unification changed to deal with negated variables
Modified Paths:
--------------
trunk/applications/as-unit-test/src/jason/tests/TestAll.java
trunk/release-notes.txt
trunk/src/jason/asSemantics/TransitionSystem.java
trunk/src/jason/asSemantics/Unifier.java
trunk/src/jason/asSyntax/VarTerm.java
trunk/src/jason/stdlib/create_agent.java
trunk/src/test/ASParserTest.java
trunk/src/test/VarTermTest.java
Added Paths:
-----------
trunk/applications/as-unit-test/src/jason/tests/TestNegatedVar.java
Modified: trunk/applications/as-unit-test/src/jason/tests/TestAll.java
===================================================================
--- trunk/applications/as-unit-test/src/jason/tests/TestAll.java 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/applications/as-unit-test/src/jason/tests/TestAll.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -25,6 +25,7 @@
TestPlanFailure.class,
TestVarInContext.class,
TestUnnamedVar.class,
- TestCopyTerm.class
+ TestCopyTerm.class,
+ TestNegatedVar.class
})
public class TestAll { }
Added: trunk/applications/as-unit-test/src/jason/tests/TestNegatedVar.java
===================================================================
--- trunk/applications/as-unit-test/src/jason/tests/TestNegatedVar.java (rev 0)
+++ trunk/applications/as-unit-test/src/jason/tests/TestNegatedVar.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -0,0 +1,32 @@
+package jason.tests;
+
+import jason.asunit.TestAgent;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestNegatedVar {
+
+ TestAgent ag;
+
+ // initialisation of the agent test
+ @Before
+ public void setupAg() {
+ ag = new TestAgent();
+ ag.setDebugMode(true);
+
+ // defines the agent's AgentSpeak code
+ ag.parseAScode(
+ "+!start <- +b. " +
+ "+B <- !~B. " +
+ "+!X <- jason.asunit.print(X)."
+ );
+ }
+
+ @Test(timeout=2000)
+ public void testContext() {
+ ag.addGoal("start");
+ ag.assertPrint("~b[source(self)]", 5);
+ }
+
+}
Modified: trunk/release-notes.txt
===================================================================
--- trunk/release-notes.txt 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/release-notes.txt 2013-09-09 00:53:39 UTC (rev 1748)
@@ -11,7 +11,7 @@
- the internal action .wait accepts a logical expression as argument, as in
...; .wait(b(X) & X > 10); ....
- The intention will be suspended until the agent belief b(X) with X > 10.
+ The intention will be suspended until the agent believes b(X) with X > 10.
Timeout and elapse time arguments can be used as previously.
---------------------------
Modified: trunk/src/jason/asSemantics/TransitionSystem.java
===================================================================
--- trunk/src/jason/asSemantics/TransitionSystem.java 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/src/jason/asSemantics/TransitionSystem.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -580,31 +580,36 @@
Term bTerm = h.getBodyTerm();
// de-var bTerm
- while (bTerm instanceof VarTerm) {
+ //while (bTerm instanceof VarTerm) {
+ if (bTerm instanceof VarTerm) {
// check if bTerm is ground
- //if (bTerm.isGround()) {
- if (((VarTerm)bTerm).hasValue()) {
+ /*if (((VarTerm)bTerm).hasValue()) {
bTerm = ((VarTerm)bTerm).getValue();
continue; // restart the loop
- }
+ }*/
// h should be 'groundable' (considering the current unifier)
- Term bValue = u.get((VarTerm)bTerm);
+ bTerm = bTerm.clone(); // clone before apply
+ bTerm.apply(u);
+ //Term bValue = u.get((VarTerm)bTerm);
//System.out.println("*** "+bTerm+"="+bValue+" "+bTerm.isGround()+" "+u);
- if (bValue == null) { // the case of !A with A not ground
+ //if (bValue == null) { // the case of !A with A not ground
+ if (bTerm.isVar()) { // the case of !A with A not ground
String msg = h.getSrcInfo()+": "+ "Variable '"+bTerm+"' must be ground.";
if (!generateGoalDeletion(conf.C.SI, JasonException.createBasicErrorAnnots("body_var_without_value", msg)))
logger.log(Level.SEVERE, msg);
return;
}
- if (bValue.isPlanBody()) {
+ //if (bValue.isPlanBody()) {
+ if (bTerm.isPlanBody()) {
if (h.getBodyType() != BodyType.action) { // the case of ...; A = { !g }; +g; ....
- String msg = h.getSrcInfo()+": "+ "The operator '"+h.getBodyType()+"' is lost with the variable '"+bTerm+"' unified with a plan body '"+bValue+"'. ";
+ String msg = h.getSrcInfo()+": "+ "The operator '"+h.getBodyType()+"' is lost with the variable '"+bTerm+"' unified with a plan body. ";
if (!generateGoalDeletion(conf.C.SI, JasonException.createBasicErrorAnnots("body_var_with_op", msg)))
logger.log(Level.SEVERE, msg);
return;
}
- h = (PlanBody)bValue;
+ //h = (PlanBody)bValue;
+ h = (PlanBody)bTerm;
if (h.getPlanSize() > 1) { // the case of A unified with {a;b;c}
h.add(im.getCurrentStep().getBodyNext());
im.insertAsNextStep(h.getBodyNext());
@@ -612,7 +617,7 @@
bTerm = h.getBodyTerm();
} else {
ListTerm annots = ((VarTerm)bTerm).getAnnots();
- bTerm = bValue;
+ //bTerm = bValue;
if (bTerm.isLiteral() && annots != null) {
bTerm = ((Literal)bTerm).forceFullLiteralImpl();
((Literal)bTerm).addAnnots(annots);
Modified: trunk/src/jason/asSemantics/Unifier.java
===================================================================
--- trunk/src/jason/asSemantics/Unifier.java 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/src/jason/asSemantics/Unifier.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -89,6 +89,18 @@
if (vl != null && vl.isVar()) { // optimised deref
return get((VarTerm)vl);
}
+ if (vl == null) { // try negated value of the var
+ //System.out.println("for "+vtp+" try "+new VarTerm(vtp.negated(), vtp.getFunctor())+" in "+this);
+ vl = function.get( new VarTerm(vtp.negated(), vtp.getFunctor()) );
+ //System.out.println(" and found "+vl);
+ if (vl != null && vl.isVar()) {
+ vl = get((VarTerm)vl);
+ }
+ if (vl != null && vl.isLiteral()) {
+ vl = vl.clone();
+ ((Literal)vl).setNegated(((Literal)vl).negated());
+ }
+ }
return vl;
}
@@ -233,21 +245,20 @@
final VarTerm t2gv = t2gisvar ? deref((VarTerm)t2g) : null;
// get their values
- final Term t1vl = t1gisvar ? function.get(t1gv) : t1g;
- final Term t2vl = t2gisvar ? function.get(t2gv) : t2g;
+ //final Term t1vl = t1gisvar ? function.get(t1gv) : t1g;
+ //final Term t2vl = t2gisvar ? function.get(t2gv) : t2g;
+ final Term t1vl = t1gisvar ? get(t1gv) : t1g;
+ final Term t2vl = t2gisvar ? get(t2gv) : t2g;
- if (t1vl != null && t2vl != null) {
- // unifies the two values of the vars
+ if (t1vl != null && t2vl != null) { // unifies the two values of the vars
return unifiesNoUndo(t1vl, t2vl);
- } else if (t1vl != null) {
- bind(t2gv, t1vl);
+ } else if (t1vl != null) { // unifies var with value
+ return bind(t2gv, t1vl);
} else if (t2vl != null) {
- bind(t1gv, t2vl);
- } else { //if (t1gv != null && t2gv != null) {
- // unify two vars
- bind(t1gv, t2gv);
+ return bind(t1gv, t2vl);
+ } else { // unify two vars
+ return bind(t1gv, t2gv);
}
- return true;
}
// both terms are not vars
@@ -307,23 +318,43 @@
return v;
}
-
-
- public void bind(VarTerm vt1, VarTerm vt2) {
+ public boolean bind(VarTerm vt1, VarTerm vt2) {
+ if (vt1.negated() && vt2.negated()) { // in the case of ~A = ~B, put A=B in the unifier
+ vt1 = new VarTerm(vt1.getFunctor());
+ vt2 = new VarTerm(vt2.getFunctor());
+ }
+
final int comp = vt1.compareTo(vt2);
if (comp < 0) {
- function.put((VarTerm)vt1.clone(), vt2);
+ function.put((VarTerm)vt1.clone(), vt2.clone());
} else if (comp > 0){
- function.put((VarTerm)vt2.clone(), vt1);
+ function.put((VarTerm)vt2.clone(), vt1.clone());
} // if they are the same (comp == 0), do not bind
+ return true;
}
- public void bind(VarTerm vt, Term vl) {
+ public boolean bind(VarTerm vt, Term vl) {
+ if (vt.negated()) { // negated vars unifies only with negated literals
+ if (vl.isLiteral()) {
+ if (!((Literal)vl).negated()) {
+ return false;
+ } else {
+ // put also the positive case in the unifier
+ Literal vlp = (Literal)vl.clone();
+ vlp.setNegated(Literal.LPos);
+ unifies(new VarTerm(vt.getFunctor()), vlp);
+ }
+ } else {
+ return false;
+ }
+ }
+
if (!vl.isCyclicTerm() && vl.hasVar(vt, this)) {
vl = new CyclicTerm((Literal)vl, (VarTerm)vt.clone());
- //System.out.println("changing "+vt+" <- "+vl+" in "+this);
}
+
function.put((VarTerm) vt.clone(), vl);
+ return true;
}
public void clear() {
Modified: trunk/src/jason/asSyntax/VarTerm.java
===================================================================
--- trunk/src/jason/asSyntax/VarTerm.java 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/src/jason/asSyntax/VarTerm.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -65,6 +65,9 @@
e.printStackTrace();
}
}
+ public VarTerm(boolean negated, String s) {
+ super(negated, s);
+ }
/** @deprecated prefer ASSyntax.parseVar(...) */
public static VarTerm parseVar(String sVar) {
@@ -83,6 +86,7 @@
} else {
// do not call constructor with term parameter!
VarTerm t = new VarTerm(super.getFunctor());
+ t.setNegated(!negated());
t.srcInfo = this.srcInfo;
if (hasAnnot())
t.setAnnots(getAnnots().cloneLT());
@@ -135,7 +139,7 @@
// P[step(N)]
if (vl.isPred() && this.hasAnnot()) // if this var has annots, add them in the value's annots (Experimental)
((Pred)vl).addAnnots(this.getAnnots());
-
+
value = vl;
resetHashCodeCache();
return true;
@@ -148,8 +152,7 @@
public boolean apply(Unifier u) {
if (value == null) {
- Term vl = u.get(this);
- //System.out.println("applying "+this+"="+vl+" un="+u);
+ Term vl = u.get(this);
if (vl != null) {
if (!vl.isCyclicTerm() && vl.hasVar(this, u)) {
//logger.warning("The value of a variable contains itself, variable "+super.getFunctor()+" "+super.getSrcInfo()+", value="+vl+", unifier="+u);
@@ -200,7 +203,7 @@
if (t instanceof VarTerm) {
final VarTerm tAsVT = (VarTerm) t;
if (tAsVT.getValue() == null) {
- return getFunctor().equals(((VarTerm)t).getFunctor());
+ return negated() == ((VarTerm)t).negated() && getFunctor().equals(((VarTerm)t).getFunctor());
}
}
}
@@ -212,10 +215,14 @@
return value.compareTo(t);
else if (t == null || t.isUnnamedVar())
return -1;
- else if (t.isVar())
- return getFunctor().compareTo(((VarTerm)t).getFunctor());
- else
- return 1;
+ else if (t.isVar()) {
+ if (!negated() && ((VarTerm)t).negated())
+ return -1;
+ else
+ return getFunctor().compareTo(((VarTerm)t).getFunctor());
+ } else {
+ return 1;
+ }
}
@Override
@@ -476,9 +483,10 @@
public String toString() {
if (value == null) {
String s = getFunctor();
- if (hasAnnot()) {
+ if (hasAnnot())
s += getAnnots();
- }
+ if (negated())
+ s = "~" + s;
return s;
} else {
return value.toString();
@@ -668,7 +676,10 @@
@Override
public boolean negated() {
- return value != null && getValue().isLiteral() && ((Literal) getValue()).negated();
+ if (value == null)
+ return super.negated();
+ else
+ return getValue().isLiteral() && ((Literal) getValue()).negated();
}
@Override
Modified: trunk/src/jason/stdlib/create_agent.java
===================================================================
--- trunk/src/jason/stdlib/create_agent.java 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/src/jason/stdlib/create_agent.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -28,23 +28,17 @@
import jason.asSemantics.TransitionSystem;
import jason.asSemantics.Unifier;
import jason.asSyntax.ListTerm;
-import jason.asSyntax.SourceInfo;
import jason.asSyntax.StringTerm;
import jason.asSyntax.StringTermImpl;
import jason.asSyntax.Structure;
import jason.asSyntax.Term;
-import jason.asSyntax.VarTerm;
import jason.mas2j.ClassParameters;
import jason.runtime.RuntimeServicesInfraTier;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
/**
<p>Internal action: <b><code>.create_agent</code></b>.
Modified: trunk/src/test/ASParserTest.java
===================================================================
--- trunk/src/test/ASParserTest.java 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/src/test/ASParserTest.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -40,6 +40,18 @@
super.setUp();
}
+ public void testNegVar() throws ParseException {
+ Literal l = ASSyntax.parseLiteral("~B");
+ assertTrue(l.isVar());
+ assertTrue(l.negated());
+ l = (Literal)l.clone();
+ assertTrue(l.isVar());
+ assertTrue(l.negated());
+ Literal l1 = ASSyntax.parseLiteral("~B");
+ Literal l2 = ASSyntax.parseLiteral("B");
+ assertFalse(l1.equals(l2));
+ }
+
public void testKQML() {
Agent ag = new Agent();
ag.initAg();
Modified: trunk/src/test/VarTermTest.java
===================================================================
--- trunk/src/test/VarTermTest.java 2013-09-09 00:51:53 UTC (rev 1747)
+++ trunk/src/test/VarTermTest.java 2013-09-09 00:53:39 UTC (rev 1748)
@@ -5,6 +5,7 @@
import jason.asSemantics.Unifier;
import jason.asSyntax.ASSyntax;
import jason.asSyntax.ArithExpr;
+import jason.asSyntax.ArithExpr.ArithmeticOp;
import jason.asSyntax.Atom;
import jason.asSyntax.ListTerm;
import jason.asSyntax.ListTermImpl;
@@ -18,7 +19,6 @@
import jason.asSyntax.Term;
import jason.asSyntax.UnnamedVar;
import jason.asSyntax.VarTerm;
-import jason.asSyntax.ArithExpr.ArithmeticOp;
import jason.asSyntax.parser.ParseException;
import jason.asSyntax.parser.SimpleCharStream;
import jason.asSyntax.parser.Token;
@@ -561,4 +561,107 @@
assertTrue(X.compareTo(new NumberTermImpl(1)) > 0);
assertTrue(new NumberTermImpl(1).compareTo(X) < 0);
}
+
+ public void testUnifyNegVar() throws ParseException {
+ Literal l1 = ASSyntax.parseLiteral("~B");
+ Literal l2 = ASSyntax.parseLiteral("~p(1)");
+ Unifier u = new Unifier();
+ assertTrue(u.unifies(l1, l2)); // ~B = ~p(1)
+ assertEquals(u.get((VarTerm)l1).toString(),"~p(1)");
+ l1.apply(u); // apply in ~B should result in ~p(1)
+ assertEquals(l1.toString(),"~p(1)");
+
+ VarTerm b = new VarTerm("B");
+ b.apply(u);
+ assertEquals(b.toString(),"p(1)");
+
+ l1 = ASSyntax.parseLiteral("~B");
+ l2 = ASSyntax.parseLiteral("p(1)");
+ u = new Unifier();
+ assertFalse(u.unifies(l1, l2));
+
+ assertFalse(u.unifies(l1, ASSyntax.parseTerm("10")));
+
+ l1 = ASSyntax.parseLiteral("B");
+ l2 = ASSyntax.parseLiteral("~p(1)");
+ u = new Unifier();
+ assertTrue(u.unifies(l1, l2));
+ assertEquals(u.get("B").toString(),"~p(1)");
+ l1.apply(u);
+ assertEquals(l1.toString(),"~p(1)");
+
+ l1 = ASSyntax.parseLiteral("~B");
+ l2 = ASSyntax.parseLiteral("~A");
+ u = new Unifier();
+ assertTrue(u.unifies(l1, l2));
+ // if A = p(10), apply in ~B should be ~p(10).
+ VarTerm va = new VarTerm("A");
+ u.unifies(va,ASSyntax.parseLiteral("p(10)"));
+ va.apply(u);
+ assertEquals(va.toString(),"p(10)");
+ l1.apply(u);
+ assertEquals(l1.toString(),"~p(10)");
+ l2.apply(u);
+ assertEquals(l2.toString(),"~p(10)");
+
+ l1 = ASSyntax.parseLiteral("~B");
+ l2 = ASSyntax.parseLiteral("~A");
+ u = new Unifier();
+ assertTrue(u.unifies(l1, l2)); // A = B
+ // if ~A = ~p(10), apply in B should be p(10).
+ assertTrue(u.unifies(l2, ASSyntax.parseLiteral("~p(10)")));
+ l2.apply(u);
+ assertEquals(l2.toString(),"~p(10)");
+ l1.apply(u);
+ assertEquals(l1.toString(),"~p(10)"); // ~B is ~p(10)
+ VarTerm vb = new VarTerm("B");
+ vb.apply(u);
+ assertEquals(vb.toString(),"p(10)"); // B is p(10)
+
+ u = new Unifier();
+ u.unifies(new VarTerm("A"),ASSyntax.parseLiteral("p(10)"));
+ u.unifies(new VarTerm("B"),ASSyntax.parseLiteral("~p(10)"));
+ assertFalse(u.unifies(new VarTerm("A"), new VarTerm("B")));
+ l1 = ASSyntax.parseLiteral("~B");
+ l2 = ASSyntax.parseLiteral("~A");
+ assertFalse(u.unifies(l1, l2));
+
+ u = new Unifier();
+ u.unifies(new VarTerm("A"),ASSyntax.parseLiteral("p(10)"));
+ assertFalse(u.unifies(new VarTerm(Literal.LNeg,"B"),new VarTerm("A")));
+
+ u = new Unifier();
+ u.unifies(new VarTerm("A"),ASSyntax.parseLiteral("~p(10)"));
+ vb = new VarTerm(Literal.LNeg,"B");
+ assertTrue(u.unifies(vb,new VarTerm("A")));
+ vb.apply(u);
+ assertEquals(vb.toString(),"~p(10)");
+
+ u = new Unifier();
+ u.unifies(new VarTerm("A"),ASSyntax.parseLiteral("~p(10)"));
+ vb = new VarTerm(Literal.LNeg,"B");
+ assertTrue(u.unifies(vb,new VarTerm("A")));
+ vb = new VarTerm("B");
+ vb.apply(u);
+ assertEquals(vb.toString(),"p(10)");
+
+ // B = ~A
+ // A = p(10)
+ // => apply B is ~p(10)
+ // apply A is p(10)
+ // apply ~A is ~p(10)
+ l1 = ASSyntax.parseLiteral("B");
+ l2 = ASSyntax.parseLiteral("~A");
+ u = new Unifier();
+ assertTrue(u.unifies(l1, l2));
+ va = new VarTerm("A");
+ u.unifies(va,ASSyntax.parseLiteral("p(10)"));
+ va.apply(u);
+ assertEquals(va.toString(),"p(10)");
+ l1.apply(u);
+ assertEquals(l1.toString(),"~p(10)");
+ l2.apply(u);
+ assertEquals(l2.toString(),"~p(10)");
+
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|