| Deutsch English Français Italiano |
|
<v7q0m7$1jrar$1@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!2.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: "B. Pym" <Nobody447095@here-nor-there.org>
Newsgroups: comp.lang.lisp,comp.lang.scheme
Subject: Re: Non-determinism
Date: Wed, 24 Jul 2024 04:41:59 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 154
Message-ID: <v7q0m7$1jrar$1@dont-email.me>
References: <v7pboq$1d67r$1@dont-email.me> <v7peea$1djes$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Injection-Date: Wed, 24 Jul 2024 06:41:59 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="dc013996b5bb46648d47418209f67001";
logging-data="1699163"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18Hya/Rt1Tj4/o2APooeoDh"
User-Agent: XanaNews/1.18.1.6
Cancel-Lock: sha1:pc4wnI7x3QTGREHJZZ3lX2XHKb0=
Bytes: 5046
B. Pym wrote:
> Problem 4.42 in SICP
>
> Five school girls took an exam. As they think thattheir
> parents are too much interested in their score, they promise
> that they write one correct and one wrong informations to
> their parents. Followings are parts of their letters
> concerning their result:
>
> Betty: Kitty was the second and I third.
> Ethel: I won the top and Joan the second.
> Joan: I was the third and poor Ethel the last.
> Kitty: I was the second and Mary the fourth.
> Mary: I was the fourth. Betty won the top.
>
> Guess the real order of the five school girls.
Shorter:
(define (xor a b)
(if a (not b) b))
(define (either a m b n lst)
(xor (= m (amb-index a lst))
(= n (amb-index b lst))))
(define (girls-exam)
(amb-set-of
(let* ((girls '(kitty betty ethel joan mary))
(answer (amb-permutation girls)))
(amb-assert (either 'kitty 2 'betty 3 answer))
(amb-assert (either 'kitty 2 'mary 4 answer))
(amb-assert (either 'mary 4 'betty 1 answer))
(amb-assert (either 'ethel 1 'joan 2 answer))
;; Next line not needed.
;; (amb-assert (either 'joan 3 'ethel 5 answer))
answer)))
(girls-exam)
===>
((kitty joan betty mary ethel))
Supporting code:
;; Modified from the excellent code found here
;; http://www.shido.info/lisp/scheme_amb_e.html
;; and written by
;; SHIDO, Takafumi
;; [ SHIDO's comment ]
;; Notice that you cannot use the code shown in this chapter if
;; the searching path has loops. See SICP 4.3. for detailed
;; information on this matter.
;;; This function is re-assigned in `amb-choose' and `amb-fail' itself.
(define amb-fail #f)
;;; function for nondeterminism
(define (amb-choose . ls)
(if (null? ls)
(amb-fail)
(let ((fail0 amb-fail))
(call/cc
(lambda (cc)
(set! amb-fail
(lambda ()
(set! amb-fail fail0)
(cc (apply amb-choose (cdr ls)))))
(cc (car ls)))))))
;;; nondeterminism macro operator
(define-syntax amb
(syntax-rules ()
((_) (amb-fail))
((_ a) a)
((_ a b ...)
(let ((fail0 amb-fail))
(call/cc
(lambda (cc)
(set! amb-fail
(lambda ()
(set! amb-fail fail0)
(cc (amb b ...))))
(cc a)))))))
;;; returning all possibilities
(define-syntax amb-set-of
(syntax-rules ()
((_ s)
(let ((acc '()))
(amb (let ((v s))
(set! acc (cons v acc))
(amb-fail))
(reverse acc))))))
;; (reverse! acc))))))
;;; if not bool backtrack
(define (amb-assert bool)
(or bool (amb)))
;;; returns arbitrary number larger or equal to n
(define (amb-integer-starting-from n)
(amb n (amb-integer-starting-from (+ 1 n))))
;;; returns arbitrary number between a and b
(define (amb-number-between a b)
(let loop ((i a))
(if (> i b)
(amb)
(amb i (loop (+ 1 i))))))
;; (amb i (loop (1+ i))))))
;;; write following at the end of file
;;; initial value for amb-fail
(call/cc
(lambda (cc)
(set! amb-fail
(lambda ()
(cc 'no-choice)))))
(define (amb-all-different? . ls)
(let loop ((obj (car ls)) (ls (cdr ls)))
(or (null? ls)
(and (not (member obj ls))
(loop (car ls) (cdr ls))))))
;; [Written by me.]
(define (amb-permutation lst)
(let ((tmp (map (lambda(_) (apply amb-choose lst))
lst)))
(amb-assert (apply amb-all-different? tmp))
tmp))
;; First position is numbered 1. [Written by me.]
(define (amb-index x xs)
(let ((tail (member x xs)))
(and tail (- (length xs) -1 (length tail)))))
;; Takes into consideration that y may appear
;; more than once. [Written by me.]
(define (amb-before? x y lst)
(let ((a (member x lst)))
(and a
(let ((b (member y lst)))
(or (not b)
(> (length a) (length b)))))))