home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / clips_2 / CLIPS / MyExample / comp < prev   
Encoding:
Text File  |  1998-01-29  |  35.6 KB  |  1,096 lines

  1. ;                        CLIPS assignment                     Justin Fletcher
  2. ;                        ================                <Gerph@innocent.com>
  3. ;
  4. ; Obviously this assignment is not written as well as it might, and as much
  5. ; of the database was written before I had learnt about many of the features
  6. ; of clips it has lead to some curious representations of the data. The major
  7. ; example of this is the 'buy' routines in the 'do' section of stage which
  8. ; could be massively simplified by making a generic format.
  9. ;
  10. ; Acknowledgement and disclaimer
  11. ; ------------------------------
  12. ; Also, whilst I've based the ideal of how the questions work on those
  13. ; examples supplied with clips, the code is all my own. These provided
  14. ; a lot of insights into techiniques I could used. The particular examples
  15. ; which I have used as the basis for the principles (although I had the
  16. ; idea for how I /wanted/ to do it, honest) are the Animals and Wine
  17. ; examples.
  18.  
  19. ;**************************************************************************
  20. ;***                          The templates                             ***
  21. ;**************************************************************************
  22.  
  23. ; A template for the question we'll need for storing the question
  24. ; the questions consist of an id (is) which is used to reference each of them
  25. ; with the initial question being triggered being 'question-1'.
  26. ; The question itself is the 'ask', and the outcome is in 'true' or 'false',
  27. ; both of which consist of a condition which will be set followed by a
  28. ; question id which should be asked later. Regardless of the choice, the
  29. ; 'next' field will be followed to trigger the next question
  30. ; These are parsed by stage 2
  31. (deftemplate question
  32.    (slot is (default none) )               ; our question id
  33.    (multislot true (default none none) )   ; (what to set) (question to ask)
  34.    (multislot false (default none none) )  ; ditto, but if they answer no
  35.    (slot ask (default "No question specified!") ) ; the question to ask
  36.    (slot next (default none) )             ; the next id to go to
  37. )
  38.  
  39. ; A requirements template - used to do boring if-then's without all that
  40. ; tedious mucking about in defrule's
  41. ; The case section must have all its entries satisfied before the require
  42. ; section will be executed. The require section is quite complex, but mostly
  43. ; consists of 'buy <something>', 'set <variable>' or 'inc <entry>' which
  44. ; try to buy an item, set an condition flag, or increment a variable
  45. ; respectively.
  46. ; These are parsed by stage 3
  47. (deftemplate requires
  48.    (multislot case (default none))    ; we can say we /always/ need something
  49.    (multislot require (default none)) ; we may want to add more things
  50. )
  51.  
  52. ;**************************************************************************
  53. ;***                            The database                            ***
  54. ;**************************************************************************
  55.  
  56. ; How much is VAT atm (easier than fiddling with lots of variables) ?
  57. (deffacts vat
  58.    (vat 1.175)
  59. )
  60.  
  61. ; Computer itself
  62. ; computer name price mem vram monitor HD extras...
  63. (deffacts computer
  64.   (computer  699 rpc700 4 0 14 210)
  65.   (computer  899 rpc700 4 1 14 540)
  66.   (computer 1099 rpc700 8 2 14 540)
  67.   (computer 1399 rpc700 8 2 17 540)
  68.   (computer  499  a7000 4 0 14 0)
  69. )
  70.  
  71. ; Additional internals
  72. ; memory price size
  73. (deffacts memory
  74.   (memory 170 32)
  75.   (memory 89 16)
  76.   (memory 49 8)
  77.   (memory 35 4)
  78. )
  79.  
  80. ; Strong ARM processor and PC Card (price with computer)
  81. (deffacts processor
  82.   (strongarm 100)
  83.   (pccard 275)
  84. )
  85.  
  86. ; cd rom drives
  87. ; price speed
  88. (deffacts cdroms
  89.   (cdrom 125 4)
  90.   (cdrom 205 6)
  91. )
  92.  
  93. ; interfaces
  94. (deffacts interfaces
  95.   (ethernet 74)
  96.   (midi 54)
  97.   (scsi 165)
  98. )
  99.  
  100. ; harddiscs
  101. ; price type size
  102. (deffacts harddiscs
  103.   (hd 345 scsi 2000)
  104.   (hd 145 ide 1200)
  105.   (hd 190 scsi 1000)
  106.   (hd 120 ide 850)
  107.   (hd 108 ide 540)
  108.   (hd 80 ide 300)
  109.   (hd 60 ide 210)
  110. ; if you need a bigger disc then you probably know what you want anyhow...
  111. )
  112.  
  113. ; other hardware
  114. (deffacts misc-hardware
  115.   (scanner 128)
  116.   (scanner_digitiser 188)
  117.   (speakers 34) )
  118.  
  119. ; modems
  120. ; price speed
  121. (deffacts modems
  122.   (modem 96 14.4)
  123.   (modem 153 28.8) )
  124.  
  125. ; printer price type
  126. (deffacts printers
  127.   (printer 138 bw)
  128.   (printer 149 colour)
  129.   (printer 10 refils) )
  130.  
  131. ; applications
  132. ; app type name price (requires)
  133. (deffacts software
  134.   (app dtp "Ovation" 163)
  135.   (app dtp "Style" 75)
  136.   (app music "Sibelius 7" 829)
  137.   (app music "Sibelius 6" 154)
  138.   (app accounts "Home accounts" 27)
  139.   (app accounts "Prophet business accounts" 143)
  140.   (app spreadsheet "Eureka" 91)
  141.   (app database "Datapower" 98)
  142.   (app comms "ArcFax" 28)
  143.   (app comms "ANT Suite II" 98)
  144.   (app design "HTMLEdit v2" 38)
  145.   (app design "Web designers toolkit" 56)
  146.   (app util "SparkFS" 20)
  147.   (app util "MacFS" 85)
  148.   (app util "MovieFS" 20)
  149.   (app prog "JFShared programming library" 0)
  150.   (app prog "Zap text editor" 0)
  151.   (app prog "PRMs" 105)
  152.   (app prog "PRMs supplement" 35)
  153.   (app prog "C development" 89)
  154.   (app design "Artworks" 98)
  155.   (app design "Photodesk 2" 228)
  156.   (app network "Access +" 25)
  157.   (app school-primary "10/10 disc sets" 40)
  158.   (app school-second "Sciences teach-yourself pack" 40)
  159. )
  160.  
  161. ; PC Software :-)
  162. (deffacts pc-software-yuck-yuck-yuck
  163.   (app encarta "Encarta" 112)
  164.   (app prog "Visual C++" 85)
  165. )
  166.  
  167. ; Questions
  168. ; question number "question" (assert if true) (assert if false
  169. (deffacts toplevel-questions
  170.   (question (is question-1)
  171.             (ask "Are you wanting to use the computer for the home ?")
  172.             (true home home-1)
  173.             (false work work-1)
  174.             (next question-2) )
  175.   (question (is question-2)
  176.             (ask "Do you wish to do design work on the computer ?")
  177.             (true design design-1)
  178.             (next question-3) )
  179.   (question (is question-3)
  180.             (ask "Will you be using the computer for programming ?")
  181.             (true programming program-1)
  182.             (next question-4) )
  183.   (question (is question-4)
  184.             (ask "Are you wanting to do publishing work ?")
  185.             (true publishing none)
  186.             (next question-5) )
  187.   (question (is question-5)
  188.             (ask "Lots of the larger software recently has been provided on CD ROM ranging from games to large publications. Do you think you would need a CD ROM ?")
  189.             (true need-cdrom none)
  190.             (next question-6) )
  191.   (question (is question-6)
  192.             (ask "Will you want to use the internet ?")
  193.             (true internet internet-1)
  194.             (next question-7) )
  195.   (question (is question-7)
  196.             (ask "Are you going to be doing music scoring ?")
  197.             (true music none) )
  198. )
  199.  
  200. (deffacts internet-questions
  201.   (question (is internet-1)
  202.             (ask "Will you be wanting to view 'foreign' files (Mac/Zip's) ?")
  203.             (true archivers none)
  204.             (next internet-2) )
  205.   (question (is internet-2)
  206.             (ask "Will you be wanting to view movie files on the net ?")
  207.             (true movies none) )
  208. )
  209.  
  210. ; work questions
  211. (deffacts work-questions
  212.   (question (is work-1)
  213.             (ask "Will you be using the computer for business acounts ?")
  214.             (true accounts none)
  215.             (next work-2) )
  216.   (question (is work-2)
  217.             (ask "Will you be wanting to use a database (keep records of people or stocks) ?")
  218.             (true database none)
  219.             (next work-3) )
  220.   (question (is work-3)
  221.             (ask "Will you be wanting to produce a published work ?")
  222.             (true dtp dtp-1)
  223.             (next work-4) )
  224.   (question (is work-4)
  225.             (ask "Are you wanting to send Faxes ?")
  226.             (true fax none)
  227.             (next work-5) )
  228.   (question (is work-5)
  229.             (ask "Will the computer want to be networked ?")
  230.             (true network none) )
  231. )
  232.  
  233. ; dtp style questions
  234. (deffacts dtp-questions
  235.   (question (is dtp-1)
  236.             (ask "Does the published work need to be colour ?")
  237.             (true printer-colour none)
  238.             (false printer-bw none)
  239.             (next scanner) )
  240. )
  241.  
  242. ; home
  243. (deffacts home-questions
  244.   (question (is home-1)
  245.             (ask "Will you be using the computer for home acounting ?")
  246.             (true accounts none)
  247.             (next home-2) )
  248.   (question (is home-2)
  249.             (ask "Will the computer be used for educational things ?")
  250.             (true school school-1) )
  251. )
  252.  
  253. ; education
  254. (deffacts education-questions
  255.   (question (is school-1)
  256.             (ask "Will it be used for primary school work ?")
  257.             (true school-primary none)
  258.             (next school-2) )
  259.   (question (is school-2)
  260.             (ask "Will it be used for KS 2 and 3 ?")
  261.             (true school-secondary secondary-1)
  262.             (next school-3) )
  263.   (question (is school-3)
  264.             (ask "Will it be used for sixth form work ?")
  265.             (true school-sixth sixth-1) )
  266.   (question (is secondary-1)
  267.             (ask "Will it be used for presentation work ?")
  268.             (true dtp dtp-1)
  269.             (next secondary-2) )
  270.   (question (is secondary-2)
  271.             (ask "Will it be used for information gathering (encyclodepia) ?")
  272.             (true encarta none) )
  273. )
  274.  
  275. ; design work
  276. (deffacts design-work-questions
  277.   (question (is design-1)
  278.             (ask "Will the design work be graphical (as opposed to web based) ?")
  279.             (true graphics design-2)
  280.             (false webeditstuff none) )
  281.   (question (is design-2)
  282.             (ask "Will you be wanting to print out your design work ?")
  283.             (true none dtp-1)
  284.             (next scanner) )
  285.   (question (is scanner)
  286.             (ask "Will you be wanting to scan pictures in ?")
  287.             (true scanner none) ) ; bit of a cheat this one, bit who cares
  288. )
  289.  
  290. ; programming work
  291. (deffacts programming-work-questions
  292.   (question (is program-1)
  293.             (ask "Will you be wanting to program in BASIC ?")
  294.             (true program-basic program-arc-1)
  295.             (next program-2) )
  296.   (question (is program-2)
  297.             (ask "Will you be wanting to program in C ?")
  298.             (true program-c none)
  299.             (next program-3) )
  300.   (question (is program-3)
  301.             (ask "Will you be wanting to program in Visual C++ ?")
  302.             (true program-vcc none) )
  303.   (question (is program-arc-1)
  304.             (ask "Would you like to do some desktop programming then ?")
  305.             (true program-jfs none) )
  306. )
  307.  
  308. ; the dependancy type thingies
  309. (deffacts what_needs_what
  310.   (requires (case) (require inc computer 0
  311.                             inc memory   4
  312.                             inc vram     0
  313.                             inc harddisc 0) )
  314.   (requires (case music) (require buy midi) )
  315.   (requires (case music work) (require buy app music "Sibelius 7"
  316.                                        inc memory 8
  317.                                        inc computer 1) )
  318.   (requires (case music home) (require buy app music "Sibelius 6"
  319.                                        inc memory 4
  320.                                        inc computer 1) )
  321.   (requires (case accounts home) (require buy app accounts "Home accounts") )
  322.   (requires (case database) (require buy app database "Datapower") )
  323.   (requires (case accounts work)
  324.                     (require buy app accounts "Prophet business accounts") )
  325.   (requires (case home) (require inc computer 0) )
  326.   (requires (case work) (require inc computer 1) )
  327.   (requires (case design webeditstuff) (require set internet) )
  328.   (requires (case design webeditstuff home)
  329.                           (require buy app design "HTMLEdit v2") )
  330.   (requires (case design webeditstuff work)
  331.                           (require buy app design "Web designers toolkit") )
  332.   (requires (case internet) (require set need-modem
  333.                                      buy app comms "ANT Suite II"
  334.                                      inc harddisc 256
  335.                                      inc computer 1) )
  336.   (requires (case fax) (require set need-modem
  337.                                 buy app comms "ArcFax"
  338.                                 inc harddisc 128) )
  339.   (requires (case printer-bw) (require buy printer bw) )
  340.   (requires (case printer-colour) (require buy printer colour) )
  341.   (requires (case scanner) (require buy scanner) )
  342.   (requires (case need-modem work) (require buy modem 28.8) )
  343.   (requires (case need-modem home) (require buy modem 14.4) )
  344.   (requires (case archives) (require buy app util "SparkFS"
  345.                                      buy app util "MacFS") )
  346.   (requires (case movies) (require buy app util "MovieFS"
  347.                                    buy speakers) )
  348.   (requires (case programming) (require buy app prog "Zap text editor"
  349.                                         inc harddisc 80) )
  350.   (requires (case program-c) (require buy app prog "C development"
  351.                                       set need-prms
  352.                                       inc memory 4
  353.                                       inc harddisc 64) )
  354.   (requires (case program-jfs) (require buy app prog "JFShared programming library"
  355.                                         set need-prms) )
  356.   (requires (case dtp work) (require buy app dtp "Ovation") )
  357.   (requires (case dtp home) (require buy app dtp "Style") )
  358.   (requires (case program-vcc) (require buy app prog "Visual C++"
  359.                                         set need-pccard
  360.                                         set need-cdrom
  361.                                         inc harddisc 512) )
  362.   (requires (case need-prms) (require buy app prog "PRMs"
  363.                                       buy app prog "PRMs supplement") )
  364.   (requires (case design work) (require buy app design "Photodesk 2"
  365.                                         set strongarm
  366.                                         inc memory 8
  367.                                         inc vram 2
  368.                                         inc harddisc 256
  369.                                         set need-cdrom) )
  370.   (requires (case design home) (require buy app design "Artworks"
  371.                                         inc memory 4
  372.                                         inc vram 1) )
  373.   (requires (case encarta) (require buy app encarta "Encarta"
  374.                                     set need-pccard
  375.                                     inc harddisc 512
  376.                                     set need-cdrom) )
  377.   (requires (case strongarm) (require buy strongarm
  378.                                       inc computer 1) ); can't fit SA to a7k
  379.   (requires (case need-pccard) (require buy pccard
  380.                                         inc memory 4
  381.                                         inc computer 1) )
  382.   (requires (case need-cdrom work) (require buy cdrom 6) )
  383.   (requires (case need-cdrom home) (require buy cdrom 4) )
  384.   (requires (case network) (require buy ethernet
  385.                                     buy app network "Access +") )
  386.  
  387. )
  388.  
  389. ;**************************************************************************
  390. ;***      The Rules - Round 1 : How much have they got spend?           ***
  391. ;**************************************************************************
  392.  
  393. ; start by introducing the program
  394. (defrule initial_rule
  395.      ?fact <- (initial-fact)
  396.   =>
  397.      (printout t "                   ======================" crlf
  398.                  "                   Computer picker thingy" crlf
  399.                  "                   ======================" crlf crlf
  400.                  "Please answer the following questions to find the "
  401.                  "computer you could have..." crlf crlf)
  402.      (retract ?fact)
  403.      (assert (stage 1) )
  404.      (assert (next question-1) )
  405. )
  406.  
  407. ; find out how much they want to spend
  408. (defrule how_much_have_they
  409.      ?fact <- (stage 1)
  410.      (vat ?vat)
  411.   =>
  412.      (printout t "How much money do you have to spend ? ")
  413.      (assert (money (/ (read) ?vat) ) )  ; so that we don't have to fiddle
  414.      (retract ?fact)                     ;            too much later on...
  415.      (assert (stage 2))
  416. )
  417.  
  418. ;**************************************************************************
  419. ;***            The Rules - Round 2 : What do they want ?               ***
  420. ;**************************************************************************
  421.  
  422. ; ask the main questions
  423. (defrule scan_questions
  424.                  (stage 2)
  425.      ?f-next <-  (next ?id)
  426.      ?f-q <-     (question (is ?id)
  427.                            (ask ?ask)
  428.                            (true $?true)
  429.                            (false $?false)
  430.                            (next ?next) )
  431.   => (retract ?f-next)
  432.      (retract ?f-q)
  433.      (assert (q-next ?next) )
  434.      (assert (q-asknow ?ask) )
  435.      (assert (q-iftrue $?true) )
  436.      (assert (q-iffalse $?false) )
  437.      (assert (askquestion) )
  438. ;      (printout t "Asking " ?id " : " ?ask crlf)
  439. )
  440.  
  441. ; asks the question specified in q-asknow
  442. (defrule ask_questions
  443.      ?f-ask <-  (askquestion)
  444.                 (q-asknow ?ask)
  445.   => (retract ?f-ask)
  446.      (printout t ?ask)
  447.      (assert (q-answer (read)) )
  448. )
  449.  
  450. ; two little aliases, to stop my hands aching :-)
  451. (defrule alias_reply_y
  452.      ?f-reply <- (q-answer y)
  453.   =>
  454.      (retract ?f-reply)
  455.      (assert (q-answer yes) )
  456. )
  457. (defrule alias_reply_n
  458.      ?f-reply <- (q-answer n)
  459.   =>
  460.      (retract ?f-reply)
  461.      (assert (q-answer no) )
  462. )
  463.  
  464. ; checks that the reply was valid
  465. (defrule check_reply_yes
  466.      ?f-reply <- (q-answer yes)
  467.      ?f-next <-  (q-next ?next)
  468.      ?f-true <-  (q-iftrue ?value ?question)
  469.      ?f-false <- (q-iffalse $?)
  470.      ?f-q <-     (q-asknow ?)
  471.   =>
  472. ;      (printout t "Answer Yes..." crlf)
  473.      (assert (toask ?question) )
  474.      (assert (set ?value) )
  475.      (assert (next ?next) )
  476.      (retract ?f-reply)
  477.      (retract ?f-next)
  478.      (retract ?f-false)
  479.      (retract ?f-true)
  480.      (retract ?f-q)
  481. )
  482.  
  483. ; checks that the reply was valid
  484. (defrule check_reply_no
  485.      ?f-reply <- (q-answer no)
  486.      ?f-next <-  (q-next ?next)
  487.      ?f-true <-  (q-iftrue $?)
  488.      ?f-false <- (q-iffalse ?value ?question)
  489.      ?f-q <-     (q-asknow ?)
  490.   =>
  491. ;      (printout t "Answer No..." crlf)
  492.      (assert (toask ?question) )
  493.      (assert (set ?value) )
  494.      (assert (next ?next) )
  495.      (retract ?f-reply)
  496.      (retract ?f-next)
  497.      (retract ?f-false)
  498.      (retract ?f-true)
  499.      (retract ?f-q)
  500. )
  501.  
  502. ; catch any other reply
  503. (defrule check_reply_unknown
  504.      ?f-reply <- (q-answer ?invalid)
  505.   =>
  506.      (printout t "I'm a bear of very little brain and I don't understand "
  507.                  ?invalid "." crlf "Please can you answer 'yes' or 'no'..."
  508.                  crlf)
  509.      (assert (askquestion) )
  510.      (retract ?f-reply)
  511. )
  512.  
  513. ; Round 2b - Ask them questions based on their answers
  514. ; now to assert any questions which are required due to earlier questions
  515. ; (ie the 'toask' sections)
  516. ; this will cause the additional questions to always be asked after
  517. ; the 'main' questions
  518. (defrule additional_questions
  519.      ?f-next <- (toask ?next)
  520.   =>
  521. ;      (printout t "Trying to ask " ?next crlf)
  522.      (assert (next ?next) )
  523.      (retract ?f-next)
  524. )
  525.  
  526.  
  527. ;**************************************************************************
  528. ;***            The Rules - Round 3 : What do they need ?               ***
  529. ;**************************************************************************
  530.  
  531. ; if we get to this point we know we've passed the stage at which questions
  532. ; can be asked so we have to move on to stage 3 - what do we actually need ?
  533. (defrule move_to_stage_3
  534.      ?f-stage <- (stage 2)
  535.   =>
  536.      (printout t crlf "Please wait..." crlf)
  537.      (printout t "  Calculating requirements..." crlf)
  538. ;      (printout t "Moving to stage 3, what do we need ?" crlf)
  539.      (retract ?f-stage)
  540.      (assert (stage 3) )
  541. )
  542.  
  543. ; we've completely fulfilled a requirement - so we need to do it's require
  544. ; section
  545. (defrule dependancies_statisified
  546.      (stage 3)
  547.      ?f-item <- (requires (case)
  548.                           (require $?sets) )
  549.   =>
  550. ;      (printout t "Requirement fulfilled, firing " $?sets crlf)
  551.      (assert (do $?sets))
  552.      (retract ?f-item)
  553. )
  554.  
  555. ; we've fulfilled the first of a set of requirements - remove it from
  556. ; the list so we can check the other ones
  557. (defrule dependancies_partial
  558.      (stage 3)
  559.      ?f-item <- (requires (case ?first $?also)
  560.                           (require $?sets) )
  561.      (set ?first)
  562.   =>
  563. ;      (printout t "Shrinking " ?first " " $?also " for " $?sets crlf)
  564.      (modify ?f-item (case $?also) )
  565. )
  566.  
  567. ; obey the 'do' clause of the requirements (multiple stages)
  568.  
  569. ; buy the thing
  570. (defrule obey_do_buy_app
  571.      ?f-match <- (do buy app ?section ?product $?rest)
  572.      (app ?section ?product ?price)
  573.   =>
  574.      (retract ?f-match)
  575.      (assert (do $?rest) )
  576. ;      (printout t "Trying to buy " ?product crlf)
  577.      (assert (please-buy ?price ?product app ?section ?product ?price) )
  578. )
  579.  
  580. ; buy a pccard
  581. (defrule obey_do_buy_pccard
  582.      ?f-match <- (do buy pccard $?rest)
  583.      (pccard ?price)
  584.   =>
  585.      (retract ?f-match)
  586.      (assert (do $?rest) )
  587. ;      (printout t "Trying to buy PC Card" crlf)
  588.      (assert (please-buy ?price "PC Card" pccard ?price) )
  589. )
  590.  
  591. ; buy a Modem
  592. (defrule obey_do_buy_modem
  593.      ?f-match <- (do buy modem ?speed $?rest)
  594.      (modem ?price ?speed)
  595.   =>
  596.      (retract ?f-match)
  597.      (assert (do $?rest) )
  598. ;      (printout t "Trying to buy Modem (" ?speed ")" crlf)
  599.      (assert (please-buy ?price (str-cat "Modem (" ?speed " kbaud)")
  600.                                  modem ?price ?speed) )
  601. )
  602.  
  603. ; buy a CDRom drive
  604. (defrule obey_do_buy_cdrom
  605.      ?f-match <- (do buy cdrom ?speed $?rest)
  606.      (cdrom ?price ?speed)
  607.   =>
  608.      (retract ?f-match)
  609.      (assert (do $?rest) )
  610. ;      (printout t "Trying to buy CD ROM (x" ?speed ")" crlf)
  611.      (assert (please-buy ?price (str-cat "CD ROM (x" ?speed ")")
  612.                                  cdrom ?price ?speed) )
  613. )
  614.  
  615. ; buy a strongarm
  616. (defrule obey_do_buy_strongarm
  617.      ?f-match <- (do buy strongarm $?rest)
  618.      (strongarm ?price)
  619.   =>
  620.      (retract ?f-match)
  621.      (assert (do $?rest) )
  622. ;      (printout t "Trying to buy StrongARM processor" crlf)
  623.      (assert (please-buy ?price StrongARM strongarm ?price) )
  624. )
  625.  
  626. ; buy a speakers
  627. (defrule obey_do_buy_speakers
  628.      ?f-match <- (do buy speakers $?rest)
  629.      (speakers ?price)
  630.   =>
  631.      (retract ?f-match)
  632.      (assert (do $?rest) )
  633. ;      (printout t "Trying to buy external speakers" crlf)
  634.      (assert (please-buy ?price "External speakers" speakers ?price) )
  635. )
  636.  
  637. ; buy a MIDI interface
  638. (defrule obey_do_buy_midi
  639.      ?f-match <- (do buy midi $?rest)
  640.      (midi ?price)
  641.   =>
  642.      (retract ?f-match)
  643.      (assert (do $?rest) )
  644. ;      (printout t "Trying to buy MIDI interface" crlf)
  645.      (assert (please-buy ?price "MIDI interface" midi ?price) )
  646. )
  647.  
  648. ; buy a scanner
  649. (defrule obey_do_buy_scanner
  650.      ?f-match <- (do buy scanner $?rest)
  651.      (scanner ?price)
  652.   =>
  653.      (retract ?f-match)
  654.      (assert (do $?rest) )
  655. ;      (printout t "Trying to buy Scanner" crlf)
  656.      (assert (please-buy ?price Scanner scanner ?price) )
  657. )
  658.  
  659. ; buy a printer
  660. (defrule obey_do_buy_printer
  661.      ?f-match <- (do buy printer ?type $?rest)
  662.      (printer ?price ?type)
  663.   =>
  664.      (retract ?f-match)
  665.      (assert (do $?rest) )
  666. ;      (printout t "Trying to buy Printer (" ?type ")" crlf)
  667.      (assert (please-buy ?price (str-cat "Printer ("?type")")
  668.                          printer ?price ?type) )
  669. )
  670.  
  671. ; increment a variable (existing)
  672. (defrule obey_do_inc_var_exists
  673.      ?f-match <- (do inc ?var ?by $?rest)
  674.      ?f-val <-   (val ?var ?value)
  675.   =>
  676.      (retract ?f-match)
  677.      (assert (do $?rest) )
  678.      (retract ?f-val)
  679.      (assert (val ?var (+ ?value ?by)) )
  680. )
  681.  
  682. ; increment a variable (non-existant)
  683. (defrule obey_do_inc_var_notexists
  684.      ?f-match <- (do inc ?var ?value $?rest)
  685.   =>
  686.      (retract ?f-match)
  687.      (assert (do $?rest) )
  688.      (assert (val ?var ?value))
  689. )
  690.  
  691. ; we've aleady got the variable set !
  692. (defrule obey_do_set_already_set
  693.      ?f-match <- (do set ?var $?rest)
  694.      (set ?var)
  695.   =>
  696.      (retract ?f-match)
  697.      (assert (do $?rest) )
  698. ;      (printout t "Set ignored (already done) " ?var crlf)
  699. )
  700.  
  701. ; we've aleady got the variable set !
  702. (defrule obey_do_set
  703.      ?f-match <- (do set ?var $?rest)
  704.   =>
  705.      (retract ?f-match)
  706.      (assert (do $?rest) )
  707.      (assert (set ?var))
  708. ;      (printout t "Set " ?var crlf)
  709. )
  710.  
  711. ; last item in a list has been obeyed
  712. (defrule obey_do_item_done
  713.      ?f-match <- (do)
  714.   =>
  715.      (retract ?f-match)
  716. )
  717.  
  718. ;**************************************************************************
  719. ;***      The Rules - Round 4 : What computer do they need ?            ***
  720. ;**************************************************************************
  721.  
  722. (defrule move_to_stage_4
  723.      ?f-stage <- (stage 3)
  724.   =>
  725.      (printout t "  Picking a computer..." crlf)
  726. ;      (printout t "Move to stage 4, buy things" crlf)
  727.      (retract ?f-stage)
  728.      (assert (stage 4) )
  729. ;      (facts)
  730. ;      (agenda)
  731. )
  732.  
  733. ; you can't have computers >1
  734. (defrule check_silly_computer_numbers
  735.      (stage 4)
  736.      ?f-comp <- (val computer ?num)
  737.      (test (< 1 ?num))
  738.   =>
  739.      (retract ?f-comp)
  740.      (assert (val computer 1))
  741. ;      (printout t "Downgrading to a sensible computer number" crlf)
  742. )
  743.  
  744. ; you can't have vram >2
  745. (defrule check_silly_vram
  746.      (stage 4)
  747.      ?f-vram <- (val vram ?num)
  748.      (test (< 2 ?num))
  749.   =>
  750.      (retract ?f-vram)
  751.      (assert (val vram 2))
  752. ;      (printout t "Downgrading to a sensible vram from " ?num crlf)
  753. )
  754.  
  755. ; ignore small HD's if we've already got one
  756. (defrule ignore_small_hd_sizes
  757.      (stage 4)
  758.      ?f-hd <-   (val harddisc ?need-hd)
  759.      (comp harddisc ?size)
  760.      (test (> ?size 0) )
  761.      (test (< ?need-hd 210) )
  762.   =>
  763.      (retract ?f-hd)
  764. ;      (printout t "Ignoring hard disc (" ?need-hd "Mb)" crlf)
  765. )
  766.  
  767. ; Buy some HD space if we need it
  768. (defrule buy_more_hd
  769.      (stage 4)
  770.      ?f-hd <-   (val harddisc ?need-hd)
  771.      (hd ?price ?type ?size)
  772.      ?f-comp <- (comp harddisc ?oldsize)
  773.      (test (<= ?size ?need-hd) )
  774.   =>
  775.      (retract ?f-hd)   (assert (val harddisc (- ?need-hd ?size)) )
  776.      (retract ?f-comp) (assert (comp harddisc (+ ?oldsize ?size)) )
  777.      (assert (please-buy ?price (str-cat ?size "Mb extra HD")
  778.                          hd ?price ?type ?size) )
  779. ;      (printout t "Buying some more HD space (" ?size "Mb)" crlf)
  780. )
  781.  
  782. ; Buy the lowest of the low hd's (cheating really)
  783. (defrule buy_diddly_hd
  784.      (stage 4)
  785.      ?f-hd <-   (val harddisc ?need-hd)
  786.      ?f-comp <- (comp harddisc 0)
  787.      (hd ?price ?type 210)
  788.      (test (< ?need-hd 210) )
  789.   =>
  790.      (retract ?f-hd)   (assert (val harddisc (- ?need-hd 210)) )
  791.      (retract ?f-comp) (assert (comp harddisc 210) )
  792.      (assert (please-buy ?price "210 Mb extra HD"
  793.                          hd ?price ?type 210) )
  794. ;      (printout t "Buying a small HD (210Mb)" crlf)
  795. )
  796.  
  797.  
  798. ; if we need a rpc, get one (from the list)
  799. (defrule we_need_a_rpc
  800.      (stage 4)
  801.      ?f-comp <- (val computer 1)
  802.      ?f-vram <- (val vram ?vram)
  803.      ?f-mem <-  (val memory ?need-mem)
  804.      (computer ?price rpc700 ?memory ?vram ?monitor ?hd)
  805.      (test (>= ?memory ?need-mem))
  806.      ?f-hd <-   (val harddisc ?need-hd)
  807.   =>
  808.      (retract ?f-mem) (assert (val memory   (- ?need-mem ?memory) ) )
  809.      (retract ?f-hd)  (assert (val harddisc (- ?need-hd  ?hd) ) )
  810.      (assert (please-buy ?price (str-cat "RPC700 " ?memory "Mb, " ?hd "HD, "
  811.                                  ?vram "VRAM")
  812.                          computer ?price rcp700 ?memory ?vram ?monitor ?hd) )
  813.      (assert (comp memory ?memory) )
  814.      (assert (comp harddisc ?hd) )
  815.      (assert (comp vram ?vram) )
  816.      (retract ?f-comp)
  817.      (retract ?f-vram)
  818.      (assert (gotcomputer) )
  819. ;      (printout t "Bought that gorgeous RPC" crlf)
  820. )
  821.  
  822. (defrule we_need_a_a7000
  823.      (stage 4)
  824.      ?f-comp <- (val computer 0)
  825.      (computer ?price a7000 ?memory ?vram ?monitor ?hd)
  826.      ?f-vram <- (val vram ?vram)
  827.      ?f-mem <- (val memory ?need-mem)
  828.      ?f-hd <- (val harddisc ?need-hd)
  829.      (test (>= ?memory ?need-mem))
  830.   =>
  831.      (retract ?f-mem) (assert (val memory   (- ?need-mem ?memory) ) )
  832.      (retract ?f-hd)  (assert (val harddisc (- ?need-hd  ?hd) ) )
  833.      (assert (please-buy ?price (str-cat "A7000 " ?memory "Mb, " ?hd "HD, "
  834.                                  ?vram "VRAM")
  835.                          computer ?price a7000 ?memory ?vram ?monitor ?hd) )
  836.      (assert (comp memory ?memory) )
  837.      (assert (comp harddisc ?hd) )
  838.      (assert (comp vram ?vram) )
  839.      (retract ?f-comp)
  840.      (retract ?f-vram)
  841. ;      (printout t "Bought that nice a7000" crlf)
  842.      (assert (gotcomputer) )
  843. )
  844.  
  845. ; buy some more memory
  846. (defrule we_need_more_memory
  847.      (stage 4)
  848.      ?f-need <- (val memory ?need-mem)
  849.      ?f-buy <-  (memory ?price ?amount)
  850. ;      (test (<= ?amount ?need-mem))
  851.   =>
  852.      (retract ?f-need)
  853.      (assert (val memory (- ?need-mem ?amount)) )
  854.      (assert (please-buy ?price (str-cat ?amount "Mb extra memory")) )
  855. )
  856.  
  857. ;**************************************************************************
  858. ;***            The Rules - Round 5 : Can we buy it ?                   ***
  859. ;**************************************************************************
  860.  
  861. ; The please-buy <price> <description> <data...> are converted to
  862. ; got <data> and bought <price> <description> whilst the money is reduced
  863. ; if it is not possible to buy the item then the item
  864. ; broke <price> <description> is created instead of the
  865.  
  866. (defrule move_to_stage_5
  867.      ?f-temp <- (gotcomputer)
  868.      ?f-stage <- (stage 4)
  869.   =>
  870.      (printout t "  Calculating prices..." crlf)
  871. ;      (printout t "Move to stage 5, buy things" crlf)
  872.      (retract ?f-stage) (assert (stage 5) )
  873.      (retract ?f-temp)
  874. )
  875.  
  876. ; this rule shouldn't be called because of the strategy employed, but
  877. ; it's better to have it just in case :-)
  878. (defrule please_buy_this_for_me_no_youve_got_one_already
  879.      (stage 5)
  880.      ?f-match <- (please-buy ?price ?product $?rest)
  881.      (got $?rest)
  882.   =>
  883. ;      (printout t "Ignoring " ?product " - already got it")
  884.      (retract ?f-match)
  885. )
  886.  
  887. ; /yeah/ we can buy it !
  888. (defrule please_buy_this_for_me_ok
  889.      (stage 5)
  890.      ?f-match <- (please-buy ?price ?product $?rest)
  891.      ?f-oldmoney <- (money ?money)
  892.      (test (> ?money ?price) )
  893.   =>
  894.      (retract ?f-oldmoney)
  895.      (assert (money (- ?money ?price) ) )
  896.      (assert (got $?rest) )
  897.      (assert (bought ?price ?product) )
  898.      (retract ?f-match)
  899. ;      (printout t "Bought " ?product crlf)
  900. )
  901.  
  902. ; can't buy 'cos not enough money, ok so the names a bit long, but I got
  903. ; carried away, and it looks good when the file loads :-)
  904. (defrule please_buy_this_for_me_no_way_laddy_youre_skint
  905.      (stage 5)
  906.      ?f-match <- (please-buy ?price ?product $?rest)
  907.      ?f-oldmoney <- (money ?money)
  908.      (test (< ?money ?price) )
  909.   =>
  910.      (assert (broke ?price ?product) )
  911.      (assert (got $?rest) ) ; we need to pretend that we have got this now
  912.      (retract ?f-match)
  913. ;      (printout t "Couldn't buy " ?product crlf)
  914. )
  915.  
  916. ;**************************************************************************
  917. ;***        The Rules - Round 6 : Tell them what they have got          ***
  918. ;**************************************************************************
  919.  
  920. ; display those things we've bought
  921. (defrule move_to_stage_6
  922.      ?f-stage <- (stage 5)
  923.   =>
  924.      (printout t crlf "Processing complete..." crlf crlf)
  925. ;      (printout t "Move to stage 6, display what we've bought" crlf)
  926.      (format t "%-60s %6s %9s%n" Item "ex VAT" "inc VAT")
  927.      (printout t "------------------------------------------------------------------------------" crlf)
  928.      (assert (stage 6))
  929.      (assert (display_basket))
  930.      (assert (exc-total 0))
  931.      (retract ?f-stage)
  932. )
  933.  
  934. (defrule display_basket_add_vat
  935.      (stage 6)
  936.      (display_basket)
  937.      ?f-bought <- (bought ?cost ?name)
  938.      (vat ?vat)
  939.      ?f-total <- (exc-total ?todate)
  940.   =>
  941.      (retract ?f-bought)
  942.      (format t "%-60s %6d %9d%n" ?name ?cost (* ?cost ?vat))
  943.      (retract ?f-total)
  944.      (assert (exc-total (+ ?todate ?cost)) )
  945. )
  946.  
  947. ; clear the display basket bit, 'cos it's done now
  948. (defrule clear_basket_flag
  949.      ?f-stage <- (stage 6)
  950.      ?f-basket <- (display_basket)
  951.      (exc-total ?exc)
  952.      (vat ?vat)
  953.   =>
  954.      (retract ?f-basket)
  955.      (printout t "                                                             -----------------" crlf)
  956.      (format t "%-60s %6d %9d%n" "" ?exc (* ?exc ?vat) )
  957.      (printout t "------------------------------------------------------------------------------" crlf crlf)
  958.      (retract ?f-stage)
  959.      (assert (stage 7))
  960. )
  961.  
  962. ;**************************************************************************
  963. ;***   The Rules - Round 7 : Explain that stuff about birds and bees    ***
  964. ;**************************************************************************
  965.  
  966. ; tell them they are bankrupt
  967. (defrule summarise_bankrupt
  968.      (stage 7)
  969.      (broke $?)
  970.   =>
  971.      (printout t "Very sorry, sir/madam, I could not match your requirements"
  972.                  " - probably you are aiming too high. You could always try"
  973.                  " with a bigger budget..." crlf crlf)
  974.      (printout t "I could not buy the following items :" crlf crlf)
  975.      (format t "%-60s %6s %9s%n" Item "ex VAT" "inc VAT")
  976.      (printout t "------------------------------------------------------------------------------" crlf crlf)
  977.      (assert (exc-total 0) )
  978.      (assert (bankrupt) )
  979. )
  980.  
  981. ; tell them what they couldn't buy
  982. (defrule summarise_bankrupt_statement
  983.      (bankrupt)
  984.      ?f-bought <- (broke ?cost ?name)
  985.      (vat ?vat)
  986.      ?f-total <- (exc-total ?todate)
  987.   =>
  988.      (retract ?f-bought)
  989.      (format t "%-60s %6d %9d%n" ?name ?cost (* ?cost ?vat))
  990.      (assert (exc-total (+ ?todate ?cost)) )
  991.      (retract ?f-total)
  992. )
  993.  
  994. ; display the footer of that shopping list
  995. (defrule summarise_bankrupt_total
  996.      (bankrupt)
  997.      ?f-stage <- (stage 7)
  998.      (exc-total ?exc)
  999.      (vat ?vat)
  1000.   =>
  1001.      (printout t "                                                             -----------------" crlf)
  1002.      (format t "%-60s %6d %9d%n" "" ?exc (* ?exc ?vat) )
  1003.      (printout t "------------------------------------------------------------------------------" crlf crlf)
  1004.      (assert (stage 8) )
  1005.      (retract ?f-stage)
  1006. )
  1007.  
  1008. ; if they did ok, tell them how much they have left
  1009. (defrule summarise_success
  1010.      (stage 7)
  1011.      (money ?left)
  1012.      (vat ?vat)
  1013.   =>
  1014.      (format t "That setup leaves you with %d" (* ?left ?vat) )
  1015.      (printout t " which you can obviously spend on other"
  1016.                  " interesting things..." crlf)
  1017.      (assert (summarised))
  1018. )
  1019.  
  1020. ; if they are using the net and have not much money left, tell them
  1021. (defrule summarise_success_internet_warning
  1022.      (stage 7)
  1023.      (set internet)
  1024.      (money ?left)
  1025.      (test (> 200 ?left) )
  1026.   =>
  1027.      (printout t crlf "As a warning, however, I'd like to point out that "
  1028.                  "you have less than 200 pounds left which needs to be "
  1029.                  "spent on an internet provider and local phone calls. "
  1030.                  "You will probably have to be very careful about how "
  1031.                  "much time you spend on the 'net if you are not to go "
  1032.                  "over budget." crlf)
  1033. )
  1034.  
  1035. ; if they have a bit of money left, warn them anyhow
  1036. (defrule summarise_success_internet_warning_the_sequel
  1037.      (stage 6)
  1038.      (set internet)
  1039.      (money ?left)
  1040.      (test (< 200 ?left) )
  1041.   =>
  1042.      (printout t crlf "I haven't, however, taken into account the cost of "
  1043.                  "/using/ the internet. The main reason for this is that "
  1044.                  "when using the 'net it is very likely that estimates "
  1045.                  "of the time (and cost) are far too low. Bare this in "
  1046.                  "mind." crlf)
  1047. )
  1048.  
  1049. ; ... and regardless, give them some idea of the cost
  1050. (defrule summarise_success_internet_warning_general
  1051.      (set internet)
  1052.      (stage 7)
  1053.   =>
  1054.      (printout t crlf "Generally internet providers charge about 10 per "
  1055.                  "month, with a initial setup fee of about 25. This is "
  1056.                  "then compounded by the actual calls themselves." crlf)
  1057. )
  1058.  
  1059. ; either way, it's time for rounding up...
  1060. (defrule summarise_success_exit
  1061.      ?f-stage <- (stage 7)
  1062.   =>
  1063.      (assert (stage 8))
  1064.      (retract ?f-stage)
  1065. )
  1066.  
  1067.  
  1068. ;**************************************************************************
  1069. ;***   The Rules - Round 8 : Say goodbye and wait for the next person   ***
  1070. ;**************************************************************************
  1071.  
  1072. ; you see, boomerang's fly away from you...
  1073. (defrule boomerang_throw
  1074.      (stage 8)
  1075.   =>
  1076.      (printout t "That's all folks" crlf crlf
  1077.                  "Press a key then return to continue...")
  1078.      (assert (restart (read)) )
  1079. )
  1080.  
  1081. ; ... and stop dead if they hit you (type quit to end) ...
  1082. (defrule boomerang_hit_head
  1083.      (stage 8)
  1084.      ?f-restart <- (restart quit)
  1085.   =>
  1086.      (retract ?f-restart)
  1087. )
  1088.  
  1089. ; ... or get caught to be thrown again (back to the beginning)
  1090. (defrule boomerang_caught
  1091.      (stage 8)
  1092.      (restart ?)
  1093.   =>
  1094.      (reset)
  1095. )
  1096.