26 iunie 2010

Partitiile unui numar in Haskell si Clips

_____________________HUSKELL________________________
leng [] = 0
leng (a:list) = 1 + leng list

-- ret o lista in care elem de pe poz poz_start si poz_start+1 sunt alipite,adunate
sm list poz_start 1 = []
sm (a:list) poz_start i =
if(i==poz_start) then (a+(head list)):(sm (tail list) poz_start (i-1))
else a:(sm list poz_start (i-1))
find lista poz_start = sm lista (leng lista - poz_start + 1) (leng lista)

-- genereaza toate astfel de combinari (pot fi duplicate)
genComb list k =
if(k<=(leng list - 1)) then (find list k):(genComb list (k+1))
else []
genC lista = genComb lista 1

-- eliminare duplicate de tip lista dintr-o lista

-- daca un element e membru intr-o lista
member x [] = False
member x (h:t) =
if (h == x) then True
else member x t

-- sterge element dintr-o lista
del x (a:list) =
if (x==a) then list
else a:(del x list)
-- daca doua liste sunt egale
eg [] list = True
eg (a:l1) l2 =
if (member a l2 == True) then eg l1 (del a l2)
else False
egale l1 l2 =
if (leng l1 == leng l2 && (eg l1 l2 == True)) then True
else False

-- daca o lista exista intr-o lista de liste
exista l [] = False
exista l (b:lista) =
if (egale l b == True) then True
else exista l lista

-- elimina duplicate
elimd [] = []
elimd (a:list) =
if(exista a list) then elimd list
else a:(elimd list)
generate list = elimd(genC list)

-- adauga la o lista de liste o noua lista
alipire [] list = [list]
alipire (a:l) list =
a:(alipire l list)

-- genereaza partitii pt o lista cu lungime admisa
gen_size list size =
if(size == leng list) then generate list
else []

-- gen partitiile pt toate listele de o anumita lungime dintr-o lista de liste
gen [] size = []
gen (a:list_of_lists) size =
(gen_size a size)++(gen list_of_lists size)
gen_final list 1 = list
gen_final list n =
gen_final ((gen list n)++list) (n-1)

-- n scris ca "suma" de n elem de 1
equiv 0 = []
equiv n =
1:(equiv (n-1))
result 0 = [[0]]
result n =
(elimd (gen_final (generate (equiv n)) n))++[(equiv n)]
-- se apeleaza: result n
_____________________ CLIPS ____________________

(deftemplate partitie (multislot p) )
(deffacts facts (p ) (n 5)) ; n reprezinta numarul pt partitionat

; scrie nr n de forma (p 1 1 ... 1) = prima partitie
(defrule init
?q <- (n ?x)
?r <- (p $?a)
(test (> ?x 0))
=> (retract ?q)
(assert (n (- ?x 1)))
(retract ?r)
(assert (p $?a 1))
)

; creeaza partitii cu tot cu duplicate
(defrule adds
(p $?a ?b ?c $?d)
=> (assert (p $?a (+ ?b ?c) $?d))
)

; sterge partitiile care contin nr descrescatoare (si elimina duplicate)
(defrule delete
?q <-(p $?a ?b ?c $?d)
(test ( > ?b ?c))
=>(retract ?q)
)

; partitiile se pot vedea in (facts)
; (p .....)

Niciun comentariu: