Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[141]

(cond ((var? e)

(if (equal? var e) true

(let ((b (binding-in-frame e frame)))

(if b

(tree-walk (binding-value b))

false))))

((pair? e) (or (tree-walk (car e)) (tree-walk (cdr e)))) (else false))) (tree-walk exp))

4.4.4.5 Ведение базы данных

Одна из важных задач при разработке логических языков программирования - так организовать работу, чтобы при проверке каждого образца просматривалось как можно меньше ненужных записей из базы. В нашей системе, помимо того, что мы храним все утверждения в одном большом потоке, мы в отдельных потоках храним утверждения, cart>i которых являются константными символами, в таблице, индексируемой по этим символам. Чтобы получить утверждения, которые могут сопоставляться с образцом, мы сначала смотрим, не является ли car образца константным символом. Если это так, то мы возвращаем (сопоставителю для проверки) все хранимые утверждения с тем же car. Если car образца не является константным символом, мы возвращаем все хранимые утверждения. Более изысканные методы могли бы использовать еще информацию из кадра, либо пытаться оптимизировать и тот случай, когда car образца не является константным символом. Мы избегаем встраивания критериев для индексации (использование car, обработка только случая с константными символами) в программу: вместо этого мы вызываем предикаты и селекторы, реализующие эти критерии.

(define THE-ASSERTIONS the-empty-stream)

(define (fetch-assertions pattern frame) (if (use-index? pattern)

(get-indexed-assertions pattern) (get-all-assertions)))

(define (get-all-assertions) THE-ASSERTIONS)

(define (get-indexed-assertions pattern)

(get-stream (index-key-of pattern) assertion-stream))

Процедура get-stream ищет поток в таблице и, если ничего там не находит, возвращает пустой поток.

(define (get-stream key1 key2)

(let ((s (get key1 key2)))

(if s s the-empty-stream)))

Правила хранятся подобным же образом, с использованием car заключения правила. Однако в заключениях правил могут стоять произвольные образцы,


и таким образом, они отличаются от утверждений тем, что могут содержать переменные. Образец, в car которого стоит константный символ, может сопоставляться не только с правилами, у которых car заключения содержит тот же символ, но и с правилами, где в начале заключения стоит переменная. Таким образом, при поиске правил, которые могут сопоставляться с образцом, у которого в начале константный символ, мы возвращаем как правила с этим символом в car заключения, так и правила с переменной в начале заключения. Ради этого мы храним правила с переменными в начале заключения в отдельном потоке, который находится в таблице под индексом ? .

(define THE-RULES the-empty-stream)

(define (fetch-rules pattern frame) (if (use-index? pattern)

(get-indexed-rules pattern) (get-all-rules)))

(define (get-all-rules) THE-RULES)

(define (get-indexed-rules pattern) (stream-append (get-stream (index-key-of pattern) rule-stream) (get-stream ? rule-stream)))

Процедура add-rule-or-assertion! вызывается из query-driver-loop, когда требуется добавить к базе данных правило или утверждение. Каждая запись сохраняется в индексе, если это требуется, а также в общем потоке правил либо утверждений базы данных.

(define (add-rule-or-assertion! assertion) (if (rule? assertion)

(add-rule! assertion) (add-assertion! assertion)))

(define (add-assertion! assertion) (store-assertion-in-index assertion) (let ((old-assertions THE-ASSERTIONS)) (set! THE-ASSERTIONS

(cons-stream assertion old-assertions))

ok))

(define (add-rule! rule) (store-rule-in-index rule)

(let ((old-rules THE-RULES))

(set! THE-RULES (cons-stream rule old-rules))

ok))

Чтобы вставить в базу утверждение или правило, мы проверяем, можно ли его проиндексировать. Если да, то мы сохраняем его в соответствующем потоке.

(define (store-assertion-in-index assertion) (if (indexable? assertion)

(let ((key (index-key-of assertion))) (let ((current-assertion-stream


(get-stream key assertion-stream))) (put key

assertion-stream (cons-stream assertion

current-assertion-stream))))))

(define (store-rule-in-index rule) (let ((pattern (conclusion rule))) (if (indexable? pattern)

(let ((key (index-key-of pattern))) (let ((current-rule-stream

(get-stream key rule-stream))) (put key

rule-stream (cons-stream rule

current-rule-stream)))))))

Следующие процедуры определяют, как используется индекс базы данных. Образец (утверждение или заключение правила) сохраняется в таблице, если он начинается с переменной или константного символа.

(define (indexable? pat)

(or (constant-symbol? (car pat)) (var? (car pat))))

Ключ, под которым образец сохраняется в таблице - это либо ? (если он начинается с переменной), либо константный символ из его начала.

(define (index-key-of pat) (let ((key (car pat)))

(if (var? key) ? key)))

Для поиска записей, которые могут соответствовать образцу, используется индекс в том случае, когда образец начинается с константного символа.

(define (use-index? pat)

(constant-symbol? (car pat)))

Упражнение 4.70.

Какова цель выражений let в процедурах add-assertion! и add-rule!? Что неправильно в следующем варианте add-assertion!? Подсказка: вспомните определение бесконечного потока единиц из раздела 3.5.2: (define ones (cons-stream 1 ones)) .

(define (add-assertion! assertion) (store-assertion-in-index assertion)

(set! THE-ASSERTIONS

(cons-stream assertion THE-ASSERTIONS))

ok)

4.4.4.6 Операции над потоками

В запросной системе используется несколько операций над потоками, помимо представленных в главе 3.



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196]