### -*- Mode: SDE -*- ############################################################################### ### ### File : travel.soar ### Original author(s): Peter Hastings ### Organization : University of Michigan AI Lab ### Created on : 20 Mar 1996, 12:11:41 ### Update Count : 32 ### Last Modified By : Soar ### Last Modified On : 21 Mar 1997, 14:07:37 ### Soar Version : 7 ### ### Description : A simple example program to suggest travel methods. ### In this version, I am taking out the productions which get input ### from the user, and I'm converting to counting money instead of ### asking the user for it. ### 960520: In this version, I'm implementing a simple lookahead. ############################################################################### indifferent-selection -random ############################################################################### ### First set up the problem on the top-state ### Start out with a particular distance to travel, and money in the ### wallet. If you want to change the behavior of the program, change ### and reload this production. It can also take ^tens and ^twenties. sp {set-up-problem (state ^superstate nil) --> ( ^required-distance 7 ^money ) ( ^ones 5 ^fives 1)} ############################################################################### ### Propose the walk operator ### This operator is proposed if the required distance is less than 1 (mile?) sp {propose-walk-operator (state ^superstate nil ^required-distance < 1) --> ( ^operator ) ( ^name walk)} ############################################################################### ### Propose the take-the-bus operator ### This operator is proposed if the required distance is between than ### 1 and 10. sp {propose-bus-operator (state ^superstate nil ^required-distance {> 1 <= 10}) --> ( ^operator ) ( ^name take-the-bus)} ############################################################################### ### Propose the take-a-taxi operator ### This operator is proposed if the required distance is between than ### 5 and 15. sp {propose-taxi-operator (state ^superstate nil ^required-distance {> 5 <= 15}) --> ( ^operator ) ( ^name take-a-taxi)} ############################################################################### ### Propose the take-the-train operator ### This operator is proposed if the required distance is between than ### 15 and 200. sp {propose-train-operator (state ^superstate nil ^required-distance {> 15 <= 200}) --> ( ^operator ) ( ^name take-the-train)} ############################################################################### ### Propose the airplane operator ### This operator is proposed if the required distance is greater than 200. sp {propose-airplane-operator (state ^superstate nil ^required-distance > 200) --> ( ^operator ) ( ^name airplane)} ############################################################################### ############################################################################### ### Halt the program ### For this simple program, all we want is for an operator to be ### selected at the topstate. So when there is a selected operator, ### this production halts Soar. Normally this would be a bad ### condition for halting Soar because the program would be taking its ### first action in problem solving at the top level at this point. sp {halt-the-program (state ^superstate nil ^operator ) ( ^name ) --> (write (crlf) |The proposed method of travel is | ) (halt)} ############################################################################### ### Name the compare-operators problem space. ### This production fires when Soar has encountered an operator tie ### impasse, and it creates a problem space for the subgoal, and ### names it compare-operators. sp {name-compare-operators-ps (state ^impasse tie ^attribute operator) --> ( ^problem-space

) (

^name compare-operators)} ############################################################################### ### Propose initializing the money sum ### Upon arriving in the compare-operators problem space, the goal is ### to count the money on hand, so that one of the operators can be ### selected. To start this process, we must have a money-sum of 0. ### This production proposes an operator to initialize the money-sum. sp {propose*init-money (state ^problem-space.name compare-operators -^money-sum) --> ( ^operator ) ( ^name init-money)} ############################################################################### ### Apply the init-money operator ### If init-money is the current operator, set the money-sum to 0. sp {apply*init-money (state ^problem-space.name compare-operators ^operator.name init-money) --> ( ^money-sum 0)} ############################################################################### ### Terminate the init-money operator ### If the money-sum is 0, then terminate the init-money operator. sp {terminate*init-money (state ^problem-space.name compare-operators ^operator ^money-sum 0) ( ^name init-money) --> ( ^operator @)} ############################################################################### ### Propose the add-ones operator ### If there is a money-sum, and the added-ones flag is not on the ### state, and if there is a number of ones on the superstate, then ### propose the add-ones operator with the new-sum, and the old sum. ### ### Note: this set of operators uses flags to assure that the ### operators are not repeated once they have been done. The new-sum ### and old-sum arguments to the operator allow it to know when ### operator has been completed, and can be terminated. sp {propose*add-ones (state ^problem-space.name compare-operators ^money-sum -^added-ones ^superstate.money.ones ) --> ( ^operator + =) ( ^name add-ones ^new-sum (+ ) ^old-sum )} ############################################################################### ### Apply the add-ones operator ### If the current operator is add-ones, then give an acceptable ### preference for the new-sum value, and give a reject preference for ### the old-sum value, and put the added-ones flag on the state. sp {add-ones*apply (state ^operator ) ( ^name add-ones ^new-sum ^old-sum ) --> ( ^money-sum - ^added-ones *yes*)} ############################################################################### ### Terminate the add-ones operator ### If the money-sum is the same as new-sum, then terminate the ### add-ones operator. sp {add-ones*terminate (state ^operator ^money-sum ) ( ^name add-ones ^new-sum ) --> ( ^operator @)} ############################################################################### ### Propose the add-fives operator ### Essentially the same as add-ones, except that the number of fives ### is multiplied by 5 to make the new-sum. sp {propose*add-fives (state ^problem-space.name compare-operators ^money-sum -^added-fives ^superstate.money.fives ) --> ( ^operator + =) ( ^name add-fives ^new-sum (+ (* 5)) ^old-sum )} ############################################################################### ### Apply the add-fives operator sp {add-fives*apply (state ^operator ^superstate.money.fives ) ( ^name add-fives ^new-sum ^old-sum ) --> ( ^money-sum - ^added-fives *yes*)} ############################################################################### ### Terminate the add-fives operator sp {add-fives*terminate (state ^operator ^money-sum ) ( ^name add-fives ^new-sum ) --> ( ^operator @)} ############################################################################### ### Propose the add-tens operator sp {propose*add-tens (state ^problem-space.name compare-operators ^money-sum -^added-tens ^superstate.money.tens ) --> ( ^operator + =) ( ^name add-tens ^new-sum (+ (* 10)) ^old-sum )} ############################################################################### ### Apply the add-tens operator sp {add-tens*apply (state ^operator ^superstate.money.tens ) ( ^name add-tens ^new-sum ^old-sum ) --> ( ^money-sum - ^added-tens *yes*)} ############################################################################### ### Terminate the add-tens operator sp {add-tens*terminate (state ^operator ^money-sum ) ( ^name add-tens ^new-sum ) --> ( ^operator @)} ############################################################################### ### Propose the add-twenties operator. sp {propose*add-twenties (state ^problem-space.name compare-operators ^money-sum -^added-twenties ^superstate.money.twenties ) --> ( ^operator + =) ( ^name add-twenties ^new-sum (+ (* 20)) ^old-sum )} ############################################################################### ### Apply the add-twenties operator sp {add-twenties*apply (state ^operator ^superstate.money.twenties ) ( ^name add-twenties ^new-sum ^old-sum ) --> ( ^money-sum - ^added-twenties *yes*)} ############################################################################### ### Terminate the add-twenties operator sp {add-twenties*terminate (state ^operator ^money-sum ) ( ^name add-twenties ^new-sum ) --> ( ^operator @)} ############################################################################### ############################################################################### ### Production to propose the finished-counting operator ### When there is a money-sum on the state of the compare-operators ### problem space, propose the finished-counting operator. Give it a ### worst preference so that it is not selected until all other ### operators (init-money, add-ones, etc) are completed. sp {propose*finished-counting (state ^problem-space.name compare-operators ^money-sum ) --> ( ^operator + <) ( ^name finished-counting)} ############################################################################### ### Production to apply the operator ### If finished-counting is the current operator, then put the ### finished-counting flag on the state. sp {finished-counting*apply (state ^operator.name finished-counting) --> ( ^finished-counting *yes*)} ############################################################################### ### Production to terminate the finished-counting operator sp {finished-counting*terminate (state ^operator ^finished-counting *yes*) ( ^name finished-counting) --> ( ^operator @)} ############################################################################### ############################################################################### ### Propose evaluate-operator for each tied operator ### If the money-sum is computed, and we are in the compare-operators ### problem space with tied operator , then propose an operator to ### evaluate . Make it indifferent so that Soar can randomly ### choose between possibilities for the lookahead search. sp {propose*evaluate-operator (state ^problem-space.name compare-operators ^finished-counting *yes* ^item ) --> ( ^operator + =) ( ^name evaluate-operator ^operator )} ############################################################################### ### Terminate evaluate-operator ### If the current evaluate-operator has an evaluation (*success* or ### *failure*), then terminate that operator. sp {terminate*evaluate-operator (state ^problem-space.name compare-operators ^operator ) ( ^name evaluate-operator ^evaluation ) --> ( ^operator @)} ############################################################################### ### Name the evaluate problem space ### If there is an operator no-change impasse, and the superstate's ### problem space is compare-operators, then name this the evaluate ### problem space. sp {name*evaluate*ps (state ^superstate ^impasse no-change ^attribute operator) ( ^problem-space.name compare-operators) --> ( ^problem-space

) (

^name evaluate)} ############################################################################### ### Copy the money sum to the evaluate space ### If the current space is evaluate and the superstate has a ### money-sum, copy it to the current state. sp {copy*money-sum (state ^problem-space.name evaluate ^superstate.money-sum ) --> ( ^money-sum )} ############################################################################### ### Copy the required distance to the evaluate space ### If the current space is evaluate and the superstate has a ### required-distance, copy it to the current state. sp {copy*required-distance (state ^problem-space.name evaluate ^superstate.superstate.required-distance ) --> ( ^required-distance )} ############################################################################### ### Propose the lookahead operator ### If the superstate's operator is to evaluate operator , ### and if no travel has been completed in this state, then propose ### as the operator in the current state. sp {propose-evaluate-operator (state ^problem-space.name evaluate ^superstate.operator -^bus-taken -^taxi-taken) ( ^name evaluate-operator ^operator ) ( ^name ) --> ( ^operator ) ( ^name )} ############################################################################### ### Productions to apply and terminate the take-the-bus and ### take-a-taxi operators ############################################################################### ### Apply take-the-bus ### If the current operator is take-the-bus, and the bus hasn't ### already been taken, and the distance required is and the ### money on hand is , then change the money-sum to be - ### (i.e. 1 dollar per km). sp {apply*take-the-bus (state ^operator ^required-distance ^money-sum -^bus-taken) ( ^name take-the-bus) --> ( ^money-sum (- ) - ^bus-taken *yes*)} ############################################################################### ### Terminate take-the-bus ### If the current operator is take-the-bus, and the bus has been ### taken, then terminate. sp {terminate*take-the-bus (state ^operator ^bus-taken *yes*) ( ^name take-the-bus) --> ( ^operator @)} ############################################################################### ### Apply take-a-taxi ### If the current operator is take-a-taxi, and a taxi hasn't ### already been taken, and the distance required is and the ### money on hand is , then change the money-sum to be - *3 ### (i.e. 3 dollars per km). sp {apply*take-a-taxi (state ^operator ^required-distance ^money-sum -^taxi-taken) ( ^name take-a-taxi) --> ( ^money-sum (- (* 3)) - ^taxi-taken *yes*)} ############################################################################### ### Terminate take-a-taxi ### If the current operator is take-a-taxi, and a taxi has been ### taken, then terminate. sp {terminate*take-a-taxi (state ^operator ^taxi-taken *yes*) ( ^name take-a-taxi) --> ( ^operator @)} ############################################################################### ### Productions to perform the evaluation ############################################################################### ### Propose do-evaluation ### If the current problem space is evaluate, then propose the ### do-evaluation operator and give it a worst preference. sp {propose*do-evaluation (state ^problem-space.name evaluate) --> ( ^operator + <) ( ^name do-evaluation)} ############################################################################### ### Apply do-evaluation for failure ### If the amount of money on hand is less than zero (after paying for ### the travel), return a *failure* evaluation on the superstate's ### operator (the evaluate-operator operator for the current mode of ### travel). sp {apply*do-evaluation*failure (state ^problem-space.name evaluate ^operator.name do-evaluation ^money-sum < 0 ^superstate.operator ) --> ( ^evaluation *failure*)} ############################################################################### ### Apply do-evaluation for success ### If the amount of money on hand is greater than or equal to zero ### (after paying for the travel), return a *success* evaluation on ### the superstate's operator (the evaluate-operator operator for the ### current mode of travel). sp {apply*do-evaluation*success (state ^problem-space.name evaluate ^operator.name do-evaluation ^money-sum >= 0 ^superstate.operator ) --> ( ^evaluation *success*)} ############################################################################### ### Productions to translate success or failure into desirability ### preferences on the topstate's operators. ############################################################################### ### Return a best preference for success ### If the current evaluate-operator has a success flag, and if the ### corresponding operator on the superstate is , then give ### a best preference on the superstate. sp {return*best-preference (state ^problem-space.name compare-operators ^operator ^superstate ) ( ^name evaluate-operator ^operator ^evaluation *success*) ( ^operator +) --> ( ^operator >)} ############################################################################### ### Return a worst preference for failure ### If the current evaluate-operator has a failure flag, and if the ### corresponding operator on the superstate is , then give ### a worst preference on the superstate. sp {return*worst-preference (state ^problem-space.name compare-operators ^operator ^superstate ) ( ^name evaluate-operator ^operator ^evaluation *failure*) ( ^operator +) --> ( ^operator <)}