Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

Experiments in Inference

 [1/2] from: tbrownell::l3technology::com at: 20-Feb-2003 0:26

Here's a challenge. Inference using Rebol. How to get from "Tweety is a canary." to "Tweety has feathers." Given the following. Tweety is a canary. Canary is a bird. Birds have feathers. Tweety has feathers. Where Tweety inherits the attributes of canaries. And Canaries inherit the attributes of birds. And Birds have feathers. Thus Tweety must have feathers also. If A is part of X and X is part of Y then A is part of Y. I considered the following... Bird: [has "feathers"] Canary: bird Tweety: Canary Tweety/has = "feathers" == True But this seems rather crude, and would run out of memory in a large inference model. Any thoughts? TBrownell

 [2/2] from: rgombert:essentiel at: 20-Feb-2003 15:14

During my first REBOL period, i built a small inference engine wich can do this sort of inference. I warn you that the code is very dirty, and the design of the engine is very smplistic and unevolutive... that was one of my firt play with REBOL ;-) The code is below, with two sets of same rules but in different orders. With the fist set, all inferences are made first round, but with the second two rounds are needed to produce all the deductibles facts. The rules provided are from the challenge :
> "Tweety is a canary." ==> become a fact > "Canary is a bird." ==> is rule 1 > "Birds have feathers." ==> is rule 2
plus one fact an two rules :
> "John is a hunter" ==> a fact > "Hunters hunts birds" ==> is rule 3 > "who is a bird is hunted by who is a hunter" ==> rule 4
Renaud GOMBERT -------------------------------- N SIRET : 418 620 159 N MdA : G316527 NAF/APE : 923A REBOL [ title: "TINY INFERENCE ENGINE" author: "Renaud GOMBERT" file: %infer.r info: { This small, dirty, and simple symbolic inference engine use rules to deduce new facts from those initialy given.} ] initialize: does [ rules: copy [] facts: copy [] ] add-rule: func [name cond act behavior][ append/only rules reduce [name cond act behavior] ] terminal: does [end: true print ">> END BY RULE REQUEST"] only: does [print " ONLY" break] init-engine: does [ do facts end: false cycle_limit: 3 nb_cycles: 0 ] ; try to apply one rule try_rule: function [rule][tmp Rvar Rprop Fvar Fprop xx tmp2 out props][ tmp: copy [] append/only tmp copy [] append/only tmp copy [] foreach [Rvar Rprop] rule/2 [ foreach [Fvar Fprop] facts [ if found? find Fprop Rprop [append/only tmp/:Rvar Fvar] ] ] ; build inferences tmp2: copy [] either empty? tmp/2 [ foreach item1 tmp/1 [ append/only tmp2 replace copy rule/3 1 item1 ] ][ foreach item2 tmp/2 [ foreach item1 tmp/1 [ xx: replace (replace copy rule/3 1 item1) 2 item2 append/only tmp2 reduce [first xx form next xx] ] ] ] ; add results to facts out: copy [] foreach item tmp2 [ props: first next find facts item/1 if not found? find props item/2 [append props item/2 append/only out item] ] out ] ; run one inference cycle cycle: has [tmp] [ print ["^/infering cycle" nb_cycles "::"] tmp: copy [] foreach rule rules [ if (not empty? tmp: try_rule rule) [ print [" use " rule/1 " : " tmp] do rule/4 ] ] nb_cycles: nb_cycles + 1 if nb_cycles >= cycle_limit [end: true] ] ; launch the inference engine run: does [ end: false nb_cycles: 0 while [not end][cycle] ] ;############### initialize add-rule "rule 1" [1 "is Canary"] [1 "is Bird"] [] add-rule "rule 2" [1 "is Bird"] [1 "has Feathers"] [] add-rule "rule 3" [1 "is Hunter"] [1 "hunts Birds"][] add-rule "rule 4" [1 "is Bird" 2 "hunts Birds"] [2 "hunts" 1][] facts: ["Tweety" ["is Canary"] "John" ["is Hunter"]] init-engine print ["BEFORE : " mold facts] run print ["^/AFTER ! " mold facts] print "^/==================^/" initialize add-rule "rule 4" [1 "is Bird" 2 "hunts Birds"] [2 "hunts" 1][] add-rule "rule 3" [1 "is Hunter"] [1 "hunts Birds"][] add-rule "rule 2" [1 "is Bird"] [1 "has Feathers"] [] add-rule "rule 1" [1 "is Canary"] [1 "is Bird"] [] facts: ["Tweety" ["is Canary"] "John" ["is Hunter"]] init-engine print ["BEFORE : " mold facts] run print ["^/AFTER ! " mold facts] halt