mirror of
				https://github.com/RAIRLab/Spectra.git
				synced 2025-11-02 23:01:20 +00:00 
			
		
		
		
	Improving DCEC support
- Time based search algorithm - Added new variables ?now and ?next
This commit is contained in:
		
							parent
							
								
									a747b38233
								
							
						
					
					
						commit
						01883787da
					
				
					 5 changed files with 364 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -4,11 +4,12 @@ import org.rairlab.planner.utils.Visualizer;
 | 
			
		|||
import org.rairlab.shadow.prover.core.Prover;
 | 
			
		||||
import org.rairlab.shadow.prover.core.ccprovers.CognitiveCalculusProver;
 | 
			
		||||
import org.rairlab.shadow.prover.core.proof.Justification;
 | 
			
		||||
import org.rairlab.shadow.prover.representations.formula.BiConditional;
 | 
			
		||||
import org.rairlab.shadow.prover.representations.formula.Formula;
 | 
			
		||||
 | 
			
		||||
import org.rairlab.shadow.prover.representations.value.Value;
 | 
			
		||||
import org.rairlab.shadow.prover.representations.value.Variable;
 | 
			
		||||
import org.rairlab.shadow.prover.representations.formula.*;
 | 
			
		||||
import org.rairlab.shadow.prover.representations.value.Constant;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import org.rairlab.shadow.prover.utils.CollectionUtils;
 | 
			
		||||
 | 
			
		||||
import org.rairlab.shadow.prover.utils.Sets;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,11 +17,14 @@ import org.apache.commons.lang3.tuple.Pair;
 | 
			
		|||
import org.apache.commons.lang3.tuple.ImmutablePair;
 | 
			
		||||
import org.apache.commons.lang3.tuple.Triple;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.*;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by naveensundarg on 1/13/17.
 | 
			
		||||
| 
						 | 
				
			
			@ -155,10 +159,37 @@ public class Operations {
 | 
			
		|||
        return Optional.of(ans.get().getRight());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Value getTime(int time) {
 | 
			
		||||
        return new Constant("t" + time);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Optional<Set<Pair<State, Action>>> apply(Set<Formula> background, Action action, State state) {
 | 
			
		||||
    public static int getTime(Value time) {
 | 
			
		||||
        String s = time.getName();
 | 
			
		||||
        String[] ss = s.split("t");
 | 
			
		||||
        if (ss.length != 2) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            int t = Integer.parseInt(ss[1]);
 | 
			
		||||
            return t + 1;
 | 
			
		||||
        } catch (NumberFormatException e) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        // Get resulting states from cache if computed before
 | 
			
		||||
    // Take a time value, get the integer number out and
 | 
			
		||||
    // increment by 1
 | 
			
		||||
    public static Value incrementTime(Value time) {
 | 
			
		||||
        int t = getTime(time);
 | 
			
		||||
        if (t < 0) {
 | 
			
		||||
            return new Constant("ERROR");
 | 
			
		||||
        }
 | 
			
		||||
        return new Constant("t" + (t + 1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Optional<Set<Pair<State, Action>>> apply(Set<Formula> background, Action action, State state, Value t) {
 | 
			
		||||
 | 
			
		||||
        // // Get resulting states from cache if computed before
 | 
			
		||||
        if(applyCache.containsKey(Triple.of(background, action, state))){
 | 
			
		||||
            Optional<Set<Pair<State, Action>>>  ans  = applyCache.get(Triple.of(background, action, state));
 | 
			
		||||
            if(ans.isPresent()){
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +200,22 @@ public class Operations {
 | 
			
		|||
 | 
			
		||||
        // Ask theorem prover for witnesses that satisfy the precondition
 | 
			
		||||
        Set<Formula> givens = Sets.union(background, state.getFormulae());
 | 
			
		||||
        Optional<Set<Map<Variable, Value>>> bindingsOpt = proveAndGetBindingsCached(givens, action.getPrecondition(), action.openVars());
 | 
			
		||||
 | 
			
		||||
        // TODO: Have all this ?now and (next ?now) code within Action.java
 | 
			
		||||
 | 
			
		||||
        // Replace ?now with current time within preconditions
 | 
			
		||||
        Formula precondition = action.getPrecondition();
 | 
			
		||||
        Value now = new Variable("?now");
 | 
			
		||||
        precondition = replaceValue(precondition, now, t);
 | 
			
		||||
 | 
			
		||||
        // We already replaced the ?now
 | 
			
		||||
        List<Variable> openVars = action.openVars()
 | 
			
		||||
            .stream()
 | 
			
		||||
            .filter(v -> !v.getName().equals("?now"))
 | 
			
		||||
            .collect(Collectors.toList());
 | 
			
		||||
 | 
			
		||||
        // TODO: Can likely more intelligently cache considering time...
 | 
			
		||||
        Optional<Set<Map<Variable, Value>>> bindingsOpt = proveAndGetBindingsCached(givens, precondition, openVars);
 | 
			
		||||
 | 
			
		||||
        // If not witnesses found, return nothing
 | 
			
		||||
        if (!bindingsOpt.isPresent()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -191,9 +237,19 @@ public class Operations {
 | 
			
		|||
            // newState = (oldState - Deletions(a)) U Additions(a)
 | 
			
		||||
            Action groundedAction = action.instantiate(binding);
 | 
			
		||||
 | 
			
		||||
            Set<Formula> additions = groundedAction.getAdditions();
 | 
			
		||||
            Set<Formula> deletions = groundedAction.getDeletions();
 | 
			
		||||
 | 
			
		||||
            // Replace (next ?now) with appropriate time
 | 
			
		||||
            Value nextTime = incrementTime(t);
 | 
			
		||||
            Value nextTimeVar = new Variable("?next");
 | 
			
		||||
            additions = replaceValue(additions, nextTimeVar, nextTime);
 | 
			
		||||
            deletions = replaceValue(deletions, nextTimeVar, nextTime);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            State newState = State.initializeWith(Sets.union(
 | 
			
		||||
                Sets.difference(state.getFormulae(), groundedAction.getDeletions()),
 | 
			
		||||
                groundedAction.getAdditions()
 | 
			
		||||
                Sets.difference(state.getFormulae(), deletions),
 | 
			
		||||
                additions
 | 
			
		||||
            ));
 | 
			
		||||
 | 
			
		||||
            // If the state progresses, record it as a possible next state
 | 
			
		||||
| 
						 | 
				
			
			@ -203,10 +259,102 @@ public class Operations {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        applyCache.put(Triple.of(background, action, state), Optional.of(nextStates));
 | 
			
		||||
 | 
			
		||||
        return Optional.of(nextStates);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static State replaceValue(State s, Value r, Value t) {
 | 
			
		||||
        Set<Formula> newFormulae = replaceValue(s.getFormulae(), r, t);
 | 
			
		||||
        return State.initializeWith(newFormulae);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Set<Formula> replaceValue(Set<Formula> s, Value r, Value t) {
 | 
			
		||||
        Set<Formula> newFormulae = new HashSet<Formula>();
 | 
			
		||||
        for (Formula f : s) {
 | 
			
		||||
            newFormulae.add(replaceValue(f, r, t));
 | 
			
		||||
        }
 | 
			
		||||
        return newFormulae;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Value replaceValue(Value v, Value r, Value t) {
 | 
			
		||||
        if (v.getName().equals(r.getName())) {
 | 
			
		||||
            return t;
 | 
			
		||||
        }
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Everywhere where there's a ?now replace with value t
 | 
			
		||||
    public static Formula replaceValue(Formula f, Value r, Value t) {
 | 
			
		||||
        // Base Cases:
 | 
			
		||||
 | 
			
		||||
        // Bottom of Formula graph wouldn't have any time points under it
 | 
			
		||||
        if (f instanceof Predicate || f instanceof Atom) {
 | 
			
		||||
            return f;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check if these quantifiers contain our bound varialbe
 | 
			
		||||
        if (f instanceof UnaryModalFormula) {
 | 
			
		||||
            UnaryModalFormula uf = (UnaryModalFormula) f;
 | 
			
		||||
 | 
			
		||||
            Value agent = uf.getAgent();
 | 
			
		||||
            Value time = uf.getTime();
 | 
			
		||||
            Value newTime = replaceValue(time, r, t);
 | 
			
		||||
            Formula uf_sub = uf.getFormula();
 | 
			
		||||
            Formula new_uf_sub = replaceValue(uf_sub, r, t);
 | 
			
		||||
 | 
			
		||||
            if (f instanceof Belief) {
 | 
			
		||||
                return new Belief(agent, newTime, new_uf_sub);
 | 
			
		||||
            } else if (f instanceof Intends) {
 | 
			
		||||
                return new Intends(agent, newTime, new_uf_sub);
 | 
			
		||||
            } else if (f instanceof Knowledge) {
 | 
			
		||||
                return new Knowledge(agent, newTime, new_uf_sub);
 | 
			
		||||
            }
 | 
			
		||||
            // Assumes Perception
 | 
			
		||||
            if (! (f instanceof Perception)) {
 | 
			
		||||
                System.out.println("[fixTimepoints:Operations.java] Doesn't account for new modal operator");
 | 
			
		||||
            }
 | 
			
		||||
            return new Perception(agent, newTime, new_uf_sub);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Recusive Case: Iterate over each subformula and replace
 | 
			
		||||
 | 
			
		||||
        if (f instanceof Not) {
 | 
			
		||||
            Formula subFormula = ((Not) f).getArgument();
 | 
			
		||||
            return new Not(replaceValue(subFormula, r, t));
 | 
			
		||||
        } else if (f instanceof Universal) {
 | 
			
		||||
            Formula subFormula = ((Universal) f).getArgument();
 | 
			
		||||
            return new Universal(((Universal) f).vars(), replaceValue(subFormula, r, t));
 | 
			
		||||
        } else if (f instanceof Existential) {
 | 
			
		||||
            Formula subFormula = ((Existential) f).getArgument();
 | 
			
		||||
            return new Universal(((Existential) f).vars(), replaceValue(subFormula, r, t));
 | 
			
		||||
        } else if (f instanceof Implication) {
 | 
			
		||||
            Formula antecedant = ((Implication) f).getAntecedent();
 | 
			
		||||
            Formula consequent = ((Implication) f).getConsequent();
 | 
			
		||||
            return new Implication(replaceValue(antecedant, r, t), replaceValue(consequent, r, t));
 | 
			
		||||
        } else if (f instanceof BiConditional) {
 | 
			
		||||
            Formula left = ((BiConditional) f).getLeft();
 | 
			
		||||
            Formula right = ((BiConditional) f).getRight();
 | 
			
		||||
            return new BiConditional(replaceValue(left, r, t), replaceValue(right, r, t));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Formula> subFormulae = f.getArgs();
 | 
			
		||||
        List<Formula> newArguments = new ArrayList<Formula>();
 | 
			
		||||
        for (Formula sf : subFormulae) {
 | 
			
		||||
            newArguments.add(replaceValue(sf, r, t));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (f instanceof And) {
 | 
			
		||||
            return new And(newArguments);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Assume Or
 | 
			
		||||
        if (! (f instanceof Or)) {
 | 
			
		||||
            System.out.println("[fixTimepoints:Operations.java] Not accounting for formula type in recursive case");
 | 
			
		||||
        }
 | 
			
		||||
        return new Or(newArguments);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean equivalent(Set<Formula> background, Formula f1, Formula f2) {
 | 
			
		||||
        if (!DEEP_EQUIVALENCE) {
 | 
			
		||||
            return f1.equals(f2);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import org.rairlab.planner.State;
 | 
			
		|||
import org.rairlab.planner.Action;
 | 
			
		||||
import org.rairlab.planner.Plan;
 | 
			
		||||
import org.rairlab.planner.Operations;
 | 
			
		||||
import org.rairlab.shadow.prover.representations.value.Value;
 | 
			
		||||
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +68,10 @@ public class AStarPlanner {
 | 
			
		|||
        comparator.setValue(searchStart, 0);
 | 
			
		||||
        search.add(searchStart);
 | 
			
		||||
 | 
			
		||||
        // For debugging...
 | 
			
		||||
        Map<State, List<Action>> seq = new HashMap<State, List<Action>>();
 | 
			
		||||
        seq.put(start, new ArrayList<Action>());
 | 
			
		||||
 | 
			
		||||
        // Current set of plans
 | 
			
		||||
        Set<Plan> plansFound = new HashSet<Plan>();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +86,11 @@ public class AStarPlanner {
 | 
			
		|||
            State lastState = currentSearch.getLeft();
 | 
			
		||||
            List<Action> previous_actions = currentSearch.getRight();
 | 
			
		||||
 | 
			
		||||
            // System.out.println("Considering state with heuristic: " + comparator.getValue(currentSearch));
 | 
			
		||||
            System.out.println("--------------------");
 | 
			
		||||
            System.out.println("Considering state with heuristic: " + comparator.getValue(currentSearch));
 | 
			
		||||
            System.out.println("Current Plan: " + seq.get(lastState).toString());
 | 
			
		||||
            System.out.println("Current State: " + lastState.toString());
 | 
			
		||||
            System.out.println("--------------------");
 | 
			
		||||
 | 
			
		||||
            // Exit loop if we've passed the depth limit
 | 
			
		||||
            int currentDepth = previous_actions.size();
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +114,10 @@ public class AStarPlanner {
 | 
			
		|||
 | 
			
		||||
            // Apply the action to the state and add to the search space
 | 
			
		||||
            for (Action action : nonTrivialActions) {
 | 
			
		||||
                Optional<Set<Pair<State, Action>>> optNextStateActionPairs = Operations.apply(background, action, lastState);
 | 
			
		||||
                // System.out.println("Considering action: " + action.getName());
 | 
			
		||||
 | 
			
		||||
                Value currentTime = Operations.getTime(previous_actions.size());
 | 
			
		||||
                Optional<Set<Pair<State, Action>>> optNextStateActionPairs = Operations.apply(background, action, lastState, currentTime);
 | 
			
		||||
 | 
			
		||||
                // Ignore actions that aren't applicable
 | 
			
		||||
                if (optNextStateActionPairs.isEmpty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -137,6 +149,10 @@ public class AStarPlanner {
 | 
			
		|||
                    int heuristicValue = heuristic.apply(nextState);
 | 
			
		||||
                    comparator.setValue(futureSearch, planCost + heuristicValue);
 | 
			
		||||
                    search.add(futureSearch);
 | 
			
		||||
 | 
			
		||||
                    // For debugging...
 | 
			
		||||
                    seq.put(nextState, next_actions);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ public final class Runner {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        AStarPlanner astarplanner = new AStarPlanner();
 | 
			
		||||
        astarplanner.setK(2);
 | 
			
		||||
        astarplanner.setK(1);
 | 
			
		||||
 | 
			
		||||
        for (PlanningProblem planningProblem : planningProblemList) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,108 @@
 | 
			
		|||
; Original problem from Joerg Hoffmann and Ronen Brafman
 | 
			
		||||
{:name "Block-Conformant-Tiny"
 | 
			
		||||
    :background [
 | 
			
		||||
        ; Setting object types
 | 
			
		||||
        (block b1)
 | 
			
		||||
        (block b2)
 | 
			
		||||
 | 
			
		||||
        ; Unique name axioms
 | 
			
		||||
        (not (= b1 b2))
 | 
			
		||||
 | 
			
		||||
        ; Block World Axioms
 | 
			
		||||
 | 
			
		||||
        ; Blocks are never on themselves
 | 
			
		||||
        (forall [x] (not (on x x)))
 | 
			
		||||
        ; on is not symmetric
 | 
			
		||||
        (forall [x y] (if (on x y) (not (on y x))))
 | 
			
		||||
        ; Any block on a table isn't on top of another block
 | 
			
		||||
        (forall [x y] (if (on-table x) (not (on x y))))
 | 
			
		||||
        ; Any block that is cleared does not have another block on top of it
 | 
			
		||||
        (forall [x y] (if (clear x) (not (on y x))))
 | 
			
		||||
 | 
			
		||||
        ; NOTE: Slow if we use complicated definitions
 | 
			
		||||
        ;; ; A block is on the table if it isn't on top of any other block
 | 
			
		||||
        ;; (forall [x] (iff (on-table x) (forall [y] (not (on x y)))))
 | 
			
		||||
        ;; ; A block is cleared if there is no other block on top of it
 | 
			
		||||
        ;; (forall [x] (iff (clear x) (forall [y] (not (on y x)))))
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    :actions [
 | 
			
		||||
 | 
			
		||||
        (define-action move-bstack-to-t [?b ?b1] {
 | 
			
		||||
            :preconditions [ 
 | 
			
		||||
                ; Type restriction
 | 
			
		||||
                (block ?b)
 | 
			
		||||
                (block ?b1)
 | 
			
		||||
                ; Arguments unique
 | 
			
		||||
                (not (= ?b ?b1))
 | 
			
		||||
 | 
			
		||||
                ; Preconditions
 | 
			
		||||
                ;; (not (on-table ?b))
 | 
			
		||||
 | 
			
		||||
            ]
 | 
			
		||||
            ; TODO: Think hard about the effect
 | 
			
		||||
            ;;   :effect (and (when (on ?b ?bl) 
 | 
			
		||||
            ;;         (and (not (on ?b ?bl)) (on-table ?b) (clear ?bl)))))
 | 
			
		||||
            :additions [
 | 
			
		||||
                ; The following creates a contradiction because
 | 
			
		||||
                ; (on-table ?b) -> (not (on ?b ?b1)) and
 | 
			
		||||
                ; we can't have P -> \neg P
 | 
			
		||||
                ;; (if (on ?b ?b1) (and (on-table ?b) (clear ?b1))) 
 | 
			
		||||
 | 
			
		||||
            ]
 | 
			
		||||
            :deletions [ ]
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        (define-action move-t-to-b [?bm ?bt ?t] {
 | 
			
		||||
            :preconditions [
 | 
			
		||||
                ; Type restrictions
 | 
			
		||||
                (block ?bm)
 | 
			
		||||
                (block ?bt)
 | 
			
		||||
                ; Arguments unique
 | 
			
		||||
                (not (= ?bm ?bt))
 | 
			
		||||
                ; Primary preconditions
 | 
			
		||||
                (clear ?bm ?t)
 | 
			
		||||
                (clear ?bt ?t)
 | 
			
		||||
                (on-table ?bm ?t)
 | 
			
		||||
            ]
 | 
			
		||||
            :additions [
 | 
			
		||||
                (on ?bm ?bt (s ?t))
 | 
			
		||||
 | 
			
		||||
                (not (clear ?bt (s ?t)))
 | 
			
		||||
                (not (on-table ?bm (s ?t)))
 | 
			
		||||
            ]
 | 
			
		||||
            :deletions [
 | 
			
		||||
                ;; (not (on ?bm ?bt))
 | 
			
		||||
                
 | 
			
		||||
                ;; (clear ?bt)
 | 
			
		||||
                ;; (on-table ?bm)
 | 
			
		||||
            ]
 | 
			
		||||
        })
 | 
			
		||||
    ]
 | 
			
		||||
    :start [
 | 
			
		||||
        ; Unknown facts don't need to be stated 
 | 
			
		||||
        ; since we don't assume closed world assumption.
 | 
			
		||||
 | 
			
		||||
        ; Negated predicates in this example is handled by
 | 
			
		||||
        ; the block world axioms
 | 
			
		||||
 | 
			
		||||
        (or
 | 
			
		||||
            (and 
 | 
			
		||||
                (on b2 b1 t0)
 | 
			
		||||
                (clear b2 t0)
 | 
			
		||||
                (on-table b1 t0)
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            (and
 | 
			
		||||
                (on b1 b2 t0)
 | 
			
		||||
                (clear b1 t0)
 | 
			
		||||
                (on-table b2 t0)
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
    ]
 | 
			
		||||
    :goal [
 | 
			
		||||
        (exists [x] (on b2 b1 x))
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,81 @@
 | 
			
		|||
; Original problem from Joerg Hoffmann and Ronen Brafman
 | 
			
		||||
{:name "Block-Conformant-Tiny"
 | 
			
		||||
    :background [
 | 
			
		||||
        ; Setting object types
 | 
			
		||||
        (Believes! a t0 (block b1))
 | 
			
		||||
        (Believes! a t0 (block b2))
 | 
			
		||||
 | 
			
		||||
        ; Unique name axioms
 | 
			
		||||
        (Believes! a t0 (not (= b1 b2)))
 | 
			
		||||
 | 
			
		||||
        ; Block World Axioms
 | 
			
		||||
 | 
			
		||||
        ; Blocks are never on themselves
 | 
			
		||||
        (Believes! a t0 (forall [x] (not (on x x))))
 | 
			
		||||
        ; on is not symmetric
 | 
			
		||||
        (Believes! a t0 (forall [x y] (if (on x y) (not (on y x)))))
 | 
			
		||||
        ; Any block on a table isn't on top of another block
 | 
			
		||||
        (Believes! a t0 (forall [x y] (if (on-table x) (not (on x y)))))
 | 
			
		||||
        ; Any block that is cleared does not have another block on top of it
 | 
			
		||||
        (Believes! a t0 (forall [x y] (if (clear x) (not (on y x)))))
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    :actions [
 | 
			
		||||
 | 
			
		||||
        (define-action move-t-to-b [?bm ?bt] {
 | 
			
		||||
            :preconditions [
 | 
			
		||||
                (Believes! a ?now (and
 | 
			
		||||
                    ; Type Restrictions
 | 
			
		||||
                    (block ?bm)
 | 
			
		||||
                    (block ?bt)
 | 
			
		||||
                    ; Arguments Unique
 | 
			
		||||
                    (not (= ?bm ?bt))
 | 
			
		||||
                    ; Primary preconditions
 | 
			
		||||
                    (clear ?bm)
 | 
			
		||||
                    (clear ?bt)
 | 
			
		||||
                    (on-table ?bm)
 | 
			
		||||
                ))
 | 
			
		||||
                ; NOTE: QA Algorithm is very barebones,
 | 
			
		||||
                ; currently does not support beliefs under
 | 
			
		||||
                ; binary operations. Example:
 | 
			
		||||
                ;; (and
 | 
			
		||||
                ;;     (Believes! a t0 (block ?bm))
 | 
			
		||||
                ;;     (Believes! a t0 (block ?bt))
 | 
			
		||||
                ;; )
 | 
			
		||||
            ]
 | 
			
		||||
            :additions [
 | 
			
		||||
                ; ShadowProver uses string comparisons to determine 
 | 
			
		||||
                ; ordering on time points.
 | 
			
		||||
                ; Spectra currently hacks around this by replacing
 | 
			
		||||
                ; ?next where the constant
 | 
			
		||||
                ; that represents ?now + 1.
 | 
			
		||||
                ; ShadowProver Limitation: Cannot go beyond 10 time points
 | 
			
		||||
                (Believes! a ?next (on ?bm ?bt))
 | 
			
		||||
 | 
			
		||||
                ; These below shouldn't be needed but left for posterity
 | 
			
		||||
                ;; (Believes! a ?next (not (clear ?bt)))
 | 
			
		||||
                ;; (Believes! a ?next (not (on-table ?bm)))
 | 
			
		||||
            ]
 | 
			
		||||
            :deletions [ ]
 | 
			
		||||
        })
 | 
			
		||||
    ]
 | 
			
		||||
    :start [
 | 
			
		||||
        ; Unknown facts don't need to be stated 
 | 
			
		||||
        ; since we don't assume closed world assumption.
 | 
			
		||||
 | 
			
		||||
        ; Negated predicates in this example is handled by
 | 
			
		||||
        ; the block world axioms
 | 
			
		||||
 | 
			
		||||
        (Believes! a t0 (on-table b2))
 | 
			
		||||
        (Believes! a t0 (on-table b1))
 | 
			
		||||
        (Believes! a t0 (clear b1))
 | 
			
		||||
        (Believes! a t0 (clear b2))
 | 
			
		||||
    ]
 | 
			
		||||
    :goal [
 | 
			
		||||
        ;; (Believes! a t0 (clear ?bm))
 | 
			
		||||
        ; Try a there exists at some point
 | 
			
		||||
        (exists [t] (Believes! a t (on b1 b2)))
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue