cps721: questions about the 5th assignment.  

Questions related to the 5th assignment

This page contains questions from students and my answers to them. If a question is asked that has already been answered, then I will not post another answer. So if your questions seems to go unanswered, you should check over previous questions.

Q1
Can I use "not" in my rules?
A1
You can use negation, for example applied to a fluent, in your rules, but remember that your precondition rules should not begin with negation that is applied to predicate with variables, if variables have not yet been assigned any value. This means that you have to call other predicates first, such that they will retrieve values to variables and, subsequently, you can write negations of predicates at the end of your rule. Recall that a body of each rule is simply conjunction of logical statements and its logical meaning remains the same if you rearrange predicates so that those which have no negation at front of them will be called at the beginning of your rule. You can review the slide 16 "Caution: variables and negation" from the "Prolog basics" that we discussed at the beginning of this course: this slide illustrates my explanations.

Q2
Can I submit my solutions of the 5th assignment earlier? I have other work to do in the end of November.
A2
Yes, you are welcome to submit your solutions earlier. If you submit them before 9pm, Sunday, November 26, you will get extra 10% bonus to your mark for the 5th assignment! However, check first whether your programs work correctly. If you lose, say, 20 points due to errors, but submit early, then you get in total only (100 - 20) *1.1 = 88 points.

Q3
For part 1, one of the goal states took me 4 minutes (without declarative heuristics) to execute even though in the question, it suggests that it should run a few seconds only. The solution is correct. But am I doing something wrong? I don't consider my computer to be slow.
A3
Make sure you are using types for all variables, e.g., soap(P), or washer(W), and so on, read assignment carfully for available types. There might be a minor bug in your program that slows down search that your program does. Print your program and read it very carefully. Compare your program with the specification given in the assignment and clarified on this Web page (see above). If this does not help, put it away, and read again next day. In some cases, you can spot a bug just by reading your program afresh, or with one of your friends. As an alternative approach, you can try to solve several easier, but related planning problems. For example, try goal states that can be reached with fewer actions. In other words, try to solve planning problems that are easier than that one which takes a long time for your computer to solve. For each of this intermediate goal state, record how much time it takes your program to compute a plan. You may notice, that some planning problems can be solved fast, but others takes long time. This may give you an idea that a delay can be due to a particular action, and consequently, may be your precondition rule, or other rules for this action are wrong. To check your precondition rules, query whether an action is possible to do after a sequence of some other actions. If you get intuitively wrong answers, then some of your rules are wrong. You may have bugs in precondition rules, in successor state rules, or both. Also, when you try a few different goals (with the same initial state) you may catch a bug, if you will see that your program does not compute a plan that it is supposed to compute for some of the goal states. However, exploring different goal states takes time. So, first try to read your program and find a bug. Another useful debuging trick is to try specific sequences of actions, and see if they lead to the goal states as expected. If intuitively you expect a sequence of actions to be a plan solving a problem, but your program says "no", then there is a bug somewhere. You can try to trace a query using combination of "creep" (if you would like to see every step) and "skip" (if you would like to skip some rules altogether when you know there is no bug there). ECLiPSe Prolog has a nice graphical debugger. By exploring different sequences of actions, you can usually locate a bug quickly.

Q4
When writing rules for fluents, are we allowed to use fluents for defining other fluents? for example using fluent "f1" and "f2" for defining fluent "f3" ?
A4
No, you cannot write rules that compute whether a fluent is true in a situation S by using in the body of your rule fluents with respect to same situation S. There are counter-examples when rules of this type lead to wrong logical conclusions. You have to write genuine successor state axioms (SSAs) for each of the given fluents. Note that each SSA is a rule such that on the left hand side we write a fluent with respect to the next situation [A | S] (that results from doing an action in a current situation S), and in the body of the rule we use fluents (and other predicates) that use the current situation S only. Read carefully the examples that we discussed in class, e.g., monkey-banana example and situation and fluents implementation of 3 coins puzzle.
Note that rather than saying that we define fluent, we say that we write a SSA for a fluent. Recall that there are two types of SSAs that you have to write. First, rules that say when a fluent becomes true in the next situation thanks to an action A. Sometimes, we say in this case, that an action A has a positive effect on this fluent. Second, rules that say that a fluent remains true in the next situation, if it is true in the current situation, and the most recent action A is not one of those which have a negative effect on the fluent (i.e., not one of those, which can make it false).

Q5
If I run a query like "poss(actionName(arg1,arg2),S)" should it take a long time to find a solution?
A5
All simple testing queries should be instanteneous. If any of them takes more than a few seconds, there is a bug in your program. This applies only to queries that have no variables, i.e., where arguments are instantiated properly. However, note that S is a variable in your query

        ?- poss(actionName(arg1,arg2),S).
