I have to calculate the General Predictive Accuracy with the help of some rules using TP, TN, FP, FN parameters in Clips.
My rule is x1 <=0.58 AND x6 <=0.61 x5 mcg<=0.61 --> Class = cp.I have written the code but when I try to run it I face the error message. There might be a mistake that I cannot find.
Can please anyone help me??? This is My Code:
(defrule rule1
(rw6 ?x6)
(rw5 ?x5)
(rw1 ?x1)
(test (<= ?x6 0.58))
(test (<= ?x5 0.61))
(test (<= ?x1 0.61))
?fact1 <- (TP1 ?TP1)
?fact2 <- (FP1 ?FP1)
?fact3 <- (TN2 ?TN2)
?fact4 <- (TN3 ?TN3)
?fact5 <- (TN4 ?TN4)
?fact6 <- (FN2 ?FN2)
?fact7 <- (FN3 ?FN3)
?fact8 <- (FN4 ?FN4)
?fact9 <- (K1 ?K1)
?fact10 <- (K2 ?K2)
?fact11 <- (K3 ?K3)
?fact12 <- (K4 ?K4)
?fact13 <- (row (rw1 ?x1)(rw2 ?x2)(rw3 ?x3)(rw4 ?x4)(rw5 ?x5)(rw6 ?x6)(rw7 ?x7)(class ?c))
=>
(if (= ?c cp) then
(retract ?fact1 ?fact3 ?fact4 ?fact5 ?fact9)
(assert (TP1 (+ ?TP1 1))(TN2 (+ ?TN2 1))(TN3 (+ ?TN3 1))(TN4 (+ ?TN4 1))(K1 (+ ?K1 1))))
else (if (= ?c im) then
(retract ?fact2 ?fact4 ?fact5 ?fact6 ?fact10)
(assert (FP1 (+ ?FP1 1))(TN3 (+ ?TN3 1))(TN4 (+ ?TN4 1))(FN2 (+ ?FN2 1))(K2 (+ ?K2 1))))
else (if (= ?c pp) then
(retract ?fact2 ?fact3 ?fact5 ?fact7 ?fact11)
(assert (FP1 (+ ?FP1 1))(TN2 (+ ?TN2 1))(TN4 (+ ?TN4 1))(FN3 (+ ?FN3 1))(K3 (+ ?K3 1))))
else (if (= ?c om) then
(retract ?fact2 ?fact3 ?fact4 ?fact8 ?fact12)
(assert (FP1 (+ ?FP1 1))(TN2 (+ ?TN2 1))(TN3 (+ ?TN3 1))(FN4 (+ ?FN4 1))(K4 (+ ?K4 1))))
(retract ?fact13))
(defrule rule2
(K1 ?K1)
(K2 ?K2)
(K3 ?K3)
(K4 ?K4)
(TP1 ?TP1)
(FP1 ?FP1)
(FN1 ?FN1)
(TP2 ?TP2)
(FP2 ?FP2)
(FN2 ?FN2)
(TP3 ?TP3)
(FP3 ?FP3)
(FN3 ?FN3)
(TP4 ?TP4)
(FP4 ?FP4)
(FN4 ?FN4)
?fact1 <- (REC1 0)
?fact2 <- (REC2 0)
?fact3 <- (REC3 0)
?fact4 <- (REC4 0)
?fact5 <- (PRE1 0)
?fact6 <- (PRE2 0)
?fact7 <- (PRE3 0)
?fact8 <- (PRE4 0)
?fact9 <- (FMES1 0)
?fact10 <- (FMES2 0)
?fact11 <- (FMES3 0)
?fact12 <- (FMES4 0)
?fact13 <- (waREC 0)
?fact14 <- (waPRE 0)
?fact15 <- (waFMES 0)
?fact13 <- (ACC 0)
=>
(retract ?fact1 ?fact2 ?fact3 ?fact4 ?fact5 ?fact6 ?fact7 ?fact8 ?fact9 ?fact10 ?fact11 ?fact12 ?fact13)
(assert (ACC (bind ?ACC (/ (+ ?TP1 ?TP2 ?TP3 ?TP4)(+ ?TP1 ?TP2 ?TP3 ?TP4 ?FN1 ?FN2 ?FN3 ?FN4)))))
(assert (REC1 (bind ?REC1 (/ ?TP1 (+ ?TP1 ?FN1)))))
(assert (REC2 (bind ?REC2 (/ ?TP2 (+ ?TP2 ?FN2)))))
(assert (REC3 (bind ?REC3 (/ ?TP3 (+ ?TP3 ?FN3)))))
(assert (REC4 (bind ?REC4 (/ ?TP4 (+ ?TP4 ?FN4)))))
(assert (PRE1 (bind ?PRE1 (/ ?TP1 (+ ?TP1 ?FP1)))))
(assert (PRE2 (bind ?PRE2 (/ ?TP2 (+ ?TP2 ?FP2)))))
(assert (PRE3 (bind ?PRE3 (/ ?TP3 (+ ?TP3 ?FP3)))))
(assert (PRE4 (bind ?PRE4 (/ ?TP4 (+ ?TP4 ?FP4)))))
(assert (FMES1 (bind ?FMES1 (/ (* 2 (/ ?TP1 (+ ?TP1 ?FN1))(/ ?TP1 (+ ?TP1 ?FP1)))(+ (/ ?TP1 (+ ?TP1 ?FN1))(/ ?TP1 (+ ?TP1 ?FP1)))))))
(assert (FMES2 (bind ?FMES2 (/ (* 2 (/ ?TP2 (+ ?TP2 ?FN2))(/ ?TP2 (+ ?TP2 ?FP2)))(+ (/ ?TP2 (+ ?TP2 ?FN2))(/ ?TP2 (+ ?TP2 ?FP2)))))))
(assert (FMES3 (bind ?FMES3 (/ (* 2 (/ ?TP3 (+ ?TP3 ?FN3))(/ ?TP3 (+ ?TP3 ?FP3)))(+ (/ ?TP3 (+ ?TP3 ?FN3))(/ ?TP3 (+ ?TP3 ?FP3)))))))
(assert (FMES4 (bind ?FMES4 (/ (* 2 (/ ?TP4 (+ ?TP4 ?FN4))(/ ?TP4 (+ ?TP4 ?FP4)))(+ (/ ?TP4 (+ ?TP4 ?FN4))(/ ?TP4 (+ ?TP4 ?FP4)))))))
(assert (waREC (+ (*(/ ?K1 (+ ?K1 ?K2 ?K3 ?K4)) ?REC1 )(*(/ ?K2 (+ ?K1 ?K2 ?K3 ?K4)) ?REC2)(*(/ ?K3 (+ ?K1 ?K2 ?K3 ?K4)) ?REC3 )(*(/ ?K4 (+ ?K1 ?K2 ?K3 ?K4)) ?REC4))))
(assert (waPRE (+ (*(/ ?K1 (+ ?K1 ?K2 ?K3 ?K4)) ?PRE1)(*(/ ?K2 (+ ?K1 ?K2 ?K3 ?K4)) ?PRE2)(*(/ ?K3 (+ ?K1 ?K2 ?K3 ?K4)) ?PRE3)(*(/ ?K4 (+ ?K1 ?K2 ?K3 ?K4)) ?REC4))))
(assert (waFMES (+ (*(/ ?K1 (+ ?K1 ?K2 ?K3 ?K4)) ?FMES1)(*(/ ?K2 (+ ?K1 ?K2 ?K3 ?K4)) ?FMES2)(*(/ ?K3 (+ ?K1 ?K2 ?K3 ?K4)) ?FMES3)(*(/ ?K4 (+ ?K1 ?K2 ?K3 ?K4)) ?REC4)))))
There are three issues.
You don't have a deftemplate defined for the row fact.
You're using = to compare a variable to a symbol in rule1. Use eq instead if you're comparing non-numeric arguments
In rule2, the fact address ?fact13 is bound to two different patterns.
CLIPS>
(deftemplate row
(slot rw1)
(slot rw2)
(slot rw3)
(slot rw4)
(slot rw5)
(slot rw6)
(slot rw7)
(slot class))
CLIPS>
(defrule rule1
(rw6 ?x6)
(rw5 ?x5)
(rw1 ?x1)
(test (<= ?x6 0.58))
(test (<= ?x5 0.61))
(test (<= ?x1 0.61))
?fact1 <- (TP1 ?TP1)
?fact2 <- (FP1 ?FP1)
?fact3 <- (TN2 ?TN2)
?fact4 <- (TN3 ?TN3)
?fact5 <- (TN4 ?TN4)
?fact6 <- (FN2 ?FN2)
?fact7 <- (FN3 ?FN3)
?fact8 <- (FN4 ?FN4)
?fact9 <- (K1 ?K1)
?fact10 <- (K2 ?K2)
?fact11 <- (K3 ?K3)
?fact12 <- (K4 ?K4)
?fact13 <- (row (rw1 ?x1)(rw2 ?x2)(rw3 ?x3)(rw4 ?x4)(rw5 ?x5)(rw6 ?x6)(rw7 ?x7)(class ?c))
=>
(if (eq ?c cp) ; was =
then
(retract ?fact1 ?fact3 ?fact4 ?fact5 ?fact9)
(assert (TP1 (+ ?TP1 1))(TN2 (+ ?TN2 1))(TN3 (+ ?TN3 1))(TN4 (+ ?TN4 1))(K1 (+ ?K1 1))))
else
(if (eq ?c im)
then
(retract ?fact2 ?fact4 ?fact5 ?fact6 ?fact10)
(assert (FP1 (+ ?FP1 1))(TN3 (+ ?TN3 1))(TN4 (+ ?TN4 1))(FN2 (+ ?FN2 1))(K2 (+ ?K2 1))))
else
(if (eq ?c pp)
then
(retract ?fact2 ?fact3 ?fact5 ?fact7 ?fact11)
(assert (FP1 (+ ?FP1 1))(TN2 (+ ?TN2 1))(TN4 (+ ?TN4 1))(FN3 (+ ?FN3 1))(K3 (+ ?K3 1))))
else (if (eq ?c om)
then
(retract ?fact2 ?fact3 ?fact4 ?fact8 ?fact12)
(assert (FP1 (+ ?FP1 1))(TN2 (+ ?TN2 1))(TN3 (+ ?TN3 1))(FN4 (+ ?FN4 1))(K4 (+ ?K4 1))))
(retract ?fact13))
CLIPS>
(defrule rule2
(K1 ?K1)
(K2 ?K2)
(K3 ?K3)
(K4 ?K4)
(TP1 ?TP1)
(FP1 ?FP1)
(FN1 ?FN1)
(TP2 ?TP2)
(FP2 ?FP2)
(FN2 ?FN2)
(TP3 ?TP3)
(FP3 ?FP3)
(FN3 ?FN3)
(TP4 ?TP4)
(FP4 ?FP4)
(FN4 ?FN4)
?fact1 <- (REC1 0)
?fact2 <- (REC2 0)
?fact3 <- (REC3 0)
?fact4 <- (REC4 0)
?fact5 <- (PRE1 0)
?fact6 <- (PRE2 0)
?fact7 <- (PRE3 0)
?fact8 <- (PRE4 0)
?fact9 <- (FMES1 0)
?fact10 <- (FMES2 0)
?fact11 <- (FMES3 0)
?fact12 <- (FMES4 0)
?fact13 <- (waREC 0)
?fact14 <- (waPRE 0)
?fact15 <- (waFMES 0)
?fact16 <- (ACC 0)
=>
(retract ?fact1 ?fact2 ?fact3 ?fact4 ?fact5 ?fact6 ?fact7 ?fact8 ?fact9 ?fact10 ?fact11 ?fact12 ?fact13)
(assert (ACC (bind ?ACC (/ (+ ?TP1 ?TP2 ?TP3 ?TP4)(+ ?TP1 ?TP2 ?TP3 ?TP4 ?FN1 ?FN2 ?FN3 ?FN4)))))
(assert (REC1 (bind ?REC1 (/ ?TP1 (+ ?TP1 ?FN1)))))
(assert (REC2 (bind ?REC2 (/ ?TP2 (+ ?TP2 ?FN2)))))
(assert (REC3 (bind ?REC3 (/ ?TP3 (+ ?TP3 ?FN3)))))
(assert (REC4 (bind ?REC4 (/ ?TP4 (+ ?TP4 ?FN4)))))
(assert (PRE1 (bind ?PRE1 (/ ?TP1 (+ ?TP1 ?FP1)))))
(assert (PRE2 (bind ?PRE2 (/ ?TP2 (+ ?TP2 ?FP2)))))
(assert (PRE3 (bind ?PRE3 (/ ?TP3 (+ ?TP3 ?FP3)))))
(assert (PRE4 (bind ?PRE4 (/ ?TP4 (+ ?TP4 ?FP4)))))
(assert (FMES1 (bind ?FMES1 (/ (* 2 (/ ?TP1 (+ ?TP1 ?FN1))(/ ?TP1 (+ ?TP1 ?FP1)))(+ (/ ?TP1 (+ ?TP1 ?FN1))(/ ?TP1 (+ ?TP1 ?FP1)))))))
(assert (FMES2 (bind ?FMES2 (/ (* 2 (/ ?TP2 (+ ?TP2 ?FN2))(/ ?TP2 (+ ?TP2 ?FP2)))(+ (/ ?TP2 (+ ?TP2 ?FN2))(/ ?TP2 (+ ?TP2 ?FP2)))))))
(assert (FMES3 (bind ?FMES3 (/ (* 2 (/ ?TP3 (+ ?TP3 ?FN3))(/ ?TP3 (+ ?TP3 ?FP3)))(+ (/ ?TP3 (+ ?TP3 ?FN3))(/ ?TP3 (+ ?TP3 ?FP3)))))))
(assert (FMES4 (bind ?FMES4 (/ (* 2 (/ ?TP4 (+ ?TP4 ?FN4))(/ ?TP4 (+ ?TP4 ?FP4)))(+ (/ ?TP4 (+ ?TP4 ?FN4))(/ ?TP4 (+ ?TP4 ?FP4)))))))
(assert (waREC (+ (*(/ ?K1 (+ ?K1 ?K2 ?K3 ?K4)) ?REC1 )(*(/ ?K2 (+ ?K1 ?K2 ?K3 ?K4)) ?REC2)(*(/ ?K3 (+ ?K1 ?K2 ?K3 ?K4)) ?REC3 )(*(/ ?K4 (+ ?K1 ?K2 ?K3 ?K4)) ?REC4))))
(assert (waPRE (+ (*(/ ?K1 (+ ?K1 ?K2 ?K3 ?K4)) ?PRE1)(*(/ ?K2 (+ ?K1 ?K2 ?K3 ?K4)) ?PRE2)(*(/ ?K3 (+ ?K1 ?K2 ?K3 ?K4)) ?PRE3)(*(/ ?K4 (+ ?K1 ?K2 ?K3 ?K4)) ?REC4))))
(assert (waFMES (+ (*(/ ?K1 (+ ?K1 ?K2 ?K3 ?K4)) ?FMES1)(*(/ ?K2 (+ ?K1 ?K2 ?K3 ?K4)) ?FMES2)(*(/ ?K3 (+ ?K1 ?K2 ?K3 ?K4)) ?FMES3)(*(/ ?K4 (+ ?K1 ?K2 ?K3 ?K4)) ?REC4)))))
CLIPS>
Related
Can someone explain me how can I import the WEKA created rules in CLIPS and evaluate its efficience in TRS and TES data?
The data I use
I have written 7 rules out of 20 from WEKA tree. I include also 3 instances from the glass datasheet
small test code
(deftemplate glass
(slot n(type FLOAT))
(slot m(type FLOAT))
(slot a(type FLOAT))
(slot b(type FLOAT))
(slot r(type FLOAT))
(slot s(type FLOAT))
(slot k(type FLOAT))
(slot c(type FLOAT)))
(deftemplate Type
(slot type))
(deffacts instances1
(glass (n 13.00)
(m 2.28)
(a 1.00)
(b 0.00)))
(deffacts instances2
(glass (n 13.70)
(m 1.80)
(a 1.40)
(b 0.00)))
(deffacts instances3
(glass (n 13.70)
(m 1.90)
(a 1.40)
(b 0.00)))
(defrule R1
(glass (b ?b))
(test (<= ?b 0.27))
(glass (m ?m))
(test (<= ?m 2.41))
(glass (n ?n))
(test (<= ?n 13.78))
(glass (a ?a))
(test (<= ?a 1.38))
=>
(assert (Type (type buildwindnonfloat1)))
(printout t "buildwindnonfloat1 detected" crlf))
(defrule R2
(glass (b ?b))
(test (<= ?b 0.27))
(glass (m ?m))
(test (<= ?m 2.41))
(glass (n ?n))
(test (<= ?n 13.78))
(glass (a ?a))
(test (> ?a 1.38))
(glass (m ?m))
(test (<= ?m 1.88))
=>
(assert (Type (type containers2)))
(printout t "containers2 detected" crlf))
(defrule R3
(glass (b ?b))
(test (<= ?b 0.27))
(glass (m ?m))
(test (<= ?m 2.41))
(glass (n ?n))
(test (<= ?n 13.78))
(glass (a ?a))
(test (> ?a 1.38))
(glass (m ?m))
(test (> ?m 1.88))
=>
(assert (Type (type buildwindnonfloat3)))
(printout t "buildwindnonfloat3 detected" crlf))
(defrule R4
(glass (b ?b))
(test (<= ?b 0.27))
(glass (m ?m))
(test (<= ?m 2.41))
(glass (n ?n))
(test (> ?n 13.78))
=>
(assert (Type (type tableware4)))
(printout t "tableware detected" crlf))
(defrule R5
(glass (b ?b))
(test (<= ?b 0.27))
(glass (m ?m))
(test (> ?m 2.41))
(glass (a ?a))
(test (<= ?a 1.4))
(glass (m ?m))
(test (<= ?m 3.34))
(glass (a ?a))
(test (<= ?a 1.25))
=>
(assert (Type (type buildwindnonfloat5)))
(printout t "buildwindnonfloat5 detected" crlf))
(defrule R6
(glass (b ?b))
(test (<= ?b 0.27))
(glass (m ?m))
(test (> ?m 2.41))
(glass (a ?a))
(test (<= ?a 1.4))
(glass (m ?m))
(test (<= ?m 3.34))
(glass (a ?a))
(test (> ?a 1.25))
=>
(assert (Type (type buildwindfloat6)))
(printout t "buildwindfloat6 detected" crlf))
(defrule R7
(glass (b ?b))
(test (<= ?b 0.27))
(glass (m ?m))
(test (> ?m 2.41))
(glass (a ?a))
(test (<= ?a 1.4))
(glass (m ?m))
(test (> ?m 3.34))
(glass (m ?m))
(test (<= ?m 3.82))
(glass (r ?r))
(test (<= ?r 1.51707))
(glass (r ?r))
(test (<= ?r 51596))
=>
(assert (Type (type buildwindfloat7)))
(printout t "buildwindfloat7 detected" crlf))
To convert your data, it's easiest to read the data from the file when your program is running and directly assert the facts. So if your data looks like the following with each entry on its own line
1.5159,13.24,3.34,1.47,73.1,0.39,8.22,0,0,'build wind non-float'
1.5167,13.24,3.57,1.38,72.7,0.56,8.44,0,0.1,'vehic wind float'
then your can read your data by reading each line as a single string, replacing the commas with spaces, and then splitting the string into multiple values. You can then have a separate rule map the values from your file to the appropriate slots in your deftemplate facts.
Store the expected result with each glass fact and then you can compare that value to the value that your rule is proposing.
CLIPS (6.31 6/12/19)
CLIPS>
(deftemplate glass
(slot n (type FLOAT))
(slot m (type FLOAT))
(slot a (type FLOAT))
(slot b (type FLOAT))
(slot r (type FLOAT))
(slot s (type FLOAT))
(slot k (type FLOAT))
(slot c (type FLOAT))
(slot f (type FLOAT))
(slot type))
CLIPS>
(deftemplate input
(multislot data))
CLIPS>
(deffunction str-rpl (?str ?find ?replace)
(if (eq ?find "")
then
(return ?str))
(bind ?rs "")
(bind ?fl (str-length ?find))
(bind ?i (str-index ?find ?str))
(while (neq ?i FALSE)
(bind ?rs (str-cat ?rs (sub-string 1 (- ?i 1) ?str) ?replace))
(bind ?str (sub-string (+ ?i ?fl) (str-length ?str) ?str))
(bind ?i (str-index ?find ?str)))
(bind ?rs (str-cat ?rs ?str))
?rs)
CLIPS>
(defrule get-data
=>
(printout t "Input File? ")
(bind ?file (readline))
(if (not (open ?file data))
then
(printout t "Unable to open file" crlf)
(return))
(bind ?line (readline data))
(while (neq ?line EOF)
(bind ?line (str-rpl ?line "," " "))
(bind ?line (str-rpl ?line "'" "\""))
(assert (input (data (explode$ ?line))))
(bind ?line (readline data)))
(close data))
CLIPS>
(defrule convert-data
?i <- (input (data ?r ?n ?m ?a ?s ?k ?c ?b ?f ?type))
=>
(retract ?i)
(assert (glass (r ?r) (n ?n) (m ?m) (a ?a) (s ?s) (k ?k) (c ?c) (b ?b) (f ?f) (type ?type))))
CLIPS>
(defrule R1
(glass (b ?b)
(m ?m)
(n ?n)
(a ?a)
(type ?type))
(test (<= ?b 0.27))
(test (<= ?m 2.41))
(test (<= ?n 13.78))
(test (<= ?a 1.38))
=>
(printout t "buildwindnonfloat1 detected type = " ?type crlf))
CLIPS>
(defrule R2
(glass (b ?b)
(m ?m)
(n ?n)
(a ?a)
(type ?type))
(test (<= ?b 0.27))
(test (<= ?m 2.41))
(test (<= ?n 13.78))
(test (> ?a 1.38))
(test (<= ?m 1.88))
=>
(printout t "containers2 detected type = " ?type crlf))
CLIPS>
(defrule R3
(glass (b ?b)
(m ?m)
(n ?n)
(a ?a)
(type ?type))
(test (<= ?b 0.27))
(test (<= ?m 2.41))
(test (<= ?n 13.78))
(test (> ?a 1.38))
(test (> ?m 1.88))
=>
(printout t "buildwindnonfloat3 detected type = " ?type crlf))
CLIPS>
(defrule R4
(glass (b ?b)
(m ?m)
(n ?n)
(type ?type))
(test (<= ?b 0.27))
(test (<= ?m 2.41))
(test (> ?n 13.78))
=>
(printout t "tableware detected type = " ?type crlf))
CLIPS>
(defrule R5
(glass (b ?b)
(m ?m)
(a ?a)
(type ?type))
(test (<= ?b 0.27))
(test (> ?m 2.41))
(test (<= ?a 1.4))
(test (<= ?m 3.34))
(test (<= ?a 1.25))
=>
(printout t "buildwindnonfloat5 detected type = " ?type crlf))
CLIPS>
(defrule R6
(glass (b ?b)
(m ?m)
(a ?a)
(type ?type))
(test (<= ?b 0.27))
(test (> ?m 2.41))
(test (<= ?a 1.4))
(test (<= ?m 3.34))
(test (> ?a 1.25))
=>
(printout t "buildwindfloat6 detected type = " ?type crlf))
CLIPS>
(defrule R7
(glass (b ?b)
(m ?m)
(a ?a)
(r ?r)
(type ?type))
(test (<= ?b 0.27))
(test (> ?m 2.41))
(test (<= ?a 1.4))
(test (> ?m 3.34))
(test (<= ?m 3.82))
(test (<= ?r 1.51707))
(test (<= ?r 51596))
=>
(printout t "buildwindfloat7 detected type = " ?type crlf))
CLIPS> (reset)
CLIPS> (run)
Input File? weka.txt
buildwindfloat7 detected type = vehic wind float
CLIPS>
I'm trying to build a simple expert system for recommending courses and want to implement certainty factor in my program, however I'm stuck looking for a simple integration method.
I've stumbled upon this example but can't seems to figure out how to make it fire.
; Allow facts that are duplicates:
(defrule start
(declare (salience 1000))
(initial-fact)
=>
(set-fact-duplication TRUE))
(defrule combine-certainities-both-positive
?fact1 <- (organism ?attribute ?value ?C1&:(>= ?C1 0))
?fact2 <- (organism ?attribute ?value ?C2&:(>= ?C2 0))
(test (neq ?fact1 ?fact2))
=>
(retract ?fact1 ?fact2)
(bind ?C3 (- (+ ?C1 ?C2) (* ?C1 ?C2)))
(assert (organism ?attribute ?value ?C3)))
(defrule combine-certainities-both-negative
?fact1 <- (organism ?attribute ?value ?C1&:(< ?C1 0))
?fact2 <- (organism ?attribute ?value ?C2&:(< ?C2 0))
(test (neq ?fact1 ?fact2))
=>
(retract ?fact1 ?fact2)
(bind ?C3 (+ (+ ?C1 ?C2) (* ?C1 ?C2)))
(assert (organism ?attribute ?value ?C3)))
(defrule combine-certainities-with-opposite-signs
?fact1 <- (organism ?attribute ?value ?C1)
?fact2 <- (organism ?attribute ?value ?C2)
(test (< (* ?C1 ?C2) 0))
(test (neq ?fact1 ?fact2))
=>
(retract ?fact1 ?fact2)
(bind ?C3 (/ (+ ?C1 ?C2) (- 1 (min (abs ?C1) (abs ?C2)))))
(assert (organism ?attribute ?value ?C3)))
I try to assert two new organism facts to kick start the first rule:
CLIPS> (assert (organism morpholgy1 rod1 0.25)
(organism morpholgy2 rod2 0.25))
==> f-4 (organism morpholgy1 rod1 0.25)
==> f-5 (organism morpholgy2 rod2 0.25)
<Fact-5>
CLIPS> (run)
<== Focus MAIN
0 rules fired Run time is 0.00300693511962891 seconds.
0.0 rules per second.
2 mean number of facts (2 maximum).
0 mean number of instances (0 maximum).
0 mean number of activations (0 maximum).
And use the matches but still don't get how to make it match here..
CLIPS> (matches combine-certainities-both-positive)
Matches for Pattern 1
f-4
f-5
Matches for Pattern 2
f-4
f-5
Partial matches for CEs 1 - 2
None
Activations
None
(4 0 0)
The attribute and the value have to match (morpholgy1 != morpholgy2 and rod1 != rod2). That's why fact duplication has to be enabled to allow multiple copies of the same attribute/value.
CLIPS> (set-fact-duplication TRUE)
FALSE
CLIPS>
(assert (organism morpholgy rod 0.25)
(organism morpholgy rod 0.25))
<Fact-2>
CLIPS> (watch facts)
CLIPS> (run)
<== f-2 (organism morpholgy rod 0.25)
<== f-1 (organism morpholgy rod 0.25)
==> f-3 (organism morpholgy rod 0.4375)
CLIPS>
How to make fact in multiple type? like in this code get the same rank fact together.
(P X Y) means X is Y's elder member
i had tried this:
(deffacts people
(P a b)
(P b c)
(P a d)
(P d e)
(P d f)
)
(defrule ranking
(P ?x ?y)
(P ?y ?z)
=>
(assert (R ?x $?y $?z))
)
i want to make a complete seniority in the family,
and get (R a bd cef), but i just get (R a b c) (R a d e) (R a d f)
can u help me?
It's a bit more complicated than what you've attempted, particularly if you want it to work properly for more than 3 generations and/or multiple family groups.
CLIPS>
(defmethod concat$ ((?m1 MULTIFIELD) (?m2 MULTIFIELD (>= (length$ ?m1) (length$ ?m2))))
(bind ?rv (create$))
(loop-for-count (?i 1 (length$ ?m2))
(bind ?rv (create$ ?rv (sym-cat (nth$ ?i ?m1) (nth$ ?i ?m2)))))
(create$ ?rv (mv-subseq (+ 1 (length$ ?m2)) (length$ ?m1) ?m1)))
CLIPS>
(defmethod concat$ ((?m1 MULTIFIELD) (?m2 MULTIFIELD (< (length$ ?m1) (length$ ?m2))))
(bind ?rv (create$))
(loop-for-count (?i 1 (length$ ?m1))
(bind ?rv (create$ ?rv (sym-cat (nth$ ?i ?m1) (nth$ ?i ?m2)))))
(create$ ?rv (mv-subseq (+ 1 (length$ ?m1)) (length$ ?m2) ?m2)))
CLIPS>
(deffacts people
(P a b) ; Family 1
(P b c)
(P a d)
(P d e)
(P d f)
(P g h) ; Family 2
(P h j)
(P h k)
(P k l)
(P k m)
(P k n)
(P j o)
(P j p)
(P j q)
(P q r)
(P q s))
CLIPS>
(defrule copy
(P ?x ?y)
=>
(assert (R ?x ?y)))
CLIPS>
(defrule extend
?f1 <- (R $?b ?x ?ym $?e1)
?f2 <- (R ?y $?z)
(test (str-index ?y ?ym))
=>
(retract ?f1 ?f2)
(assert (R ?b ?x ?ym (concat$ ?e1 ?z))))
CLIPS>
(defrule combine
?f1 <- (R ?x $?b ?y1 $?e1)
?f2 <- (R ?x $?b ?y2&~?y1 $?e2)
=>
(retract ?f1 ?f2)
(assert (R ?x ?b (sym-cat ?y1 ?y2) (concat$ ?e1 ?e2))))
CLIPS> (reset)
CLIPS> (run)
CLIPS> (facts)
f-0 (initial-fact)
f-1 (P a b)
f-2 (P b c)
f-3 (P a d)
f-4 (P d e)
f-5 (P d f)
f-6 (P g h)
f-7 (P h j)
f-8 (P h k)
f-9 (P k l)
f-10 (P k m)
f-11 (P k n)
f-12 (P j o)
f-13 (P j p)
f-14 (P j q)
f-15 (P q r)
f-16 (P q s)
f-37 (R g h jk opqlmn rs)
f-46 (R a bd cef)
For a total of 19 facts.
CLIPS>
Let's say that I have a rule like this:
(defrule get_next_N_poz
?id <- (get_next_poz $?)
(world (limit $?) (ball ?b1 ?b2) (men $? ?x ?y - $?) (id ?))
(and
(test (= ?x ?b1))
(test (= ?y (- ?b2 1))))
=>
(printout t "north ready position:" ?x ?y)
(modify ?id (get_next_poz 1)))
How do I add a new "and"?
Thank you.
It depends on what logic you're trying to implement. The existing and you have is redundant anyway, but if you wanted a second one, you'd just add it after the end of the last:
(and
(test (= ?x ?b1))
(test (= ?y (- ?b2 1))))
(and
(test (= ?x ?b2))
(test (= ?y (+ ?b1 1))))
If you wanted one or the other of these conditions you'd do this:
(or (and
(test (= ?x ?b1))
(test (= ?y (- ?b2 1))))
(and
(test (= ?x ?b2))
(test (= ?y (+ ?b1 1)))))
Rather than using and/or conditional elements, you could use the and/or boolean functions within a single test conditional element:
(test (or (and (= ?x ?b1)
(= ?y (- ?b2 1)))
(and (= ?x ?b2)
(= ?y (+ ?b1 1)))))
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Example input:
((a1 . b) (a1 . c)):
I have one list with two elements, those elements are lists or pairs with two elements. And i want to check if the first element of the first pair/list is equal to the first element of the second pair/list.
output: If so, i want to create a new list with two lists, the first is the list:
while (b < c) -> (a1 . b(even)) (a1 . b+2(even))...
The other list is the same, but with the odd's
How do I implement this in scheme:
INPUT:
((1 . 1) (1 . 7))
OUTPUT:
(((1 . 2) (1 . 4) (1 . 6)) ((1 . 3) (1 . 5) (1 . 7)))
I have one list with two elements. Each element is also a list with two elements, both integers >= 0 and < 8
I have to create this:
input ((a1 . b) (a1 . c))
output: (if (and (= a1 a2) (odd? b))
While < b c
(list (a1 . b+1) (a1 . b+3) (a1 . b+n)...))
(list (a2 . b) (a2 . b+2) (a2 . b+4)...)
I had done this, but i can't find where i'm failing, could you help me?....
;;; Verify if absissa0 = absissa1
(define (game-position input)
(if (= (car (car j)) (cdr (cdr j)))
(col1_col2 j)
(error "Not valid"))))
;;; verify if absissa0 is even
(define (col1_col2 gstart)
(if (even? (cdr (car jstart)))
(list (pos-start jstart))
(list (pos-start (list (cons (car (car jstart)) (- (cdr (car jstart)) 1)) (car (cdr jstart))))))
;;; Loop that creates positions of even's and odd's
(define (pos-start j2)
(while ( < (cdr (car j2)) (- (cdr (cdr j2)) 2))
((cons (car (car j2)) (+ (cdr (car j2)) 2)) (pos-start (list (cons (car (car j2)) (+ (cdr (car j2)) 2)) (car (cdr j2)))))
(odd_2 (list (cons (car (car j2)) (+ (cdr (car j2)) 1)) (car (cdr j2)))))
(define (odd_2 j3)
(while ( < (cdr (car j3)) (- (car (cdr j3)) 2))
((j3) (odd_2 (list (cons (car (car j3)) (+ (cdr (car j3)) 2)) (car (cdr j3)))
(value)))
; position l e a coluna c.
(define (do-pos l c)
(if (and (integer? l) (integer? c) (>= l 0) (>= c 0) (<= l 7) (<= c 7))
(cons l c)
(error "insert a valid number between 0 and 7")))
; returns l
(define (line-pos p)
(car p))
; returns c
(define (column-pos p)
(cdr p))
; Arg is position.
(define (pos? arg)
(and (pair? arg) (integer? (line-pos arg)) (integer? (column-pos arg)) (< (car arg) 8) (>= (car arg) 0) (< (cdr arg) 8) (>= (cdr arg) 0)))
; two positions are equal?
(define (pos=? p1 p2)
(and (= (line-pos p1)(line-pos p2))(= (column-pos p1)(column-pos p2))))
(define (oper* x y)
(* (- x y) (- x y)))
; Distance between p1 e p2.
(define (distance p1 p2)
(sqrt (+ (oper* (line-pos p1) (line-pos p2)) (oper* (column-pos p1) (column-pos p2)))))
; Same directions? if same line and same column
(define (same-direction? p1 p2)
(or (= (line-pos p1) (line-pos p2)) (= (column-pos p1) (column-pos p2))))
; check if to positions are adjacent
(define (adjacent? p1 p2)
(and (same-direccao? p1 p2) (= (distance p1 p2) 1)))
; from a position, returns all adjacents moves
(define (adjacent p) (cond ((and (= (line-pos p) 0) (= (column-pos p) 0)) (list (faz-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1))))
((and (= (line-pos p) 7) (= (column-pos p) 7)) (list (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (- (column-pos p) 1))))
((= (line-pos p) 0) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))
((= (column-pos p) 0) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1))))
((= (line-pos p) 7) (list (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))
((= (column-pos p) 7) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (- (column-pos p) 1))))
(else (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))))
; returns a move with p1 and p2
(define (do-game p1 p2)
(if (and (pos? p1) (pos? p2))
(list p1 p2)
(error "Insert two valid positions")))
; returns the beguining of j.
(define (b-do-game j)
(car j))
; returns the end of j.
(define (e-do-hame j)
(car (cdr j)))
; Arg is a do-game?.
(define (do-game? arg)
(and (list? arg) (pos? (b-do-game arg)) (pos? (e-do-game arg))))
; do game is null?.
(define (do-game-null? j)
(pos=? (b-do-game j) (e-do-game j)))
; list with two do-game (pc and pl)
(define (play-pos pc pl)
(if (and (list? pc) (list? pl))
(list pc pl)
(error "Insere two valid moves")))
; returns pc.
(define (cap-pieces pj)
(b-do-game pj))
; returns pj
(define (free_pieces pj)
(e-do-game pj))
(define (neven n)
(if (even? n)
n (+ n 1)))
; create sublists
(define (sublist a mn mx)
(cond ((<= mn mx) (cons (do-pos a mn) (sublist a (+ mn 2) mx)))
(else '())))
(define (sublist2 a mn mx)
(cond ((<= mx (- mn 2)) (cons (do-pos a (- mn 2)) (sublist2 a (- mn 2) mx)))
(else '())))
(define (sublist3 a mn mx)
(cond ((<= mn mx) (cons (do-pos mn a) (sublist3 a (+ mn 2) mx)))
(else '())))
(define (sublist4 a mn mx)
(cond ((<= mx (- mn 2)) (cons (do-pos (- mn 2) a) (sublist4 a (- mn 2) mx)))
(else '())))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Returns game-positions
(define (game-positions j)
(if (not (and (do-game? j) (same-direction? (b-do-game j) (e-do-game j)) (even? (distance (b-do-game j) (e-do-game j)))))
(list)
(if (= (line-pos (b-do-game j)) (line-pos (e-do-game j)))
(f_odd_even? j)
(f_odd_even2? j))))
; Check is starts with odd or even.
(define (f_odd_even? j) (if (even? (column-pos (b-do-game j)))
(b_even j)
(b_odd j)))
(define (f_odd_even2? j) (if (even? (line-pos (b-do-jogada j)))
(b-even1 j)
(b_odd1 j)))
; If starts with odd:
(define (b_odd j)
(if (< (column-pos (b-do-game j)) (column-pos (e-do-game j)))
(list (sublist (line-pos (b-do-game j))
(neven (column-pos (b-do-game j)))
(column-pos (e-do-game j)))
(sublist (line-pos (b-do-game j))
(+ 1 (neven (column-pos (b-do-game j))))
(column-pos (e-do-game j))))
(list (sublist2 (line-pos (b-do-game j))
(+ 1 (column-pos (b-do-game j)))
(column-pos (e-do-game j)))
(sublist2 (line-pos (b-do-game j))
(column-pos (b-do-game j))
(- 1 (column-pos (e-do-game j)))))))
(define (b_even j)
(if (< (column-pos (b-do-game j)) (column-pos (e-do-game j)))
(list (sublist (line-pos (b-do-game j))
(+ 2 (neven (column-pos (b-do-game j))))
(column-pos (e-do-game j)))
(sublist (line-pos (b-do-game j))
(+ 1 (neven (column-pos (b-do-game j))))
(column-pos (e-do-game j))))
(list (sublist2 (line-pos (b-do-game j))
(column-pos (b-do-game j))
(column-pos (e-do-game j)))
(sublist2 (line-pos (b-do-game j))
(+ 1 (column-pos (b-do-game j)))
(column-pos (e-do-game j))))))
(define (b_odd1 j)
(if (< (line-pos (b-do-game j)) (column-pos (e-do-game j)))
(list (sublist3 (column-pos (b-do-game j))
(neven (line-pos (b-do-game j)))
(line-pos (e-do-game j)))
(sublist3 (column-pos (b-do-game j))
(+ 1 (neven (line-pos (b-do-game j))))
(line-pos (e-do-game j))))
(list (sublist4 (column-pos (b-do-game j))
(+ 1 (line-pos (b-do-game j)))
(line-pos (e-do-game j)))
(sublist4 (column-pos (b-do-game j))
(line-pos (b-do-game j))
(- 1 (line-pos (e-do-game j)))))))
(define (b_even1 j)
(if (< (line-pos (b-do-game j)) (line-pos (e-do-game j)))
(list (sublist3 (column-pos (b-do-game j))
(+ 2 (neven (line-pos (b-do-game j))))
(line-pos (e-do-game j)))
(sublist3 (column-pos (b-do-game j))
(+ 1 (neven (line-pos (b-do-game j))))
(line-pos (e-do-game j))))
(list (sublist4 (column-pos (b-do-game j))
(line-pos (b-do-game j))
(line-pos (e-do-game j)))
(sublist4 (column-pos (b-do-game j))
(+ 1 (line-pos (b-do-game j)))
(line-pos (e-do-game j))))))
This is the first part of the game I'm making, I was translating the variables from portuguese to english so it could have some error.
Dlm, can you do the same that you did in your code with "while cicles"?
Could you check my code and improve it a litle? I am trying to improve my programming skills, and it's starts from my code, Basicaly I want to get a programming style
Sorry for the previous posting. It was my first post
and I posted as an unregistered user. I obviously
haven't figured out how to format text yet.
I've created an account (user dlm) and I'm making a
second attempt -- here goes.
I've been working on learning Racket/Scheme for a while
now and this site looks like a great place to share and
learn from others.
I'm not 100% sure of the spec on this question and
have my doubts that my code actually solves the problem
at hand but I think it's readable enough to be modified
as needed
Readability is one of the things I've been working on
and would appreciate feedback/suggestions from others.
dlm.
My 2 cents :
(define (process-list? lst)
(let*([pair-0 (list-ref lst 0)]
[pair-1 (list-ref lst 1)])
(and (= (car pair-0) (car pair-1))
(< (cdr pair-0) (cdr pair-1)))))
(define (make-odd/even-sets data)
(let*([x (car (list-ref data 0))]
[y-start (cdr (list-ref data 0))]
[max (cdr (list-ref data 1))])
(define (loop y evens odds)
(if (<= y max)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds))
(list (reverse odds) (reverse evens))))
(loop y-start '() '())))
(define (main data)
(if (process-list? data)
(let*([odd/even (make-odd/even-sets data)])
(printf "~a~n" (list-ref odd/even 0))
(printf "~a~n" (list-ref odd/even 1)))
(printf "Invalid list~n" )))
(main '((1 . 1) (1 . 7)) )
UPDATE:
Hi gn66,
I don't know how much I can actually do in terms of the
game itself but I might be able to give you some
pointers/ideas.
A major thing to look for in improving code is to to
look for repeating code applied to specific situations
and try to think of ways to generalize. At first the
generalized form can seam harder to read when you don't
see what's going on but once you fully understand it
it's actually easier, not only to read but modify.
Looking at your code the 'adjacent' procedure jumps out
as something that could be shortened so I'll use that as
an example. Let's start by first ignoring the boundary
conditions and look for the generial pattern of
operations (example: where you put the logic for
conditional test can have a big effect on the size of the
code).
(define (adjacent p)
(list (do-pos (+ (line-pos p) 1) (column-pos p))
(do-pos (- (line-pos p) 1) (column-pos p))
(do-pos (line-pos p) (+ (column-pos p) 1))
(do-pos (line-pos p) (- (column-pos p) 1))) )
The problem here can be partitioned into 2 different
problems: 1) changing line postions + - 1 and
2) changing row positions + - 1. Both applying
the same operations to different components of the
position. So let's just work with one.
(instead of a while loop lets look at MAP which is
like a "while list not empty" loop)
Using 'map' to apply an operation to data list(s)
is pretty straight forward:
(map (lambda (val) (+ val 5))
'(10 20 30))
If needed you can inclose it inside the scope of a procdure
to maintain state information such as a counter:
(define (test lst)
(let*([i 0])
(map (lambda (val)
(set! i (+ i 1))
(+ val i))
lst)))
(test '(10 20 30))
Or pass in values to use in the operation:
(define (test lst amount)
(map (lambda (val) (+ val amount))
lst))
(test '(10 20 30) 100)
Now turn your thinking inside out and consider that
it's possible to have it map a list of operations to
some data rather than data to the operation.
(define (test val operations-lst)
(map (lambda (operation) (operation val))
operations-lst))
(test 10 (list sub1 add1))
Now we have the tools to start creating a new
'adjacent' procedure:
(define (adjacent p)
(define (up/down p) ;; operations applied to the line componet
(map (lambda (operation)
(cons (operation (line-pos p)) (column-pos p)))
(list add1 sub1)))
(define (left/right p) ;; operations applied to the column componet
(map (lambda (operation)
(cons (line-pos p) (operation (column-pos p))))
(list add1 sub1)))
(append (up/down p) (left/right p))
)
(adjacent (do-pos 1 1))
This works find for positions that aren't on the boundary
but just as the old saying goes "it's sometimes easier to do
something and then apologize for it than it is to first ask
permission". Let's take the same approach and let the errant
situations occur then remove them. The 'filter' command is
just the tool for the job.
The 'filter' command is similiar to the map command in that
it takes a list of values and passes them to a function. The
'map' command returns a new list containing new elements
that correpsond to each element consumed. Filter returns
the original values but only the ones that the (predicate)
function "approves of" (returns true for).
(filter
(lambda (val) (even? val))
'(1 2 3 4 5 6 7 8))
will return the list (2 4 6 8)
So adding this to the new 'adjacent' procedure we get:
(define (adjacent p)
(define (up/down p)
(map (lambda (operation)
(cons (operation (line-pos p)) (column-pos p)))
(list add1 sub1)))
(define (left/right p)
(map (lambda (operation)
(cons (line-pos p) (operation (column-pos p))))
(list add1 sub1)))
(define (select-valid p-lst)
(filter
(lambda (p) (and (>= (line-pos p) 0) (>= (column-pos p) 0)
(<= (line-pos p) 7) (<= (column-pos p) 7)))
p-lst))
(select-valid
(append (up/down p) (left/right p))))
As for the "while cycles" you asked about: you need to
develop the ability to "extract" information like this from
existing examples. You can explore different aspects of
existing code by trying to remove as much code as you can
and still get it to work for what you are interested in
(using print statements to get a window onto what's going
on). This is a great way to learn.
From my first posting cut out the loop that creates the
evens/odds list. When you try to run you find out what is
missing (the dependencies) from the error messages so
just define them as needed:
(define x 1)
(define max 5)
(define (loop y evens odds)
(if (<= y max)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds))
(list (reverse odds) (reverse evens))))
(loop 1 '() '())
Add a print statement to get info on the mechanics of how
it works:
(define x 1)
(define max 5)
(define y-start 1)
(define (loop y evens odds)
(if (<= y max)
(begin
(printf "section 1 : y=~a~n" y)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds)))
(begin
(printf "section 2 : y=~a~n" y)
(list (reverse odds) (reverse evens))
)))
(loop y-start '() '())
Now remove parts you aren't interested in or don't need,
which may take some exploration:
(let*([max 5])
(define (loop y)
(if (<= y max)
(begin
(printf "section 1 : y=~a~n" y)
(loop (add1 y)))
(begin
(printf "section 2 : y=~a~n" y)
'()
)))
(loop 1))
Now you should be able to more easily see the mechanics of a
recursive while loop and use this as a simple template
to apply to other situations.
I hope this helps and I hope it doesn't cross the line
on the "subjective questions" guidelines -- I'm new to
this site and hope to fit in as it looks like a great
resource.
I'm a bit rusty in scheme, I've managed to get this solution to your problem,
it use recursion vs while, but I'm not accustomed to that construct in scheme:
(define data (list (cons 1 1) (cons 1 7)))
(define (neven n) (if (even? n) n (+ n 1)))
(define (sublist a mn mx)
(cond
((<= mn mx ) (cons (cons a mn) (sublist a (+ mn 2) mx)))
(else '())))
(define (game-position input)
(if (= (caar input) (caadr input))
(list (sublist (caar input)
(neven (cdar input))
(cdadr input))
(sublist (caar input)
(+ 1 (neven (cdar input)))
(cdadr input)))
(error "no match")))
(game-position data)
edit: It works in guile and drscheme. Hope it will works in plt-scheme too.
edit: sublist inner working
First the parameters:
a is the car of the pairs contained into the list
mn is the cdr of the first pair
mx is the upper limit of the serie.
the body of the function is quite simple:
if the cdr of the current pair is smaller or equal to the upper limit then return a list
composed by a pair (a . mn) and the list created by a call to sublist with the mn parameter changed to reflect the next possible pair.
if the current pair will have a cdr higher than the upper limit then return null (empty list) in order to close the cons issued by the previous invocation of sublist.
I've been working on learning Racket/Scheme for a while
now and this site looks like a great place to share and
learn from others.
I'm not 100% sure of the spec on this question and
have my doubts that my code actually solves the problem
at hand but I think it's readable enough to be modified
as needed
Readability is one of the things I've been working on
and would appreciate feedback/suggestions from others.
dlm.
My 2 cents :
(define (process-list? lst)
(let*([pair-0 (list-ref lst 0)]
[pair-1 (list-ref lst 1)])
(and (= (car pair-0) (car pair-1))
(< (cdr pair-0) (cdr pair-1)))))
(define (make-odd/even-sets data)
(let*([x (car (list-ref data 0))]
[y-start (cdr (list-ref data 0))]
[max (cdr (list-ref data 1))])
(define (loop y evens odds)
(if (<= y max)
(loop (add1 y)
(if (even? y) (cons (cons x y) evens) evens)
(if (odd? y) (cons (cons x y) odds) odds))
(list (reverse odds) (reverse evens))))
(loop y-start '() '())))
(define (main data)
(if (process-list? data)
(let*([odd/even (make-odd/even-sets data)])
(printf "~a~n" (list-ref odd/even 0))
(printf "~a~n" (list-ref odd/even 1)))
(printf "Invalid list~n" )))
(main '((1 . 1) (1 . 7)) )