sboyer.sch 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ; File: sboyer.sch
  3. ; Description: The Boyer benchmark
  4. ; Author: Bob Boyer
  5. ; Created: 5-Apr-85
  6. ; Modified: 10-Apr-85 14:52:20 (Bob Shaw)
  7. ; 22-Jul-87 (Will Clinger)
  8. ; 2-Jul-88 (Will Clinger -- distinguished #f and the empty list)
  9. ; 13-Feb-97 (Will Clinger -- fixed bugs in unifier and rules,
  10. ; rewrote to eliminate property lists, and added
  11. ; a scaling parameter suggested by Bob Boyer)
  12. ; 19-Mar-99 (Will Clinger -- cleaned up comments)
  13. ; 4-Apr-01 (Will Clinger -- changed four 1- symbols to sub1)
  14. ; Language: Scheme
  15. ; Status: Public Domain
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17. ;;; SBOYER -- Logic programming benchmark, originally written by Bob Boyer.
  18. ;;; Much less CONS-intensive than NBOYER because it uses Henry Baker's
  19. ;;; "sharing cons".
  20. ; Note: The version of this benchmark that appears in Dick Gabriel's book
  21. ; contained several bugs that are corrected here. These bugs are discussed
  22. ; by Henry Baker, "The Boyer Benchmark Meets Linear Logic", ACM SIGPLAN Lisp
  23. ; Pointers 6(4), October-December 1993, pages 3-10. The fixed bugs are:
  24. ;
  25. ; The benchmark now returns a boolean result.
  26. ; FALSEP and TRUEP use TERM-MEMBER? rather than MEMV (which is called MEMBER
  27. ; in Common Lisp)
  28. ; ONE-WAY-UNIFY1 now treats numbers correctly
  29. ; ONE-WAY-UNIFY1-LST now treats empty lists correctly
  30. ; Rule 19 has been corrected (this rule was not touched by the original
  31. ; benchmark, but is used by this version)
  32. ; Rules 84 and 101 have been corrected (but these rules are never touched
  33. ; by the benchmark)
  34. ;
  35. ; According to Baker, these bug fixes make the benchmark 10-25% slower.
  36. ; Please do not compare the timings from this benchmark against those of
  37. ; the original benchmark.
  38. ;
  39. ; This version of the benchmark also prints the number of rewrites as a sanity
  40. ; check, because it is too easy for a buggy version to return the correct
  41. ; boolean result. The correct number of rewrites is
  42. ;
  43. ; n rewrites peak live storage (approximate, in bytes)
  44. ; 0 95024
  45. ; 1 591777
  46. ; 2 1813975
  47. ; 3 5375678
  48. ; 4 16445406
  49. ; 5 51507739
  50. ; Sboyer is a 2-phase benchmark.
  51. ; The first phase attaches lemmas to symbols. This phase is not timed,
  52. ; but it accounts for very little of the runtime anyway.
  53. ; The second phase creates the test problem, and tests to see
  54. ; whether it is implied by the lemmas.
  55. (define (sboyer-benchmark . args)
  56. (let ((n (if (null? args) 0 (car args))))
  57. (setup-boyer)
  58. (run-benchmark (string-append "sboyer"
  59. (number->string n))
  60. 1
  61. (lambda () (test-boyer n))
  62. (lambda (rewrites)
  63. (and (number? rewrites)
  64. (case n
  65. ((0) (= rewrites 95024))
  66. ((1) (= rewrites 591777))
  67. ((2) (= rewrites 1813975))
  68. ((3) (= rewrites 5375678))
  69. ((4) (= rewrites 16445406))
  70. ((5) (= rewrites 51507739))
  71. ; If it works for n <= 5, assume it works.
  72. (else #t)))))))
  73. (define (setup-boyer) #t) ; assigned below
  74. (define (test-boyer) #t) ; assigned below
  75. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  76. ;
  77. ; The first phase.
  78. ;
  79. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  80. ; In the original benchmark, it stored a list of lemmas on the
  81. ; property lists of symbols.
  82. ; In the new benchmark, it maintains an association list of
  83. ; symbols and symbol-records, and stores the list of lemmas
  84. ; within the symbol-records.
  85. (let ()
  86. (define (setup)
  87. (add-lemma-lst
  88. (quote ((equal (compile form)
  89. (reverse (codegen (optimize form)
  90. (nil))))
  91. (equal (eqp x y)
  92. (equal (fix x)
  93. (fix y)))
  94. (equal (greaterp x y)
  95. (lessp y x))
  96. (equal (lesseqp x y)
  97. (not (lessp y x)))
  98. (equal (greatereqp x y)
  99. (not (lessp x y)))
  100. (equal (boolean x)
  101. (or (equal x (t))
  102. (equal x (f))))
  103. (equal (iff x y)
  104. (and (implies x y)
  105. (implies y x)))
  106. (equal (even1 x)
  107. (if (zerop x)
  108. (t)
  109. (odd (sub1 x))))
  110. (equal (countps- l pred)
  111. (countps-loop l pred (zero)))
  112. (equal (fact- i)
  113. (fact-loop i 1))
  114. (equal (reverse- x)
  115. (reverse-loop x (nil)))
  116. (equal (divides x y)
  117. (zerop (remainder y x)))
  118. (equal (assume-true var alist)
  119. (cons (cons var (t))
  120. alist))
  121. (equal (assume-false var alist)
  122. (cons (cons var (f))
  123. alist))
  124. (equal (tautology-checker x)
  125. (tautologyp (normalize x)
  126. (nil)))
  127. (equal (falsify x)
  128. (falsify1 (normalize x)
  129. (nil)))
  130. (equal (prime x)
  131. (and (not (zerop x))
  132. (not (equal x (add1 (zero))))
  133. (prime1 x (sub1 x))))
  134. (equal (and p q)
  135. (if p (if q (t)
  136. (f))
  137. (f)))
  138. (equal (or p q)
  139. (if p (t)
  140. (if q (t)
  141. (f))))
  142. (equal (not p)
  143. (if p (f)
  144. (t)))
  145. (equal (implies p q)
  146. (if p (if q (t)
  147. (f))
  148. (t)))
  149. (equal (fix x)
  150. (if (numberp x)
  151. x
  152. (zero)))
  153. (equal (if (if a b c)
  154. d e)
  155. (if a (if b d e)
  156. (if c d e)))
  157. (equal (zerop x)
  158. (or (equal x (zero))
  159. (not (numberp x))))
  160. (equal (plus (plus x y)
  161. z)
  162. (plus x (plus y z)))
  163. (equal (equal (plus a b)
  164. (zero))
  165. (and (zerop a)
  166. (zerop b)))
  167. (equal (difference x x)
  168. (zero))
  169. (equal (equal (plus a b)
  170. (plus a c))
  171. (equal (fix b)
  172. (fix c)))
  173. (equal (equal (zero)
  174. (difference x y))
  175. (not (lessp y x)))
  176. (equal (equal x (difference x y))
  177. (and (numberp x)
  178. (or (equal x (zero))
  179. (zerop y))))
  180. (equal (meaning (plus-tree (append x y))
  181. a)
  182. (plus (meaning (plus-tree x)
  183. a)
  184. (meaning (plus-tree y)
  185. a)))
  186. (equal (meaning (plus-tree (plus-fringe x))
  187. a)
  188. (fix (meaning x a)))
  189. (equal (append (append x y)
  190. z)
  191. (append x (append y z)))
  192. (equal (reverse (append a b))
  193. (append (reverse b)
  194. (reverse a)))
  195. (equal (times x (plus y z))
  196. (plus (times x y)
  197. (times x z)))
  198. (equal (times (times x y)
  199. z)
  200. (times x (times y z)))
  201. (equal (equal (times x y)
  202. (zero))
  203. (or (zerop x)
  204. (zerop y)))
  205. (equal (exec (append x y)
  206. pds envrn)
  207. (exec y (exec x pds envrn)
  208. envrn))
  209. (equal (mc-flatten x y)
  210. (append (flatten x)
  211. y))
  212. (equal (member x (append a b))
  213. (or (member x a)
  214. (member x b)))
  215. (equal (member x (reverse y))
  216. (member x y))
  217. (equal (length (reverse x))
  218. (length x))
  219. (equal (member a (intersect b c))
  220. (and (member a b)
  221. (member a c)))
  222. (equal (nth (zero)
  223. i)
  224. (zero))
  225. (equal (exp i (plus j k))
  226. (times (exp i j)
  227. (exp i k)))
  228. (equal (exp i (times j k))
  229. (exp (exp i j)
  230. k))
  231. (equal (reverse-loop x y)
  232. (append (reverse x)
  233. y))
  234. (equal (reverse-loop x (nil))
  235. (reverse x))
  236. (equal (count-list z (sort-lp x y))
  237. (plus (count-list z x)
  238. (count-list z y)))
  239. (equal (equal (append a b)
  240. (append a c))
  241. (equal b c))
  242. (equal (plus (remainder x y)
  243. (times y (quotient x y)))
  244. (fix x))
  245. (equal (power-eval (big-plus1 l i base)
  246. base)
  247. (plus (power-eval l base)
  248. i))
  249. (equal (power-eval (big-plus x y i base)
  250. base)
  251. (plus i (plus (power-eval x base)
  252. (power-eval y base))))
  253. (equal (remainder y 1)
  254. (zero))
  255. (equal (lessp (remainder x y)
  256. y)
  257. (not (zerop y)))
  258. (equal (remainder x x)
  259. (zero))
  260. (equal (lessp (quotient i j)
  261. i)
  262. (and (not (zerop i))
  263. (or (zerop j)
  264. (not (equal j 1)))))
  265. (equal (lessp (remainder x y)
  266. x)
  267. (and (not (zerop y))
  268. (not (zerop x))
  269. (not (lessp x y))))
  270. (equal (power-eval (power-rep i base)
  271. base)
  272. (fix i))
  273. (equal (power-eval (big-plus (power-rep i base)
  274. (power-rep j base)
  275. (zero)
  276. base)
  277. base)
  278. (plus i j))
  279. (equal (gcd x y)
  280. (gcd y x))
  281. (equal (nth (append a b)
  282. i)
  283. (append (nth a i)
  284. (nth b (difference i (length a)))))
  285. (equal (difference (plus x y)
  286. x)
  287. (fix y))
  288. (equal (difference (plus y x)
  289. x)
  290. (fix y))
  291. (equal (difference (plus x y)
  292. (plus x z))
  293. (difference y z))
  294. (equal (times x (difference c w))
  295. (difference (times c x)
  296. (times w x)))
  297. (equal (remainder (times x z)
  298. z)
  299. (zero))
  300. (equal (difference (plus b (plus a c))
  301. a)
  302. (plus b c))
  303. (equal (difference (add1 (plus y z))
  304. z)
  305. (add1 y))
  306. (equal (lessp (plus x y)
  307. (plus x z))
  308. (lessp y z))
  309. (equal (lessp (times x z)
  310. (times y z))
  311. (and (not (zerop z))
  312. (lessp x y)))
  313. (equal (lessp y (plus x y))
  314. (not (zerop x)))
  315. (equal (gcd (times x z)
  316. (times y z))
  317. (times z (gcd x y)))
  318. (equal (value (normalize x)
  319. a)
  320. (value x a))
  321. (equal (equal (flatten x)
  322. (cons y (nil)))
  323. (and (nlistp x)
  324. (equal x y)))
  325. (equal (listp (gopher x))
  326. (listp x))
  327. (equal (samefringe x y)
  328. (equal (flatten x)
  329. (flatten y)))
  330. (equal (equal (greatest-factor x y)
  331. (zero))
  332. (and (or (zerop y)
  333. (equal y 1))
  334. (equal x (zero))))
  335. (equal (equal (greatest-factor x y)
  336. 1)
  337. (equal x 1))
  338. (equal (numberp (greatest-factor x y))
  339. (not (and (or (zerop y)
  340. (equal y 1))
  341. (not (numberp x)))))
  342. (equal (times-list (append x y))
  343. (times (times-list x)
  344. (times-list y)))
  345. (equal (prime-list (append x y))
  346. (and (prime-list x)
  347. (prime-list y)))
  348. (equal (equal z (times w z))
  349. (and (numberp z)
  350. (or (equal z (zero))
  351. (equal w 1))))
  352. (equal (greatereqp x y)
  353. (not (lessp x y)))
  354. (equal (equal x (times x y))
  355. (or (equal x (zero))
  356. (and (numberp x)
  357. (equal y 1))))
  358. (equal (remainder (times y x)
  359. y)
  360. (zero))
  361. (equal (equal (times a b)
  362. 1)
  363. (and (not (equal a (zero)))
  364. (not (equal b (zero)))
  365. (numberp a)
  366. (numberp b)
  367. (equal (sub1 a)
  368. (zero))
  369. (equal (sub1 b)
  370. (zero))))
  371. (equal (lessp (length (delete x l))
  372. (length l))
  373. (member x l))
  374. (equal (sort2 (delete x l))
  375. (delete x (sort2 l)))
  376. (equal (dsort x)
  377. (sort2 x))
  378. (equal (length (cons x1
  379. (cons x2
  380. (cons x3 (cons x4
  381. (cons x5
  382. (cons x6 x7)))))))
  383. (plus 6 (length x7)))
  384. (equal (difference (add1 (add1 x))
  385. 2)
  386. (fix x))
  387. (equal (quotient (plus x (plus x y))
  388. 2)
  389. (plus x (quotient y 2)))
  390. (equal (sigma (zero)
  391. i)
  392. (quotient (times i (add1 i))
  393. 2))
  394. (equal (plus x (add1 y))
  395. (if (numberp y)
  396. (add1 (plus x y))
  397. (add1 x)))
  398. (equal (equal (difference x y)
  399. (difference z y))
  400. (if (lessp x y)
  401. (not (lessp y z))
  402. (if (lessp z y)
  403. (not (lessp y x))
  404. (equal (fix x)
  405. (fix z)))))
  406. (equal (meaning (plus-tree (delete x y))
  407. a)
  408. (if (member x y)
  409. (difference (meaning (plus-tree y)
  410. a)
  411. (meaning x a))
  412. (meaning (plus-tree y)
  413. a)))
  414. (equal (times x (add1 y))
  415. (if (numberp y)
  416. (plus x (times x y))
  417. (fix x)))
  418. (equal (nth (nil)
  419. i)
  420. (if (zerop i)
  421. (nil)
  422. (zero)))
  423. (equal (last (append a b))
  424. (if (listp b)
  425. (last b)
  426. (if (listp a)
  427. (cons (car (last a))
  428. b)
  429. b)))
  430. (equal (equal (lessp x y)
  431. z)
  432. (if (lessp x y)
  433. (equal (t) z)
  434. (equal (f) z)))
  435. (equal (assignment x (append a b))
  436. (if (assignedp x a)
  437. (assignment x a)
  438. (assignment x b)))
  439. (equal (car (gopher x))
  440. (if (listp x)
  441. (car (flatten x))
  442. (zero)))
  443. (equal (flatten (cdr (gopher x)))
  444. (if (listp x)
  445. (cdr (flatten x))
  446. (cons (zero)
  447. (nil))))
  448. (equal (quotient (times y x)
  449. y)
  450. (if (zerop y)
  451. (zero)
  452. (fix x)))
  453. (equal (get j (set i val mem))
  454. (if (eqp j i)
  455. val
  456. (get j mem)))))))
  457. (define (add-lemma-lst lst)
  458. (cond ((null? lst)
  459. #t)
  460. (else (add-lemma (car lst))
  461. (add-lemma-lst (cdr lst)))))
  462. (define (add-lemma term)
  463. (cond ((and (pair? term)
  464. (eq? (car term)
  465. (quote equal))
  466. (pair? (cadr term)))
  467. (put (car (cadr term))
  468. (quote lemmas)
  469. (cons
  470. (translate-term term)
  471. (get (car (cadr term)) (quote lemmas)))))
  472. (else (error "ADD-LEMMA did not like term: " term))))
  473. ; Translates a term by replacing its constructor symbols by symbol-records.
  474. (define (translate-term term)
  475. (cond ((not (pair? term))
  476. term)
  477. (else (cons (symbol->symbol-record (car term))
  478. (translate-args (cdr term))))))
  479. (define (translate-args lst)
  480. (cond ((null? lst)
  481. '())
  482. (else (cons (translate-term (car lst))
  483. (translate-args (cdr lst))))))
  484. ; For debugging only, so the use of MAP does not change
  485. ; the first-order character of the benchmark.
  486. (define (untranslate-term term)
  487. (cond ((not (pair? term))
  488. term)
  489. (else (cons (get-name (car term))
  490. (map untranslate-term (cdr term))))))
  491. ; A symbol-record is represented as a vector with two fields:
  492. ; the symbol (for debugging) and
  493. ; the list of lemmas associated with the symbol.
  494. (define (put sym property value)
  495. (put-lemmas! (symbol->symbol-record sym) value))
  496. (define (get sym property)
  497. (get-lemmas (symbol->symbol-record sym)))
  498. (define (symbol->symbol-record sym)
  499. (let ((x (assq sym *symbol-records-alist*)))
  500. (if x
  501. (cdr x)
  502. (let ((r (make-symbol-record sym)))
  503. (set! *symbol-records-alist*
  504. (cons (cons sym r)
  505. *symbol-records-alist*))
  506. r))))
  507. ; Association list of symbols and symbol-records.
  508. (define *symbol-records-alist* '())
  509. ; A symbol-record is represented as a vector with two fields:
  510. ; the symbol (for debugging) and
  511. ; the list of lemmas associated with the symbol.
  512. (define (make-symbol-record sym)
  513. (vector sym '()))
  514. (define (put-lemmas! symbol-record lemmas)
  515. (vector-set! symbol-record 1 lemmas))
  516. (define (get-lemmas symbol-record)
  517. (vector-ref symbol-record 1))
  518. (define (get-name symbol-record)
  519. (vector-ref symbol-record 0))
  520. (define (symbol-record-equal? r1 r2)
  521. (eq? r1 r2))
  522. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  523. ;
  524. ; The second phase.
  525. ;
  526. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  527. (define (test n)
  528. (let ((term
  529. (apply-subst
  530. (translate-alist
  531. (quote ((x f (plus (plus a b)
  532. (plus c (zero))))
  533. (y f (times (times a b)
  534. (plus c d)))
  535. (z f (reverse (append (append a b)
  536. (nil))))
  537. (u equal (plus a b)
  538. (difference x y))
  539. (w lessp (remainder a b)
  540. (member a (length b))))))
  541. (translate-term
  542. (do ((term
  543. (quote (implies (and (implies x y)
  544. (and (implies y z)
  545. (and (implies z u)
  546. (implies u w))))
  547. (implies x w)))
  548. (list 'or term '(f)))
  549. (n n (- n 1)))
  550. ((zero? n) term))))))
  551. (tautp term)))
  552. (define (translate-alist alist)
  553. (cond ((null? alist)
  554. '())
  555. (else (cons (cons (caar alist)
  556. (translate-term (cdar alist)))
  557. (translate-alist (cdr alist))))))
  558. (define (apply-subst alist term)
  559. (cond ((not (pair? term))
  560. (let ((temp-temp (assq term alist)))
  561. (if temp-temp
  562. (cdr temp-temp)
  563. term)))
  564. (else (cons (car term)
  565. (apply-subst-lst alist (cdr term))))))
  566. (define (apply-subst-lst alist lst)
  567. (cond ((null? lst)
  568. '())
  569. (else (cons (apply-subst alist (car lst))
  570. (apply-subst-lst alist (cdr lst))))))
  571. (define (tautp x)
  572. (tautologyp (rewrite x)
  573. '() '()))
  574. (define (tautologyp x true-lst false-lst)
  575. (cond ((truep x true-lst)
  576. #t)
  577. ((falsep x false-lst)
  578. #f)
  579. ((not (pair? x))
  580. #f)
  581. ((eq? (car x) if-constructor)
  582. (cond ((truep (cadr x)
  583. true-lst)
  584. (tautologyp (caddr x)
  585. true-lst false-lst))
  586. ((falsep (cadr x)
  587. false-lst)
  588. (tautologyp (cadddr x)
  589. true-lst false-lst))
  590. (else (and (tautologyp (caddr x)
  591. (cons (cadr x)
  592. true-lst)
  593. false-lst)
  594. (tautologyp (cadddr x)
  595. true-lst
  596. (cons (cadr x)
  597. false-lst))))))
  598. (else #f)))
  599. (define if-constructor '*) ; becomes (symbol->symbol-record 'if)
  600. (define rewrite-count 0) ; sanity check
  601. ; The next procedure is Henry Baker's sharing CONS, which avoids
  602. ; allocation if the result is already in hand.
  603. ; The REWRITE and REWRITE-ARGS procedures have been modified to
  604. ; use SCONS instead of CONS.
  605. (define (scons x y original)
  606. (if (and (eq? x (car original))
  607. (eq? y (cdr original)))
  608. original
  609. (cons x y)))
  610. (define (rewrite term)
  611. (set! rewrite-count (+ rewrite-count 1))
  612. (cond ((not (pair? term))
  613. term)
  614. (else (rewrite-with-lemmas (scons (car term)
  615. (rewrite-args (cdr term))
  616. term)
  617. (get-lemmas (car term))))))
  618. (define (rewrite-args lst)
  619. (cond ((null? lst)
  620. '())
  621. (else (scons (rewrite (car lst))
  622. (rewrite-args (cdr lst))
  623. lst))))
  624. (define (rewrite-with-lemmas term lst)
  625. (cond ((null? lst)
  626. term)
  627. ((one-way-unify term (cadr (car lst)))
  628. (rewrite (apply-subst unify-subst (caddr (car lst)))))
  629. (else (rewrite-with-lemmas term (cdr lst)))))
  630. (define unify-subst '*)
  631. (define (one-way-unify term1 term2)
  632. (begin (set! unify-subst '())
  633. (one-way-unify1 term1 term2)))
  634. (define (one-way-unify1 term1 term2)
  635. (cond ((not (pair? term2))
  636. (let ((temp-temp (assq term2 unify-subst)))
  637. (cond (temp-temp
  638. (term-equal? term1 (cdr temp-temp)))
  639. ((number? term2) ; This bug fix makes
  640. (equal? term1 term2)) ; nboyer 10-25% slower!
  641. (else
  642. (set! unify-subst (cons (cons term2 term1)
  643. unify-subst))
  644. #t))))
  645. ((not (pair? term1))
  646. #f)
  647. ((eq? (car term1)
  648. (car term2))
  649. (one-way-unify1-lst (cdr term1)
  650. (cdr term2)))
  651. (else #f)))
  652. (define (one-way-unify1-lst lst1 lst2)
  653. (cond ((null? lst1)
  654. (null? lst2))
  655. ((null? lst2)
  656. #f)
  657. ((one-way-unify1 (car lst1)
  658. (car lst2))
  659. (one-way-unify1-lst (cdr lst1)
  660. (cdr lst2)))
  661. (else #f)))
  662. (define (falsep x lst)
  663. (or (term-equal? x false-term)
  664. (term-member? x lst)))
  665. (define (truep x lst)
  666. (or (term-equal? x true-term)
  667. (term-member? x lst)))
  668. (define false-term '*) ; becomes (translate-term '(f))
  669. (define true-term '*) ; becomes (translate-term '(t))
  670. ; The next two procedures were in the original benchmark
  671. ; but were never used.
  672. (define (trans-of-implies n)
  673. (translate-term
  674. (list (quote implies)
  675. (trans-of-implies1 n)
  676. (list (quote implies)
  677. 0 n))))
  678. (define (trans-of-implies1 n)
  679. (cond ((equal? n 1)
  680. (list (quote implies)
  681. 0 1))
  682. (else (list (quote and)
  683. (list (quote implies)
  684. (- n 1)
  685. n)
  686. (trans-of-implies1 (- n 1))))))
  687. ; Translated terms can be circular structures, which can't be
  688. ; compared using Scheme's equal? and member procedures, so we
  689. ; use these instead.
  690. (define (term-equal? x y)
  691. (cond ((pair? x)
  692. (and (pair? y)
  693. (symbol-record-equal? (car x) (car y))
  694. (term-args-equal? (cdr x) (cdr y))))
  695. (else (equal? x y))))
  696. (define (term-args-equal? lst1 lst2)
  697. (cond ((null? lst1)
  698. (null? lst2))
  699. ((null? lst2)
  700. #f)
  701. ((term-equal? (car lst1) (car lst2))
  702. (term-args-equal? (cdr lst1) (cdr lst2)))
  703. (else #f)))
  704. (define (term-member? x lst)
  705. (cond ((null? lst)
  706. #f)
  707. ((term-equal? x (car lst))
  708. #t)
  709. (else (term-member? x (cdr lst)))))
  710. (set! setup-boyer
  711. (lambda ()
  712. (set! *symbol-records-alist* '())
  713. (set! if-constructor (symbol->symbol-record 'if))
  714. (set! false-term (translate-term '(f)))
  715. (set! true-term (translate-term '(t)))
  716. (setup)))
  717. (set! test-boyer
  718. (lambda (n)
  719. (set! rewrite-count 0)
  720. (let ((answer (test n)))
  721. (write rewrite-count)
  722. (display " rewrites")
  723. (newline)
  724. (if answer
  725. rewrite-count
  726. #f)))))