This is wrong. You should type a list of actions instead of S, or simply [], if you are testing if action "actionName(arg1,arg2)" is possible initially. Otherwise, if you have a variable S in this query, you are asking your program to plan for a sequence of actions that leads to a state where "actionName(arg1,arg2)" is possible. Basically, you are asking your program to solve a planning problem. This may take a long time even if your program is not buggy, sine there are no means to guarantee that S is built out of legal_move actions. I would expect that this query may not be answered at all even by a correct program because it will do infinite recursion over lists of situations. So, you should better avoid queries that use predicate poss with S as a variable argument. In contrast, a query like
        ?- poss(actionName(arg1,arg2),[act1, act2]).
should be answered immediately if your program is correct, where act1 and act2 are kind of place holders for action terms.

Q6
Can I introduce new predicates and use them in precondition rules or successor state rules?
A6
No. You are not allowed to introduce any new predicates. You can use only the predicate given to you in the assignment.

Q7
In the 'dining philosophers' problem (part 2) of Assignment 5, the description of the "waiting" fluent indicates that "He [the philosopher] switches from thinking to waiting by picking up a fork, or from eating to waiting by putting down one of his two forks...". Then in the "happy" fluent, it indicates that the philosopher "becomes happy after eating in the previous situation as soon as he puts down at least one of his forks."
It seems to me that these two fluents have the same requirement. If the philosopher is eating, then puts down a fork, it appears that he could go into either waiting or happy. I would intuitively think that he should be happy after eating, and not go back to waiting, but the description doesn't indicate that to me.
A7
The fluents "happy" and "waiting" serve different purposes and they have different dynamics. Note that when an eating philosopher puts down one of his forks, he becomes both waiting and happy. This follows from specifications that you quoted. However, once a philosopher has become happy, he remains happy forever. However, if a waiting philosopher puts down his last fork, he becomes thinking, not waiting. In other words, the philosopher can undergo transitions eating --> waiting --> thinking. Also, if a waiting philosopher (who holds only 1 fork) picks up the second fork, then he can try to eat. If the conditions are right, he may become eating again, and then he will no longer be waiting. In other words, the following transitions are possible: thinking --> waiting --> eating. This demonstrates that "waiting" is a kind of intermediate transient experience between thinking and eating. Now the differences between "waiting" and "happy" should be clear: "happy" is a kind of absorbing feeling that can be reached only from "eating", but once a philoshoper got into this feeling, he cannot become unhappy. In other words, there is a transition eating--> happy, and all subsequent actions lead from "happy" back to "happy". (If I could, I should draw a kind of loop or cyclic arrow around the node "happy".) In case, if you are wondering what is the purpose of introducing the fluent "happy", then notice that it serves as a kind of label for the fact that a philospher has eaten once. This label is convenient, when we formulate a goal state saying that there should be a situation when all philosophers are not hungry, i.e., when all of them had a chance to eat at least once. Without the fluent "happy" we cannot specify such goal state. So, the fluent "happy" is a somewhat auxiliary fluent that serves technical purposes.

Q8
In Question 2, one of the conditions for the eating(P,S) fluent is: "If a waiting philosopher is trying to eat when 2 other philosophers are already eating, he cannot eat, but keeps waiting." However, there are only three philosophers and three forks in the initialization file -- so this will never happen. With three forks, it's only possible for one philosopher to be eating at once.
Are we expected to test our program with a higher number of philosophers? For example, with seven philosophers and seven forks?
A8
You have to write your precondition rules and SSA rules without regard to what initial or goal states are given to you. This is because your precondition rules and SSA rules should be applicable to any number of philosophers and forks. This is the main advantage of the situations and fluents approach over a simple-minded approach when state is represented using a list. All examples that we discussed have general precondition rules and SSA rules, including the coins on the desk and tiles on the grid. Once you have correct rules, you can test them on specific instances of the planning problem. It is up to you which instances you might wish to try, but if you do testing with 7 philosophers, choose a goal state that can be easily reached from your initial state. You are expected to test only simple instances like those given in the assignment. In any case, the TA will be testing your programs using his own instance of a planning problem, e.g., with 4 or 5 philosophers. Also, the TA will be reading and testing your rules. If they are not general, or if they do not implement specifications from the assignment, then you may lose marks.

Q9
For Question 1 Part (a) of Assignment 5, should we be checking if the variable is a certain type? For example, for hasSoap(W,S), should we be doing washer(W) and soap(S)? And if so, should these conditions be in both the precondition axioms and the successor-state axioms?

A9
Yes, you have to add types to the precondition axioms. However, notice that   S   is a situation variable, but you are supposed to use P as a variable for soap in the 5th assignment. Note usually you do not need types in the SSA rules.

Q10
In part 1, for situations like such as when adding soap to the washer with addSoap(P,W) (assuming all its preconditions are met), should we no longer be holding P?
A10
Yes, this is stated in the assignment when the meaning of the fluent holding(P,S) is expained: see the top half of the 2nd page. Once you have added a soap (or a softener), you are no longer holding it, and consequently, you cannot put it away.

