From 7bea10031060aeb9ca3ca716d301a1d02fb0f52e Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <vu3rdd@gmail.com>
Date: Wed, 23 Mar 2011 21:56:08 +0530
Subject: [PATCH] solutions to 3.28, 3.29 and 3.30

---
 src/sicp/ex3_28.rkt | 21 ++++++++++++++
 src/sicp/ex3_29.rkt | 25 +++++++++++++++++
 src/sicp/ex3_30.rkt | 67 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 src/sicp/ex3_28.rkt
 create mode 100644 src/sicp/ex3_29.rkt
 create mode 100644 src/sicp/ex3_30.rkt

diff --git a/src/sicp/ex3_28.rkt b/src/sicp/ex3_28.rkt
new file mode 100644
index 0000000..33e64b8
--- /dev/null
+++ b/src/sicp/ex3_28.rkt
@@ -0,0 +1,21 @@
+#lang racket
+
+(define (or-gate o1 o2 output)
+  (define (or-action-procedure)
+    (let ((new-value
+           (logical-or (get-signal o1)
+                       (get-signal o2))))
+      (after-delay or-gate-delay
+                   (lambda ()
+                     (set-signal! output new-value)))))
+  
+  (define (logicval-or o1 o2)
+    (cond
+      ((and (= o1 0) (= o1 0)) 0)
+      ((or  (= o1 1) (= o2 1)) 1)
+      (else (error "invalid signals"))))
+  
+  (add-action! o1 or-action-procedure)
+  (add-action! o2 or-action-procedure)
+  'ok)
+
diff --git a/src/sicp/ex3_29.rkt b/src/sicp/ex3_29.rkt
new file mode 100644
index 0000000..5d56596
--- /dev/null
+++ b/src/sicp/ex3_29.rkt
@@ -0,0 +1,25 @@
+#lang racket
+
+#|
+(or a b) = (and (and (not a) b)
+                (and a (not b))
+|#
+
+(define (or-gate o1 o2 output)
+  (let ((a1 (make-wire)) 
+        (a2 (make-wire))
+        (a3 (make-wire))
+        (a4 (make-wire)))
+    (inverter o1 a1)
+    (inverter o2 a2)
+    (and-gate a1 o2 a3)
+    (and-gate o1 a2 a4)
+    (and-gate a3 a4 output)
+    'ok))
+
+#|
+
+or-gate delay is one inverter delay + 2 x and-gate-delay, considering that
+the whole things works in a parallel way. i.e. a3 and a4 are produced parallely.
+
+|#
\ No newline at end of file
diff --git a/src/sicp/ex3_30.rkt b/src/sicp/ex3_30.rkt
new file mode 100644
index 0000000..f234752
--- /dev/null
+++ b/src/sicp/ex3_30.rkt
@@ -0,0 +1,67 @@
+#lang racket
+
+(define (half-adder a b s c)
+  (let ((d (make-wire)) (e (make-wire)))
+    (or-gate a b d)
+    (and-gate a b c)
+    (inverter c e)
+    (and-gate d e s)
+    'ok))
+
+(define (full-adder a b c-in sum c-out)
+  (let ((s (make-wire))
+        (c1 (make-wire))
+        (c2 (make-wire)))
+    (half-adder b c-in s c1)
+    (half-adder a s sum c2)
+    (or-gate c1 c2 c-out)
+    'ok))
+
+(define (last coll)
+  (cond
+    ((not (null? coll)) (error "coll not a list"))
+    ((null? (cdr coll)) (car coll))
+    (else (last (cdr coll)))))
+
+(define (butlast coll)
+  (cond
+    ((not (null? coll)) (error "coll not a list"))
+    ((null? (cdr coll)) '())
+    (else (cons (car coll)
+                (butlast (cdr coll))))))
+
+(define (ripple-carry-adder a-list b-list s-list c)
+  (define (ripple-carry-adder-1 a-list b-list c-in s-list c-out)
+    (if (null? a-list)
+        'ok
+        (begin
+          (full-adder (last a-list)
+                      (last b-list)
+                      c-in
+                      (last s-list)
+                      c-out)
+          (ripple-carry-adder-1 (butlast a-list)
+                                (butlast b-list)
+                                c-out
+                                (butlast s-list)
+                                c-out))))
+  (let ((c-in (make-wire))
+        (c-out (make-wire)))
+    (set-signal! c-in 0)
+    (ripple-carry-adder-1 a-list
+                          b-list
+                          c-in
+                          s-list
+                          c-out)))
+
+#|
+
+delay for s(n) = n x full-adder-delay
+
+1 full-adder-delay = 2 x half-adder-delay + 1 x or-gate-delay
+
+1 half-adder-delay = max ((and-gate-delay + inverter delay), or-gate-delay)
+                     + and-gate-delay
+
+|#
+
-- 
2.45.2