SET
> data-structures.scm
;;; inside define-datatype
(set-val
(set (list-of expval?))
)
;;; independent function
(define expval->set (lambda (v)
(cases expval v
(set-val (set) set)
(else (expval-extractor-error 'set v)))))
> lang.scm
;;; inside expression
(expression
("set" "{" (separated-list expression ",") "}")
set-exp)
> interp.scm
;;; inside value-of
(set-exp (exp1) ; exp1 is a list of expressions
;; the return type should be set-val
(set-val
(map (lambda (myexp) (value-of myexp env)) exp1)) ; don't make it concrete value inside the set!
)
> top.scm
;;; inside sloppy->expval
((list? sloppy-val) (set-val (map sloppy->expval sloppy-val)))
> tests.scm
(set-test-diff1 "-(set {1,2}, 3)" error) ; can't extract from a set
(set-test-diff2 "-(5, set {1,2})" error)
(set-test-zero "zero?(set{1,2})" error) ; can't test a set for zero
(set-test-if1 "if set{1,2} then #t else 2" error) ; can't test if set
(set-test-if2 "if zero?(2) then 3 else set {1,2}" (1 2))
(set-test-if3 "if zero?(0) then set{1,2} else 0" (1 2))
(test-set-let1 "let id =set {1,2,3} in id" (1 2 3))
(test-set-let2 "let x=1 in set {x, -(x,1), -(x,2)}" (1 0 -1))
(test-set-set "set {set {1,2}, 5, zero?(3), if zero?(x) then x else 0, let y=1 in set{y,7}}"
((1 2) 5 #f 0 (1 7)))
Operații pe SET de numere: Union, Intersect, Membership, isEmpty ...
> lang.scm_______________________________________________________
;; member check
(expression
("is" expression "member-of" expression)
memb-exp)
;; is empty
(expression
("empty-set?" "(" expression ")")
empty-exp)
;; union
(expression
("union" expression "with" expression)
union-exp)
;; intersection
(expression
("intersect" expression "with" expression)
inter-exp)
> interp.scm___________________________________________________________
;; membership ---- works only for numbers inside of set
(memb-exp (memb setList)
(letrec ((mymember (expval->num (value-of memb env)))
(myset (expval->set (value-of setList env)))
(getMembership (lambda (memberName set)
(if (null? set) (bool-val #f)
(if (eq? (expval->num (car set)) memberName) (bool-val #t)
(getMembership memberName (cdr set)))))))
(getMembership mymember myset)))
;; check if set is empty
(empty-exp (setList)
(if (null? (expval->set (value-of setList env))) (bool-val #t)
(bool-val #f)))
;; union --- set of numbers
(union-exp (set1 set2)
(letrec ((s1 (expval->set (value-of set1 env)))
(s2 (expval->set (value-of set2 env)))
(isMember (lambda (mem mylist)
(if (null? mylist) #f (if (eq? (expval->num mem) (expval->num (car mylist))) #t (isMember mem (cdr mylist))))))
(getUnion (lambda (se1 se2)
(if (null? se2) se1
(if (not (isMember (car se2) se1)) (getUnion (cons (car se2) se1) (cdr se2))
(getUnion se1 (cdr se2)))))))
(set-val (getUnion s1 s2))))
;; intersection --- works for numbers only
(inter-exp (set1 set2)
(letrec ((myset1 (expval->set (value-of set1 env)))
(myset2 (expval->set (value-of set2 env)))
(isMember (lambda (mem mylist)
(if (null? mylist) #f (if (eq? (expval->num mem) (expval->num (car mylist))) #t (isMember mem (cdr mylist))))))
(find-intersect (lambda (s1 s2 dummy)
(if (null? s1) dummy ; else
(if (isMember (car s1) s2) (find-intersect (cdr s1) s2 (cons (car s1) dummy))
(find-intersect (cdr s1) s2 dummy))))))
(set-val (find-intersect myset1 myset2 '()))))
> tests.scm__________________________________________________________
(test-member1 "is 2 member-of set {1,2,3}" #t)
(test-member2 "is 4 member-of set {1,2,3}" #f)
(test-empty1 "empty-set?(set{2,3,4, set{1,2}})" #f)
(test-empty2 "empty-set?(set{})" #t)
(test-union1 "union set{1,2} with set{2,3}" (3 1 2))
(test-union2 "union set{} with set{2}" (2))
(test-inter1 "intersect set{1,2} with set{2,3}" (2))
(test-inter2 "intersect set{0,4,2,1,6,3} with set {9,0,2,10}" (2 0))