Q11
When testing the following query:

  ?- poss(washClothes(cl1, w1), [addSoftener(sft1, w1), fetch(sft1, cbd1), 
        addSoap(p1, w1), fetch(p1,cbd1), move(cl1, w1, h1)]).
    Yes (0.00s cpu, solution 1, maybe more)
We get the answer yes quickly, but when doing the query:
?- solve_problem(6, Plan).
The answer does not return in a remotely reasonable time. How would I approach debugging such an issue to speed-up my program?
A11
You must look through your code for small "issues" that will impede the program from running in a few seconds. This means checking if you are unnecessarily using the various auxiliary predicates, making sure inefficiencies have been dealt with, and using the debugging of poss in a more detailed manner. Specifically, for each action in your list, query if it is consecutively possible after the preceeding actions.

Q12
Do the soap and softener need to be put away after they are used?  Or are they the "pod" type that can simply be tossed in (versus a bottle that must be poured and returned)? If the soap and softener do not need to be put away, then I'm not sure what the purpose of the putAway action would be.
A12
No, the robot does not have to put the soap and softener away, i.e., they are not in the bottle. Please note this is related to Q10/A10 above.
Anyway, the pair of actions fetch/putAway is a usual example of a reversible action, and it is included to avoid hard-coding of solutions to the laundry-related planning problems. Each solution to the planning problem should involve a fair amount of reasoning. Let your program discover a solution.

Q13
Can you fold something in a container? There is no constraint saying you can not.
A13
For simplicity, let's assume that clothes can be folded anywhere, e.g., even if they are in a container.

Q14
The actions fetch(O,C) and putAway(O,C) are defined only for cupboards, but can they apply to any container?
A14
Yes, this would be a natural extension of the application domain. You might wish to explore the case when actions fetch or put away apply to any container, not only to a cupboard. But this is not required.

Q15
Can we say   waiting(P,S):- not thinking and not eating ?   If not, how can we approach this specification? 
A15
You cannot write rules like this: see Q4/A4 above. Write SSA rules for each fluent "f", as explained in the class and in the assignment, e.g.,
f(X, [ A | S]) :- A=actionInitiatesFluent(X,Y), conditionsPos(S).         /* how fluent becomes true */
f(X, [ A | S]) :- not A=actionTerminatesFluent(X,Y), conditionsNeg(S).         /* when fluent remains true */

where conditionsPos(S), conditionsNeg(S) can include same fluent "f", or any other given fluents, or a formula composed from the given fluents. Note that in the head of SSA rules you have to write fluent "f" with respect to next situation [A | S], but in the bodies of these rules the fluents can mention only the current situation S. We discussed in class that SSAs are recursive rules that reduce a query about any given list of actions to a query wrt to a shorter list of actions that has one action A less. Therefore, each recursive query about a fluent wrt a given list of action terminates and consults the values of the fluents given in the initial situation represented as the empty list []. We discussed many examples of SSA rules in class. Ask other students for copies of their lecture notes, if you missed classes.

Q16
I read the QA and I think you said that we cannot use other fluents in the bodies of our fluents, but I am just wondering how would we complete the question, since most of the fluents are dependent on the truth of other fluents.
A16
Read Q15/A15 above. All SSA rules must use only the fluents given to you in the assignment. The SSA for the fluent "f" can use in the rule body any given fluents wrt S. However, the declarative heurisitc rules for the predicate "useless" can use the library predicates that we discussed in class, if they can help.

Q17
For our useless predicate, we are running into issues with what we can say is useless in terms of reaching the goal state. For example, [...skip...] This useless predicate would make our program run within the appropriate time frame, however, this will also make it impossible [..skip...]
A17
You can write any domain specific declarative heuristics, as long as they are general enough, i.e., they are always applicable to this domain. Moreover, they must not prevent the program from solving any reasonable and realistic planning problems with related, but different goals. In other words, the rules defining the predicate "useless" should work with any "real life" and sensible initial and goal states.

Q18
For some reason I get the same solution multiple times when I press 'more', for both parts of the assignment.
A18
The planner should not be repeating solutions. Each time you should be getting a new correct plan. Check if there are bugs in your program. Make sure you compile the main program that loads by itself the corresponding "init" part.

Q19
In the action definitions, you mention that for move(C,F,T), "The container T can be a dresser, or a hamper, or a washer, or a dryer that is empty." However, in one of the goals given for the question: 

goal_state(S) :- clean(cl1,S), clean(cl2,S), not wet(cl1,S), not wet(cl2,S),
        folded(cl1,S), folded(cl2,S), in(cl1,dresser,S), in(cl2,dresser,S).
both cl1 and cl2 are in the dresser. Given that they do not start there, this means that they must have be put there using move(C,F,T). How can we move both clothes, if the dresser becomes not-empty as we move the first into it?
A19
You can remove the condition that the target container T must be empty, before something can be moved into T. After that, you can try to solve this more difficult planning problem. However, your program is not required to produce plans for this long and complex goal state, only if you are curios. No extra marks for this goal state.

Q20

A20

 

 


CPS721