diff --git a/doc/chapter03/ex_3_34.md b/doc/chapter03/ex_3_34.md new file mode 100644 index 0000000..9a99dc6 --- /dev/null +++ b/doc/chapter03/ex_3_34.md @@ -0,0 +1,17 @@ +# [Глава 3](../index.md#Глава-3) + +### Упражнение 3.34 +Хьюго Дум хочет построить квадратор, блок-ограничение с двумя выводами, такое, что значение соединителя `b` на втором выводе всегда будет равно квадрату значения соединителя `a` на первом выводе. Он предлагает следующее простое устройство на основе умножителя: + +```clojure +(defn squarer [a b] + (multiplier a a b)) +``` + +В такой идее есть существенная ошибка. Объясните ее. + +#### Решение +Установка значения для вывода `b` не позволяет получить значение `a`. + +[Code](../../src/sicp/chapter03/3_34.clj) | [Test](../../test/sicp/chapter03/3_34_test.clj) + diff --git a/doc/index.md b/doc/index.md index 3601a07..f24854a 100644 --- a/doc/index.md +++ b/doc/index.md @@ -153,3 +153,4 @@ * [Упражнение 3.31](./chapter03/ex_3_31.md) Альтернативный вариант процедуры `accept-action-procedure!` * [Упражнение 3.32](./chapter03/ex_3_32.md) * [Упражнение 3.33](./chapter03/ex_3_33.md) Система ограничений. Процедура `averager`. + * [Упражнение 3.34](./chapter03/ex_3_34.md) Система ограничений. Процедура `squarer`. diff --git a/src/sicp/chapter03/3_34.clj b/src/sicp/chapter03/3_34.clj new file mode 100644 index 0000000..4933eb0 --- /dev/null +++ b/src/sicp/chapter03/3_34.clj @@ -0,0 +1,6 @@ +(ns sicp.chapter03.3-34 + (:require [sicp.chapter03.constraints :refer [multiplier]])) + +(defn squarter + [a b] + (multiplier a a b)) diff --git a/test/sicp/chapter03/3_34_test.clj b/test/sicp/chapter03/3_34_test.clj new file mode 100644 index 0000000..da7ac97 --- /dev/null +++ b/test/sicp/chapter03/3_34_test.clj @@ -0,0 +1,26 @@ +(ns sicp.chapter03.3-34-test + (:require [clojure.test :refer :all] + [sicp.chapter03.3-34 :refer [squarter]] + [sicp.chapter03.constraints :refer [get-value make-connector probe + set-value!]])) + +(deftest test-squarter + (let [a (make-connector) + b (make-connector)] + (squarter a b) + + (probe "A" a) + (probe "B" b) + + (is (= :done (set-value! a 3 :user))) + (is (= 9 (get-value b)))) + + (let [a (make-connector) + b (make-connector)] + (squarter a b) + + (probe "A" a) + (probe "B" b) + + (is (= :done (set-value! b 9 :user))) + (is (nil? (get-value a)))))