2006-11-08

SEND + MORE = MONEY in CLIPS

Two days ago I spent some time thinking about the SEND + MORE = MONEY problem. It turns out that CLIPS is about 10x faster than the Python brute force program I wrote. It will be interesting to see how much slower or faster a pyRete version is. Here's the CLIPS program (saved in a file named sendmoremoney.clp):

(defrule send-more-money
(digit ?s&:(<> ?s 0))
(digit ?e&:(<> ?e ?s))
(digit ?n&:(<> ?n ?s ?e))
(digit ?d&:(<> ?d ?s ?e ?n))
(digit ?m&:(<> ?m ?s ?e ?n ?d 0))
(digit ?o&:(<> ?o ?s ?e ?n ?d ?m))
(digit ?r&:(<> ?r ?s ?e ?n ?d ?m ?o))
(digit ?y&:(<> ?y ?s ?e ?n ?d ?m ?o ?r))
(test (= (+ (+ (* ?s 1000) (* ?e 100) (* ?n 10) ?d)
(+ (* ?m 1000) (* ?o 100) (* ?r 10) ?e))
(+ (* ?m 10000) (* ?o 1000) (* ?n 100) (* ?e 10) ?y)))
=>
(printout t ?s ?e ?n ?d " + " ?m ?o ?r ?e " = " ?m ?o ?n ?e ?y crlf))

(deffacts digits
(digit 0) (digit 1) (digit 2) (digit 3) (digit 4)
(digit 5) (digit 6) (digit 7) (digit 8) (digit 9))
Running it takes only a few seconds. Well actually (run) takes almost no time at all but when you call (reset) and all of the facts are asserted, that takes a few seconds.
         CLIPS (V6.24 06/15/06)
CLIPS> (watch all)
CLIPS> (load sendmoremoney.clp)
Defining defrule: send-more-money +j+j+j+j+j+j+j+j
Defining deffacts: digits
TRUE
CLIPS> (reset)
<== Focus MAIN ==> Focus MAIN
==> instance [initial-object] of INITIAL-OBJECT
MSG >> create ED:1 (<Instance-initial-object>)
HND >> create primary in class USER
ED:1 (<Instance-initial-object>)
HND <<>)
MSG <<>)
MSG >> init ED:1 (<Instance-initial-object>)
HND >> init primary in class USER
ED:1 (<Instance-initial-object>)
HND <<>)
MSG <<>)==> f-0 (initial-fact)
==> f-1 (digit 0)
==> f-2 (digit 1)
==> f-3 (digit 2)
==> f-4 (digit 3)
==> f-5 (digit 4)
==> f-6 (digit 5)
==> f-7 (digit 6)
==> f-8 (digit 7)
==> f-9 (digit 8)
==> f-10 (digit 9)
==> Activation 0 send-more-money: f-10,f-6,f-7,f-8,f-2,f-1,f-9,f-3
CLIPS> (run)
FIRE 1 send-more-money: f-10,f-6,f-7,f-8,f-2,f-1,f-9,f-3
9567 + 1085 = 10652
<== Focus MAIN
1 rules fired
11 mean number of facts (11 maximum).
1 mean number of instances (1 maximum).
1 mean number of activations (1 maximum).
CLIPS>
The program might not be the most elegant or efficient but it does the job and the important thing is that this sort of chaining IS supported so I'm going to have to implement it in pyRete somehow...

Inga kommentarer: