; Add binary operators into the evaluation of your DSL
; ------------------------------
; The Little Lisper 3rd Edition
; Chapter 7
; Exercise 10
; Common Lisp
; http://t...content-available-to-author-only...r.com/thelittlelisper
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper-chapter-7-shadows.html
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper.html
; ------------------------------
(setf l1 '())
(setf l2 '(3 + (66 6)))
(setf aexp4 5)
; ------------------------------

(setf lexp1 '(AND (OR x y) y))
(setf lexp2 '(AND (NOT y)(OR u v)))
(setf lexp3 '(OR x y))
(setf lexp4 'z)

(OR t f t f)
;T

(AND t NIL t NIL)
;NIL false

(defun Mlexp (x y))

(defun Mlexp-OR (lat alist)
  (cond
   ((null alist) NIL)
   ((null lat) NIL)
   (t
    (OR
     (Mlexp (car lat) alist)
     (Mlexp-OR (cdr lat) alist)))))

(Mlexp-OR '(x y z) '((x 1)(y 1)(z 0)))
;T

(Mlexp-OR '(x y z) '((x 1)))
;T

(defun lookup (a lat)
  (cond
   ((null a) NIL)
   ((null lat) NIL)
   ((eq a (car (car lat)))
    (cdr (car lat)))
   (t 
    (lookup a (cdr lat)))))

(lookup 'x '((x 1)(y 1)(z 0)))
;(1)

(defun Mlexp-AND (lat alist)
  (cond
   ((null alist) NIL)
   ((null lat) t)
   (t
    (AND
     (Mlexp (car lat) alist)
     (Mlexp-AND (cdr lat) alist)))))

(Mlexp-AND '(x y z) '((x 1)(y 1)(z 0)))
;NIl false

(Mlexp-AND '(x) '((x 0)))
;NIL false

(Mlexp-AND '(x) '((y 1)(x 0)))
;NIL false

(Mlexp-AND '(x y) '((x 1)(y 1)(z 0)))
;T 

(defun operator (aexp_)
  (car aexp_))
  
(defun 1st-sub-expr (aexp_)
  (car (cdr aexp_)))

(defun Mlexp (lexp_ alist_)
  (cond
   ((null lexp_) NIL)
   ((null alist_) NIL)
   ((atom lexp_)
    (cond
     ;((eq lexp_ 't) t)
     ((= 1 (car(lookup lexp_ alist_))) t)
     (t NIL)))
   ((eq (operator lexp_) 'AND)
    (Mlexp-AND (cdr lexp_) alist_))
   ((eq (operator lexp_) 'OR)
     (Mlexp-OR (cdr lexp_) alist_))
   ((eq (operator lexp_) 'NOT)
     (cond
    ((not
     (Mlexp (1st-sub-expr lexp_) alist_))
      't)
     (t NIL)))
   (t NIL)))

(print (Mlexp lexp1 '((x 1)(y 0)(z 0))))
;NIKL false

(print (setf lexp2 '(AND (NOT y)(OR u v))))
(Mlexp lexp2 '((y 0)(u 0)(v 1)))
;T

(print (Mlexp '(OR u v) '((y 0)(u 0)(v 1))))
;T

(print (Mlexp '(OR u (OR u v)) '((y 0)(u 0)(v 1))))
;T

(print (Mlexp '(NOT y) '((y 0)(u 0)(v 1))))
;T

(print (Mlexp '(AND v v) '((y 0)(u 0)(v 1))))
;T

(print (Mlexp '(AND (AND v v) v) '((y 0)(u 0)(v 1))))
;T

(print (Mlexp lexp4 '((x 1)(y 0)(z 0))))
;NIL false



(print (Mlexp '(AND x y z) '((x 1)(y 0)(z 0))));F;correct
(print (Mlexp '(NOT(AND x y z)) '((x 1)(y 0)(z 0))));T;correct
(print (Mlexp '(OR z z (NOT(AND x y z))) '((x 1)(y 0)(z 0))));T;correct
