27 octombrie 2014

Extensii pentru limbajul LET | EOPL3 Let language extensions: SET

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))

Niciun comentariu: