From f06da83f2e373a77a1e21b83cefc43719fd357b2 Mon Sep 17 00:00:00 2001 From: Samagra Date: Tue, 29 May 2018 20:32:44 +0530 Subject: [PATCH 1/7] Adds angelicParser --- .../java/aima/core/logic/planning/Utils.java | 62 +++++++++++++++++++ .../planning/angelicsearch/AngelicHLA.java | 4 ++ .../core/unit/logic/planning/UtilsTest.java | 43 +++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java diff --git a/aima-core/src/main/java/aima/core/logic/planning/Utils.java b/aima-core/src/main/java/aima/core/logic/planning/Utils.java index c862072909..f3cfb5cbee 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/Utils.java +++ b/aima-core/src/main/java/aima/core/logic/planning/Utils.java @@ -7,6 +7,8 @@ import aima.core.logic.fol.parsing.ast.Variable; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; /** @@ -50,4 +52,64 @@ public static List parse(String s) { } return literals; } + + public static List> angelicParse(String s){ + HashSet positive = new HashSet<>(); + HashSet negative = new HashSet<>(); + HashSet maybePositive = new HashSet<>(); + HashSet maybeNegative = new HashSet<>(); + if (s.isEmpty()) + return new ArrayList<>(Arrays.asList(positive,negative,maybePositive,maybeNegative)); + s = s.replaceAll("\\s+", ""); + String[] tokens = s.split("\\^"); + Literal literal; + for (String token : + tokens) { + String[] terms = token.split("[(,)]"); + ArrayList literalTerms = new ArrayList<>(); + Term term; + String termString; + for (int i = 1; i < terms.length; i++) { + termString = terms[i]; + if (termString.equals(termString.toLowerCase())) { + term = new Variable(termString); + } else { + term = new Constant(termString); + } + literalTerms.add(term); + } + + String name = terms[0]; + if (name.charAt(0) == '~'){ + if (name.charAt(1)=='+'){ + if (name.charAt(2)=='-') { + name = name.substring(3); + literal = new Literal(new Predicate(name,literalTerms)); + maybeNegative.add(literal); + maybePositive.add(literal); + } + else { + name = name.substring(2); + literal = new Literal(new Predicate(name,literalTerms)); + maybePositive.add(literal); + } + } + else if (name.charAt(1)=='-'){ + name = name.substring(2); + literal = new Literal(new Predicate(name,literalTerms)); + maybeNegative.add(literal); + } + else { + name = name.substring(1); + literal = new Literal(new Predicate(name,literalTerms)); + negative.add(literal); + } + } + else { + literal = new Literal(new Predicate(name,literalTerms)); + positive.add(literal); + } + } + return new ArrayList<>(Arrays.asList(positive,negative,maybePositive,maybeNegative)); + } } diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java new file mode 100644 index 0000000000..d2faddb3e5 --- /dev/null +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java @@ -0,0 +1,4 @@ +package aima.core.logic.planning.angelicsearch; + +public class AngelicHLA { +} diff --git a/aima-core/src/test/java/aima/test/core/unit/logic/planning/UtilsTest.java b/aima-core/src/test/java/aima/test/core/unit/logic/planning/UtilsTest.java index 4b19e4c718..21a01706f8 100644 --- a/aima-core/src/test/java/aima/test/core/unit/logic/planning/UtilsTest.java +++ b/aima-core/src/test/java/aima/test/core/unit/logic/planning/UtilsTest.java @@ -1,10 +1,14 @@ package aima.test.core.unit.logic.planning; import aima.core.logic.fol.kb.data.Literal; +import aima.core.logic.fol.parsing.ast.Predicate; import aima.core.logic.planning.Utils; +import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; /** * @author samagra @@ -15,4 +19,43 @@ public void parserTest() { String precondition = "At(C1,JFK) ^ At(C2,SFO)"; ArrayList literals = (ArrayList) Utils.parse(precondition); } + + @Test + public void angelicParserTest(){ + String first = "~A"; + String second = "A^~-B"; + String third = "~+A^~+-C"; + Literal a = new Literal(new Predicate("A",new ArrayList<>())); + Literal b = new Literal(new Predicate("B",new ArrayList<>())); + Literal c = new Literal(new Predicate("C",new ArrayList<>())); + + // ~A + List> parsed = Utils.angelicParse(first); + Assert.assertFalse(parsed.get(0).contains(a)); + Assert.assertTrue(parsed.get(1).contains(a)); + Assert.assertFalse(parsed.get(2).contains(a)); + Assert.assertFalse(parsed.get(3).contains(a)); + + // A^~-B + parsed = Utils.angelicParse(second); + Assert.assertTrue(parsed.get(0).contains(a)); + Assert.assertFalse(parsed.get(1).contains(a)); + Assert.assertFalse(parsed.get(2).contains(a)); + Assert.assertFalse(parsed.get(3).contains(a)); + Assert.assertFalse(parsed.get(0).contains(b)); + Assert.assertFalse(parsed.get(1).contains(b)); + Assert.assertFalse(parsed.get(2).contains(b)); + Assert.assertTrue(parsed.get(3).contains(b)); + + //~+A^~+-C + parsed = Utils.angelicParse(third); + Assert.assertFalse(parsed.get(0).contains(a)); + Assert.assertFalse(parsed.get(1).contains(a)); + Assert.assertTrue(parsed.get(2).contains(a)); + Assert.assertFalse(parsed.get(3).contains(a)); + Assert.assertFalse(parsed.get(0).contains(c)); + Assert.assertFalse(parsed.get(1).contains(c)); + Assert.assertTrue(parsed.get(2).contains(c)); + Assert.assertTrue(parsed.get(3).contains(c)); + } } From d4c6456799e2c03935b4ebea12910a30de9384e0 Mon Sep 17 00:00:00 2001 From: Samagra Date: Wed, 30 May 2018 10:40:28 +0530 Subject: [PATCH 2/7] Adds angelic HLA --- .../planning/angelicsearch/AngelicHLA.java | 165 ++++++++++++++++++ .../angelicsearch/AngelicSearchAlgorithm.java | 5 + 2 files changed, 170 insertions(+) create mode 100644 aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java index d2faddb3e5..cff9869de1 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java @@ -1,4 +1,169 @@ package aima.core.logic.planning.angelicsearch; +import aima.core.logic.fol.kb.data.Literal; +import aima.core.logic.fol.parsing.ast.Term; +import aima.core.logic.planning.ActionSchema; +import aima.core.logic.planning.Utils; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + public class AngelicHLA { + List variables;// list of variables + List precondition; //PRECONDITION: treated as a conjunction of fluents + List> effects;//EFFECT: treated as a conjunction of fluents + HashSet effectsPositiveLiterals; + HashSet effectsNegativeLiterals; + HashSet effectsMaybePositiveLiterals; + HashSet effectsMaybeNegativeLiterals; + private String name;//action name + + public AngelicHLA(String name, List variables, + List precondition, List> effects) { + if (variables == null) + variables = new ArrayList<>(); + this.name = name; + this.variables = variables; + this.precondition = precondition; + this.effects = effects; + effectsNegativeLiterals = new HashSet<>(); + effectsPositiveLiterals = new HashSet<>(); + effectsMaybePositiveLiterals = new HashSet<>(); + effectsMaybeNegativeLiterals = new HashSet<>(); + this.sortEffects(); + } + + public AngelicHLA(String name, List variables, String precondition, String effects) { + this(name, variables, Utils.parse(precondition), Utils.angelicParse(effects)); + } + + private void sortEffects() { + effectsPositiveLiterals.addAll(this.effects.get(0)); + effectsNegativeLiterals.addAll(this.effects.get(1)); + effectsMaybePositiveLiterals.addAll(this.effects.get(2)); + effectsMaybeNegativeLiterals.addAll(this.effects.get(3)); + } + + public List getVariables() { + return variables; + } + + public List getPrecondition() { + return precondition; + } + + public List> getEffects() { + return effects; + } + + public String getName() { + return name; + } + + public HashSet getEffectsPositiveLiterals() { + return effectsPositiveLiterals; + } + + public HashSet getEffectsNegativeLiterals() { + return effectsNegativeLiterals; + } + + public HashSet getEffectsMaybePositiveLiterals() { + return effectsMaybePositiveLiterals; + } + + public HashSet getEffectsMaybeNegativeLiterals() { + return effectsMaybeNegativeLiterals; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("Action(" + this.getName() + ")\n\tPRECOND:"); + for (Literal precond : + getPrecondition()) { + result.append("^").append(precond.toString()); + } + result.append("\n\tEFFECT:"); + for (Literal effect : + getEffectsPositiveLiterals()) { + result.append("^").append(effect.toString()); + } + + for (Literal effect : + getEffectsNegativeLiterals()) { + result.append("^~").append(effect.toString()); + } + + for (Literal effect : + getEffectsMaybePositiveLiterals()) { + if (getEffectsMaybeNegativeLiterals().contains(effect)) + result.append("^~+-").append(effect.toString()); + else + result.append("^~+").append(effect.toString()); + } + + for (Literal effect : + getEffectsMaybeNegativeLiterals()) { + result.append("^~-").append(effect.toString()); + } + + + return result.toString(); + } + + @Override + public int hashCode() { + int hashCode = 17; + for (Literal preCo : + this.getPrecondition()) { + hashCode = 37 * hashCode + preCo.hashCode(); + } + for (Literal effect : + this.getEffectsPositiveLiterals()) { + hashCode = 37 * hashCode + effect.hashCode(); + } + + for (Literal effect : + this.getEffectsNegativeLiterals()) { + hashCode = 37 * hashCode + effect.hashCode(); + } + + for (Literal effect : + this.getEffectsMaybePositiveLiterals()) { + hashCode = 37 * hashCode + effect.hashCode(); + } + + for (Literal effect : + this.getEffectsMaybeNegativeLiterals()) { + hashCode = 37 * hashCode + effect.hashCode(); + } + + for (Term var : + this.getVariables()) { + hashCode = 37 * hashCode + var.hashCode(); + } + return hashCode; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof AngelicHLA)) + return false; + return this.getName().equals(((AngelicHLA) obj).getName()) && + this.getPrecondition().containsAll(((AngelicHLA) obj).getPrecondition()) + && ((AngelicHLA) obj).getPrecondition().containsAll(this.getPrecondition()) + && this.getEffectsPositiveLiterals().containsAll(((AngelicHLA) obj).getEffectsPositiveLiterals()) + && ((AngelicHLA) obj).getEffectsPositiveLiterals().containsAll(this.getEffectsPositiveLiterals()) + && this.getEffectsNegativeLiterals().containsAll(((AngelicHLA) obj).getEffectsNegativeLiterals()) + && ((AngelicHLA) obj).getEffectsNegativeLiterals().containsAll(this.getEffectsNegativeLiterals()) + && this.getEffectsMaybePositiveLiterals().containsAll(((AngelicHLA) obj).getEffectsMaybePositiveLiterals()) + && ((AngelicHLA) obj).getEffectsMaybePositiveLiterals().containsAll(this.getEffectsMaybePositiveLiterals()) + && this.getEffectsMaybeNegativeLiterals().containsAll(((AngelicHLA) obj).getEffectsMaybeNegativeLiterals()) + && ((AngelicHLA) obj).getEffectsMaybeNegativeLiterals().containsAll(this.getEffectsNegativeLiterals()); + } + + } diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java new file mode 100644 index 0000000000..776d7db9f2 --- /dev/null +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java @@ -0,0 +1,5 @@ +package aima.core.logic.planning.angelicsearch; + +public class AngelicSearchAlgorithm { + +} From 1ab35ad4abacd6e8c482463aa5d913f2a318c7a1 Mon Sep 17 00:00:00 2001 From: Samagra Date: Wed, 30 May 2018 13:51:50 +0530 Subject: [PATCH 3/7] Add optimistic and pessimistic reach functions --- .../java/aima/core/logic/planning/State.java | 78 +++++++++++++++++++ .../angelicsearch/AngelicSearchAlgorithm.java | 20 +++++ .../core/unit/logic/planning/StateTest.java | 19 +++++ 3 files changed, 117 insertions(+) diff --git a/aima-core/src/main/java/aima/core/logic/planning/State.java b/aima-core/src/main/java/aima/core/logic/planning/State.java index b0a63297b0..3c5c16fd1f 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/State.java +++ b/aima-core/src/main/java/aima/core/logic/planning/State.java @@ -1,7 +1,10 @@ package aima.core.logic.planning; import aima.core.logic.fol.kb.data.Literal; +import aima.core.logic.planning.angelicsearch.AngelicHLA; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; /** @@ -65,6 +68,10 @@ public boolean isApplicable(ActionSchema a) { return this.getFluents().containsAll(a.getPrecondition()); } + public boolean isApplicable(AngelicHLA angelicHLA){ + return this.getFluents().containsAll(angelicHLA.getPrecondition()); + } + public List getFluents() { return fluents; } @@ -86,4 +93,75 @@ public int hashCode() { } return hashCode; } + + public HashSet optimisticReach(AngelicHLA angelicAction){ + HashSet result = new HashSet<>(); + State thisStateCopy = new State(new ArrayList<>(this.getFluents())); + result.add(new State(new ArrayList<>(this.getFluents()))); + if (this.isApplicable(angelicAction)) { + for (Literal fluent : + angelicAction.getEffectsNegativeLiterals()) { + Literal tempFluent = new Literal(fluent.getAtomicSentence()); + thisStateCopy.fluents.remove(tempFluent); + } + thisStateCopy.fluents.addAll(angelicAction.getEffectsPositiveLiterals()); + result.add(new State(new ArrayList<>(thisStateCopy.getFluents()))); + for (Literal literal : + angelicAction.getEffectsMaybePositiveLiterals()) { + List listToAdd = new ArrayList<>(); + for (State state : + result) { + State tempCopyState = new State(new ArrayList<>(state.getFluents())); + if (!tempCopyState.getFluents().contains(literal)) { + tempCopyState.getFluents().add(literal); + listToAdd.add(new State(new ArrayList<>(tempCopyState.getFluents()))); + } + } + result.addAll(listToAdd); + } + for (Literal literal : + angelicAction.getEffectsMaybeNegativeLiterals()) { + List listToAdd = new ArrayList<>(); + for (State state : + result) { + State tempCopyState = new State(new ArrayList<>(state.getFluents())); + if (tempCopyState.getFluents().contains(literal)) { + tempCopyState.getFluents().remove(literal); + listToAdd.add(new State(new ArrayList<>(tempCopyState.getFluents()))); + } + } + result.addAll(listToAdd); + } + } + return result; + } + + public HashSet pessimisticReach(AngelicHLA angelicAction){ + HashSet result = new HashSet<>(); + State thisStateCopy = new State(new ArrayList<>(this.getFluents())); + result.add(new State(new ArrayList<>(this.getFluents()))); + if (this.isApplicable(angelicAction)){ + for (Literal fluent : + angelicAction.getEffectsNegativeLiterals()) { + Literal tempFluent = new Literal(fluent.getAtomicSentence()); + thisStateCopy.fluents.remove(tempFluent); + } + thisStateCopy.fluents.addAll(angelicAction.getEffectsPositiveLiterals()); + } + return result; + } + + public HashSet optimisticReach(List plan){ + return null; + } + + @Override + public String toString() { + StringBuilder result = new StringBuilder("State:"); + for (Literal literal : + this.getFluents()) { + result.append("\n").append(literal.toString()); + } + return result.toString(); + } } diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java index 776d7db9f2..d5a27ef121 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java @@ -1,5 +1,25 @@ package aima.core.logic.planning.angelicsearch; +import aima.core.logic.planning.Problem; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + public class AngelicSearchAlgorithm { + public List angelicSearch(Problem problem, List initialPlan){ + Queue> frontier = new LinkedList<>(); + frontier.add(initialPlan); + while(true) { + if (frontier.isEmpty()) + return null; + List plan = frontier.poll(); + // if (problem.getInitialState().optimisticReach(plan)){ + // if(plan is primitive) + return plan; + } + } } + diff --git a/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java b/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java index e6d1a84c9b..9536bbc824 100644 --- a/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java +++ b/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java @@ -5,10 +5,14 @@ import aima.core.logic.fol.parsing.ast.Predicate; import aima.core.logic.planning.ActionSchema; import aima.core.logic.planning.State; +import aima.core.logic.planning.Utils; +import aima.core.logic.planning.angelicsearch.AngelicHLA; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import javax.sound.midi.SysexMessage; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -69,4 +73,19 @@ public void resultTest() { newState = testState.result(flyActionTwo); Assert.assertEquals(initState, newState); } + + @Test + public void optimisticReachTest(){ + Literal a = new Literal(new Predicate("A",new ArrayList<>())); + Literal b = new Literal(new Predicate("B",new ArrayList<>())); + Literal c = new Literal(new Predicate("C",new ArrayList<>())); + AngelicHLA h1 = new AngelicHLA("h1",null,"~A","A^~-B"); + AngelicHLA h2 = new AngelicHLA("h2",null,"~B","~+A^~+-C"); + State stateOne = new State(Utils.parse("~A")); + State stateTwo = new State(Utils.parse("~B")); + for (State state : + stateOne.optimisticReach(h1)) { + System.out.println(state); + } + } } From 974d6e60df0fb0d7f175eb05d9d18913d5927a95 Mon Sep 17 00:00:00 2001 From: Samagra Date: Thu, 31 May 2018 22:18:30 +0530 Subject: [PATCH 4/7] Corrections in the reach optimistic function --- .../java/aima/core/logic/planning/State.java | 40 ++++++++++++++----- .../core/unit/logic/planning/StateTest.java | 20 ++++++++-- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/aima-core/src/main/java/aima/core/logic/planning/State.java b/aima-core/src/main/java/aima/core/logic/planning/State.java index 3c5c16fd1f..35bde65e6e 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/State.java +++ b/aima-core/src/main/java/aima/core/logic/planning/State.java @@ -68,7 +68,7 @@ public boolean isApplicable(ActionSchema a) { return this.getFluents().containsAll(a.getPrecondition()); } - public boolean isApplicable(AngelicHLA angelicHLA){ + public boolean isApplicable(AngelicHLA angelicHLA) { return this.getFluents().containsAll(angelicHLA.getPrecondition()); } @@ -94,17 +94,31 @@ public int hashCode() { return hashCode; } - public HashSet optimisticReach(AngelicHLA angelicAction){ + public HashSet optimisticReach(AngelicHLA angelicAction) { HashSet result = new HashSet<>(); State thisStateCopy = new State(new ArrayList<>(this.getFluents())); - result.add(new State(new ArrayList<>(this.getFluents()))); - if (this.isApplicable(angelicAction)) { + if (!this.isApplicable(angelicAction)) { + result.add(new State(new ArrayList<>(this.getFluents()))); + return result; + } else { for (Literal fluent : angelicAction.getEffectsNegativeLiterals()) { Literal tempFluent = new Literal(fluent.getAtomicSentence()); thisStateCopy.fluents.remove(tempFluent); + tempFluent = new Literal(fluent.getAtomicSentence(), true); + if (!thisStateCopy.fluents.contains(tempFluent)) + thisStateCopy.fluents.add(tempFluent); + } + for (Literal fluent : + angelicAction.getEffectsPositiveLiterals()) { + Literal tempFluent = new Literal(fluent.getAtomicSentence(), true); + tempFluent = new Literal(tempFluent.getAtomicSentence()); + if (!thisStateCopy.fluents.contains(tempFluent)) { + thisStateCopy.fluents.add(tempFluent); + tempFluent = new Literal(tempFluent.getAtomicSentence(),true); + thisStateCopy.fluents.remove(tempFluent); + } } - thisStateCopy.fluents.addAll(angelicAction.getEffectsPositiveLiterals()); result.add(new State(new ArrayList<>(thisStateCopy.getFluents()))); for (Literal literal : angelicAction.getEffectsMaybePositiveLiterals()) { @@ -113,6 +127,8 @@ public HashSet optimisticReach(AngelicHLA angelicAction){ result) { State tempCopyState = new State(new ArrayList<>(state.getFluents())); if (!tempCopyState.getFluents().contains(literal)) { + Literal tempFluent = new Literal(literal.getAtomicSentence(), true); + tempCopyState.fluents.remove(tempFluent); tempCopyState.getFluents().add(literal); listToAdd.add(new State(new ArrayList<>(tempCopyState.getFluents()))); } @@ -125,8 +141,12 @@ public HashSet optimisticReach(AngelicHLA angelicAction){ for (State state : result) { State tempCopyState = new State(new ArrayList<>(state.getFluents())); - if (tempCopyState.getFluents().contains(literal)) { - tempCopyState.getFluents().remove(literal); + Literal tempFluent = new Literal(literal.getAtomicSentence(), true); + if (!tempCopyState.getFluents().contains(tempFluent)) { + tempFluent = new Literal(tempFluent.getAtomicSentence()); + tempCopyState.getFluents().remove(tempFluent); + tempFluent = new Literal(tempFluent.getAtomicSentence(), true); + tempCopyState.fluents.add(tempFluent); listToAdd.add(new State(new ArrayList<>(tempCopyState.getFluents()))); } } @@ -136,11 +156,11 @@ public HashSet optimisticReach(AngelicHLA angelicAction){ return result; } - public HashSet pessimisticReach(AngelicHLA angelicAction){ + public HashSet pessimisticReach(AngelicHLA angelicAction) { HashSet result = new HashSet<>(); State thisStateCopy = new State(new ArrayList<>(this.getFluents())); result.add(new State(new ArrayList<>(this.getFluents()))); - if (this.isApplicable(angelicAction)){ + if (this.isApplicable(angelicAction)) { for (Literal fluent : angelicAction.getEffectsNegativeLiterals()) { Literal tempFluent = new Literal(fluent.getAtomicSentence()); @@ -151,7 +171,7 @@ public HashSet pessimisticReach(AngelicHLA angelicAction){ return result; } - public HashSet optimisticReach(List plan){ + public HashSet optimisticReach(List plan) { return null; } diff --git a/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java b/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java index 9536bbc824..4e650a3ac4 100644 --- a/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java +++ b/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java @@ -83,9 +83,21 @@ public void optimisticReachTest(){ AngelicHLA h2 = new AngelicHLA("h2",null,"~B","~+A^~+-C"); State stateOne = new State(Utils.parse("~A")); State stateTwo = new State(Utils.parse("~B")); - for (State state : - stateOne.optimisticReach(h1)) { - System.out.println(state); - } + // States obtained after applying h1 to stateOne + State stateOneResultOne = new State(Utils.parse("A^~B")); + State stateOneResultTwo = new State(Utils.parse("A")); + Assert.assertTrue(stateOne.optimisticReach(h1).containsAll(Arrays.asList(stateOneResultTwo,stateOneResultOne))); + Assert.assertEquals(2,stateOne.optimisticReach(h1).size()); + // States obtained after applying h2 to stateTwo + Assert.assertEquals(6,stateTwo.optimisticReach(h2).size()); + State [] statesResultTwo = { + stateTwo, + new State(Utils.parse("~B^~C")), + new State(Utils.parse("~B^A^C")), + new State(Utils.parse("~B^A")), + new State(Utils.parse("~B^C")), + new State(Utils.parse("~B^A^~C")) + }; + Assert.assertTrue(stateTwo.optimisticReach(h2).containsAll(Arrays.asList(statesResultTwo))); } } From a3a0d06d0ddaada2de01650c2df4ac8e8fce0276 Mon Sep 17 00:00:00 2001 From: Samagra Date: Thu, 31 May 2018 23:50:42 +0530 Subject: [PATCH 5/7] Further refinements in reach functions --- .../java/aima/core/logic/planning/State.java | 73 +++++++++++++++++-- .../core/unit/logic/planning/StateTest.java | 73 +++++++++++++------ 2 files changed, 118 insertions(+), 28 deletions(-) diff --git a/aima-core/src/main/java/aima/core/logic/planning/State.java b/aima-core/src/main/java/aima/core/logic/planning/State.java index 35bde65e6e..4a95b6b7bb 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/State.java +++ b/aima-core/src/main/java/aima/core/logic/planning/State.java @@ -115,7 +115,7 @@ public HashSet optimisticReach(AngelicHLA angelicAction) { tempFluent = new Literal(tempFluent.getAtomicSentence()); if (!thisStateCopy.fluents.contains(tempFluent)) { thisStateCopy.fluents.add(tempFluent); - tempFluent = new Literal(tempFluent.getAtomicSentence(),true); + tempFluent = new Literal(tempFluent.getAtomicSentence(), true); thisStateCopy.fluents.remove(tempFluent); } } @@ -159,20 +159,81 @@ public HashSet optimisticReach(AngelicHLA angelicAction) { public HashSet pessimisticReach(AngelicHLA angelicAction) { HashSet result = new HashSet<>(); State thisStateCopy = new State(new ArrayList<>(this.getFluents())); - result.add(new State(new ArrayList<>(this.getFluents()))); - if (this.isApplicable(angelicAction)) { + if (!this.isApplicable(angelicAction)) { + result.add(new State(new ArrayList<>(this.getFluents()))); + return result; + } else { for (Literal fluent : angelicAction.getEffectsNegativeLiterals()) { Literal tempFluent = new Literal(fluent.getAtomicSentence()); thisStateCopy.fluents.remove(tempFluent); + tempFluent = new Literal(fluent.getAtomicSentence(), true); + if (!thisStateCopy.fluents.contains(tempFluent)) + thisStateCopy.fluents.add(tempFluent); } - thisStateCopy.fluents.addAll(angelicAction.getEffectsPositiveLiterals()); + for (Literal fluent : + angelicAction.getEffectsPositiveLiterals()) { + Literal tempFluent = new Literal(fluent.getAtomicSentence(), true); + tempFluent = new Literal(tempFluent.getAtomicSentence()); + if (!thisStateCopy.fluents.contains(tempFluent)) { + thisStateCopy.fluents.add(tempFluent); + tempFluent = new Literal(tempFluent.getAtomicSentence(), true); + thisStateCopy.fluents.remove(tempFluent); + } + } + result.add(new State(new ArrayList<>(thisStateCopy.getFluents()))); + return result; } - return result; } public HashSet optimisticReach(List plan) { - return null; + HashSet result = new HashSet<>(); + result.add(new State(this.getFluents())); + if (plan.isEmpty()) { + return result; + } + for (Object action : + plan) { + HashSet currResult = new HashSet<>(); + if (action instanceof ActionSchema) { + for (State state : + result) { + currResult.add(state.result((ActionSchema) action)); + } + } else if (action instanceof AngelicHLA) { + for (State state : + result) { + currResult.addAll(state.optimisticReach((AngelicHLA) action)); + } + } + result = currResult; + } + return result; + } + + public HashSet pessimisticReach(List plan){ + HashSet result = new HashSet<>(); + result.add(new State(this.getFluents())); + if (plan.isEmpty()) { + return result; + } + for (Object action : + plan) { + HashSet currResult = new HashSet<>(); + if (action instanceof ActionSchema) { + for (State state : + result) { + currResult.add(state.result((ActionSchema) action)); + } + } else if (action instanceof AngelicHLA) { + for (State state : + result) { + currResult.addAll(state.pessimisticReach((AngelicHLA) action)); + } + } + result = currResult; + } + return result; } @Override diff --git a/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java b/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java index 4e650a3ac4..1748521fdb 100644 --- a/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java +++ b/aima-core/src/test/java/aima/test/core/unit/logic/planning/StateTest.java @@ -11,18 +11,18 @@ import org.junit.Before; import org.junit.Test; -import javax.sound.midi.SysexMessage; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; /** * @author samagra */ public class StateTest { private Literal testFluentOne, testFluentTwo, testFluentThree, testFluentFour; - private State testState; + private State stateOne, stateTwo, testState; private ActionSchema flyActionOne, flyActionTwo; + private AngelicHLA h1, h2; @Before public void setup() { @@ -42,6 +42,11 @@ public void setup() { flyActionTwo = new ActionSchema("Fly", null, "At(P1,JFK)^Plane(P1)^Airport(SFO)^Airport(JFK)", "~At(P1,JFK)^At(P1,SFO)"); + + h1 = new AngelicHLA("h1", null, "~A", "A^~-B"); + h2 = new AngelicHLA("h2", null, "~B", "~+A^~+-C"); + stateOne = new State("~A"); + stateTwo = new State("~B"); } @Test @@ -56,6 +61,10 @@ public void constructorTest() { public void isApplicableTest() { Assert.assertTrue(testState.isApplicable(flyActionOne)); Assert.assertFalse(testState.isApplicable(flyActionTwo)); + Assert.assertTrue(stateOne.isApplicable(h1)); + Assert.assertFalse(stateOne.isApplicable(h2)); + Assert.assertTrue(stateTwo.isApplicable(h2)); + Assert.assertFalse(stateTwo.isApplicable(h1)); } @Test @@ -75,29 +84,49 @@ public void resultTest() { } @Test - public void optimisticReachTest(){ - Literal a = new Literal(new Predicate("A",new ArrayList<>())); - Literal b = new Literal(new Predicate("B",new ArrayList<>())); - Literal c = new Literal(new Predicate("C",new ArrayList<>())); - AngelicHLA h1 = new AngelicHLA("h1",null,"~A","A^~-B"); - AngelicHLA h2 = new AngelicHLA("h2",null,"~B","~+A^~+-C"); - State stateOne = new State(Utils.parse("~A")); - State stateTwo = new State(Utils.parse("~B")); + public void optimisticReachTest() { // States obtained after applying h1 to stateOne - State stateOneResultOne = new State(Utils.parse("A^~B")); - State stateOneResultTwo = new State(Utils.parse("A")); - Assert.assertTrue(stateOne.optimisticReach(h1).containsAll(Arrays.asList(stateOneResultTwo,stateOneResultOne))); - Assert.assertEquals(2,stateOne.optimisticReach(h1).size()); + State stateOneResultOne = new State("A^~B"); + State stateOneResultTwo = new State("A"); + Assert.assertTrue(stateOne.optimisticReach(h1).containsAll(Arrays.asList(stateOneResultTwo, stateOneResultOne))); + Assert.assertEquals(2, stateOne.optimisticReach(h1).size()); // States obtained after applying h2 to stateTwo - Assert.assertEquals(6,stateTwo.optimisticReach(h2).size()); - State [] statesResultTwo = { + Assert.assertEquals(6, stateTwo.optimisticReach(h2).size()); + State[] statesResultTwo = { stateTwo, - new State(Utils.parse("~B^~C")), - new State(Utils.parse("~B^A^C")), - new State(Utils.parse("~B^A")), - new State(Utils.parse("~B^C")), - new State(Utils.parse("~B^A^~C")) + new State("~B^~C"), + new State("~B^A^C"), + new State("~B^A"), + new State("~B^C"), + new State("~B^A^~C") }; Assert.assertTrue(stateTwo.optimisticReach(h2).containsAll(Arrays.asList(statesResultTwo))); } + + @Test + public void pessimisticReachTest() { + Assert.assertEquals(1, stateOne.pessimisticReach(h1).size()); + Assert.assertTrue(stateOne.pessimisticReach(h1). + contains(new State("A"))); + Assert.assertEquals(1, stateTwo.pessimisticReach(h2).size()); + Assert.assertTrue(stateTwo.pessimisticReach(h2). + contains(new State("~B"))); + } + + @Test + public void optimisticReachListTest(){ + HashSet resultingStates = stateOne.optimisticReach(Arrays.asList(h1, h2)); + Assert.assertEquals(4,resultingStates.size()); + Assert.assertTrue(resultingStates.contains(new State("A"))); + Assert.assertTrue(resultingStates.contains(new State("A^~B"))); + Assert.assertTrue(resultingStates.contains(new State("A^~B^C"))); + Assert.assertTrue(resultingStates.contains(new State("A^~B^~C"))); + } + + @Test + public void pessimisticReachTestList(){ + HashSet resultStates = stateOne.pessimisticReach(Arrays.asList(h1,h2)); + Assert.assertEquals(1,resultStates.size()); + Assert.assertTrue(resultStates.contains(new State("A"))); + } } From c40193824065e52ae74545559ccef39bb24e70e1 Mon Sep 17 00:00:00 2001 From: Samagra Date: Fri, 1 Jun 2018 10:30:47 +0530 Subject: [PATCH 6/7] Adds angelic hla --- .../planning/PlanningProblemFactory.java | 5 + .../planning/angelicsearch/AngelicHLA.java | 16 ++- .../angelicsearch/AngelicSearchAlgorithm.java | 116 ++++++++++++++++-- 3 files changed, 128 insertions(+), 9 deletions(-) diff --git a/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java b/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java index 5389fa60ff..5c08b89f80 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java +++ b/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java @@ -2,6 +2,7 @@ import aima.core.logic.fol.parsing.ast.Constant; import aima.core.logic.fol.parsing.ast.Variable; +import aima.core.logic.planning.angelicsearch.AngelicHLA; import aima.core.logic.planning.hierarchicalsearch.HighLevelAction; import java.util.ArrayList; @@ -142,4 +143,8 @@ public static HighLevelAction getHlaAct(Problem problem) { act.addRefinement(new ArrayList<>()); return act; } + + public static List getAngelicInitialPlan(List list){ + AngelicHLA act = new AngelicHLA("act",null,"",""); + } } diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java index cff9869de1..ee9cfe0e86 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Objects; public class AngelicHLA { List variables;// list of variables @@ -18,9 +19,22 @@ public class AngelicHLA { HashSet effectsMaybePositiveLiterals; HashSet effectsMaybeNegativeLiterals; private String name;//action name + List> refinements = new ArrayList<>(); + + public void setRefinements(List> refinements) { + this.refinements = refinements; + } + + public void addRefinement(List newRefinement){ + this.refinements.add(newRefinement); + } + + public List> getRefinements() { + return refinements; + } public AngelicHLA(String name, List variables, - List precondition, List> effects) { + List precondition, List> effects) { if (variables == null) variables = new ArrayList<>(); this.name = name; diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java index d5a27ef121..a8d1b070c8 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java @@ -1,25 +1,125 @@ package aima.core.logic.planning.angelicsearch; +import aima.core.logic.planning.ActionSchema; import aima.core.logic.planning.Problem; +import aima.core.logic.planning.State; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; +import java.util.*; public class AngelicSearchAlgorithm { - public List angelicSearch(Problem problem, List initialPlan){ + public List angelicSearch(Problem problem, List initialPlan) { Queue> frontier = new LinkedList<>(); frontier.add(initialPlan); - while(true) { + while (true) { if (frontier.isEmpty()) return null; List plan = frontier.poll(); - // if (problem.getInitialState().optimisticReach(plan)){ - // if(plan is primitive) + + boolean flag = false; + for (State state : + problem.getInitialState().optimisticReach(plan)) { + if (state.getFluents().containsAll(problem.getGoalState().getFluents())) + flag = true; + } + if (flag) { + if (checkPrimitive(plan)) + return plan; + HashSet guaranteed = problem.getInitialState().pessimisticReach(plan); + guaranteed.add(problem.getGoalState()); + if ((!guaranteed.isEmpty()) && makingProgress(plan, initialPlan)) { + State finalState = guaranteed.iterator().next(); + return decompose(problem.getInitialState(), plan, finalState); + } + int i = 0; + AngelicHLA hla; + while (i < plan.size() && !(plan.get(i) instanceof AngelicHLA)) + i++; + if (i < plan.size()) + hla = (AngelicHLA) plan.get(i); + else + hla = null; + // prefix,suffix ← the action subsequences before and after hla in plan + List prefix = new ArrayList<>(); + List suffix = new ArrayList<>(); + for (int j = 0; j < i; j++) { + prefix.add( plan.get(j)); + } + for (int j = i + 1; j < plan.size(); j++) { + suffix.add(plan.get(j)); + } + List tempInsertionList = new ArrayList<>(); + HashSet outcomeStates = problem.getInitialState().optimisticReach(prefix); + for (List sequence : + refinements(hla,outcomeStates)){ + tempInsertionList.clear(); + tempInsertionList.addAll(prefix); + tempInsertionList.addAll(sequence); + tempInsertionList.addAll(suffix); + ((LinkedList>) frontier).addLast(new ArrayList<>(tempInsertionList)); + } + } return plan; + } + } + + private boolean makingProgress(List plan, List initialPlan) { + return !(plan.containsAll(initialPlan)&&initialPlan.containsAll(plan)); + } + + private boolean checkPrimitive(List plan) { + for (Object obj : + plan) { + if (!(obj instanceof ActionSchema)) + return false; + } + return true; + } + + private List decompose(State initialState, List plan, State finalState) { + List solution = new ArrayList<>(); + while(!plan.isEmpty()){ + Object action = plan.remove(plan.size()-1); + State si = new State(""); + for (State state : + initialState.pessimisticReach(plan)) { + if (state.pessimisticReach(Collections.singletonList(action)).contains(finalState)){ + si = state; + break; + } + } + Problem problem = new Problem(si,finalState,new HashSet<>()); + solution.add(angelicSearch(problem,Collections.singletonList(action))); + finalState = si; + } + return solution; + } + public List> refinements(AngelicHLA hla, HashSet outcome) { + List> result = new ArrayList<>(); + for (List refinement : + hla.getRefinements()) { + if (refinement.size() > 0) { + if (refinement.get(0) instanceof AngelicHLA) { + for (State state : + outcome) { + if (state.isApplicable((AngelicHLA) refinement.get(0))) { + result.add(refinement); + break; + } + } + } else { + for (State state : + outcome) { + if (state.isApplicable((ActionSchema) refinement.get(0))) { + result.add(refinement); + break; + } + } + } + } else + result.add(refinement); } + return result; } } From f74f722b76ceb0d2a67737caaade53cfa70f992c Mon Sep 17 00:00:00 2001 From: Samagra Date: Sat, 2 Jun 2018 11:47:42 +0530 Subject: [PATCH 7/7] Additions to the HLA --- .../planning/PlanningProblemFactory.java | 23 +++++++++--- .../planning/angelicsearch/AngelicHLA.java | 35 +++++++++++-------- .../angelicsearch/AngelicSearchAlgorithm.java | 25 ++++++++++--- .../angelicsearch/AngelicSearchTest.java | 25 +++++++++++++ 4 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 aima-core/src/test/java/aima/test/core/unit/logic/planning/angelicsearch/AngelicSearchTest.java diff --git a/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java b/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java index 5c08b89f80..30e41604c1 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java +++ b/aima-core/src/main/java/aima/core/logic/planning/PlanningProblemFactory.java @@ -1,13 +1,12 @@ package aima.core.logic.planning; +import aima.core.logic.fol.kb.data.Literal; import aima.core.logic.fol.parsing.ast.Constant; import aima.core.logic.fol.parsing.ast.Variable; import aima.core.logic.planning.angelicsearch.AngelicHLA; import aima.core.logic.planning.hierarchicalsearch.HighLevelAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; /** * A problem factory to generate planning problems. @@ -144,7 +143,21 @@ public static HighLevelAction getHlaAct(Problem problem) { return act; } - public static List getAngelicInitialPlan(List list){ - AngelicHLA act = new AngelicHLA("act",null,"",""); + public static Problem getAngelicABProblem(){ + return new Problem(new State("~A"), + new State("A^C"), + new HashSet<>()); + } + + public static List getAngelicInitialPlan(List refinements,Problem problem,String goal){ + List effects = new ArrayList<>(); + AngelicHLA act = new AngelicHLA("act",null,problem.getInitialState().getFluents(), + Utils.angelicParse(goal)); + for (Object obj : + refinements) { + act.addRefinement(Arrays.asList(obj, act)); + } + act.addRefinement(new ArrayList<>()); + return Collections.singletonList(act); } } diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java index ee9cfe0e86..feac2f002a 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicHLA.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Objects; public class AngelicHLA { List variables;// list of variables @@ -18,20 +17,8 @@ public class AngelicHLA { HashSet effectsNegativeLiterals; HashSet effectsMaybePositiveLiterals; HashSet effectsMaybeNegativeLiterals; - private String name;//action name List> refinements = new ArrayList<>(); - - public void setRefinements(List> refinements) { - this.refinements = refinements; - } - - public void addRefinement(List newRefinement){ - this.refinements.add(newRefinement); - } - - public List> getRefinements() { - return refinements; - } + private String name;//action name public AngelicHLA(String name, List variables, List precondition, List> effects) { @@ -52,6 +39,18 @@ public AngelicHLA(String name, List variables, String precondition, String this(name, variables, Utils.parse(precondition), Utils.angelicParse(effects)); } + public void addRefinement(List newRefinement) { + this.refinements.add(newRefinement); + } + + public List> getRefinements() { + return refinements; + } + + public void setRefinements(List> refinements) { + this.refinements = refinements; + } + private void sortEffects() { effectsPositiveLiterals.addAll(this.effects.get(0)); effectsNegativeLiterals.addAll(this.effects.get(1)); @@ -121,6 +120,14 @@ public String toString() { getEffectsMaybeNegativeLiterals()) { result.append("^~-").append(effect.toString()); } + for (List refinement : + this.getRefinements()) { + result.append("\n"); + for (Object act : + refinement) { + result.append("\n").append(((AngelicHLA) act).getName()); + } + } return result.toString(); diff --git a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java index a8d1b070c8..e9a934f2cb 100644 --- a/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java +++ b/aima-core/src/main/java/aima/core/logic/planning/angelicsearch/AngelicSearchAlgorithm.java @@ -13,21 +13,37 @@ public List angelicSearch(Problem problem, List initialPlan) { while (true) { if (frontier.isEmpty()) return null; + for (List obj : + frontier) { + System.out.println("Frontier list"); + for (Object object: + obj) { + System.out.println(object.toString()); + } + } List plan = frontier.poll(); - boolean flag = false; for (State state : problem.getInitialState().optimisticReach(plan)) { if (state.getFluents().containsAll(problem.getGoalState().getFluents())) flag = true; } + System.out.println("Flag ========"+flag); if (flag) { if (checkPrimitive(plan)) return plan; - HashSet guaranteed = problem.getInitialState().pessimisticReach(plan); - guaranteed.add(problem.getGoalState()); + HashSet guaranteed = new HashSet<>(); + for (State state : + problem.getInitialState().pessimisticReach(plan)) { + if (state.getFluents().containsAll(problem.getGoalState().getFluents())){ + guaranteed.add(state); + System.out.println("guaranteed state== "+ state.toString() ); + } + } + System.out.println( makingProgress(plan, initialPlan) ); if ((!guaranteed.isEmpty()) && makingProgress(plan, initialPlan)) { State finalState = guaranteed.iterator().next(); + System.out.println("BOOOOOYEAHHHH"); return decompose(problem.getInitialState(), plan, finalState); } int i = 0; @@ -44,6 +60,8 @@ public List angelicSearch(Problem problem, List initialPlan) { for (int j = 0; j < i; j++) { prefix.add( plan.get(j)); } + System.out.println("Prefix ===== "+prefix.size()); + System.out.println("Prefix"); for (int j = i + 1; j < plan.size(); j++) { suffix.add(plan.get(j)); } @@ -58,7 +76,6 @@ public List angelicSearch(Problem problem, List initialPlan) { ((LinkedList>) frontier).addLast(new ArrayList<>(tempInsertionList)); } } - return plan; } } diff --git a/aima-core/src/test/java/aima/test/core/unit/logic/planning/angelicsearch/AngelicSearchTest.java b/aima-core/src/test/java/aima/test/core/unit/logic/planning/angelicsearch/AngelicSearchTest.java new file mode 100644 index 0000000000..982ec29aff --- /dev/null +++ b/aima-core/src/test/java/aima/test/core/unit/logic/planning/angelicsearch/AngelicSearchTest.java @@ -0,0 +1,25 @@ +package aima.test.core.unit.logic.planning.angelicsearch; + +import aima.core.logic.planning.ActionSchema; +import aima.core.logic.planning.PlanningProblemFactory; +import aima.core.logic.planning.angelicsearch.AngelicHLA; +import aima.core.logic.planning.angelicsearch.AngelicSearchAlgorithm; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class AngelicSearchTest { + @Test + public void angelicSearchTest(){ + AngelicHLA h1 = new AngelicHLA("h1", null, "~A", "A^~-B"); + AngelicHLA h2 = new AngelicHLA("h2", null, "~B", "~+A^~+-C"); + ActionSchema + AngelicSearchAlgorithm algo = new AngelicSearchAlgorithm(); + System.out.println("Answer"); + List list = algo.angelicSearch(PlanningProblemFactory.getAngelicABProblem(), + PlanningProblemFactory.getAngelicInitialPlan(new ArrayList<>(Arrays.asList(h1,h2)),PlanningProblemFactory.getAngelicABProblem(),"A^C")); + System.out.println(list.size()); + } +}