[racket] Macros baffle me

From: Eduardo Costa (edu500ac at gmail.com)
Date: Thu May 1 21:01:01 EDT 2014

In general, I don't have problems with macros in Common Lisp or in Scheme.
However, macros in Racket baffle me. I simply cannot figure out how
syntax->datum, syntax->list and datum->syntax work. In any case, I need a
macro to prove that a proposition is a tautology. Below you will find what
I did. There are a few examples on how to run the program. What bothers me
in this program is the need of calling ev on a quoted version of the fm wff:

(define (ev xs)
  (eval `(with-vars ,(free-vars xs) ,xs)))

(define-syntax-rule (tauta fm) (ev 'fm))

I suppose that one can avoid calling eval by a judicious use of
syntax->datum, syntax->list and datum->syntax. I would appreciate
suggestions to improve the program.



#lang racket

;; (with-vars (P Q ) (or Q (or (not P) P))) builds:
;;   (for/and [(P (in-list (list #t #f)))] (for/and [(Q (in-list (list #t
#f)))] (or Q (or (not P) P))))
(define-syntax with-vars
  (syntax-rules ()
    ((with-vars (v) cm) (for/and [(v (in-list (list #t #f)))] cm))
    ((with-vars (w v ...) cm)
     (for/and [(w (in-list (list #t #f)))] (with-vars (v ...) cm))) ))

;; flattens a list; for instance, (or (not P) Q) becomes (or not P Q)
(define (flatten lst)
  (cond ((null? lst) '())
        ((pair? (car lst)) (append (flatten (car lst)) (flatten (cdr lst))))
        (else
          (cons (car lst) (flatten (cdr lst))))))

;; gets the variables in a wff. For instance (free-vars ' (or Q (or (not P)
P)))
;; produces (P Q)
(define (free-vars s)
  (let loop [(x (flatten s))]
    (cond [(null? x) x]
          [(member (car x) '(and or then -> <-> not
                                 equiv display displayln)) (loop (cdr x))]
          [(member (car x) (cdr x)) (loop (cdr x))]
          [else (cons (car x) (loop (cdr x)))] )))

(define (then x y) (or y (not x)))

(define (equiv x y) (and (then x y) (then y x)))

;; I want to avoid this step. (ev '(or Q (or (not P) P)))) gets the list
;; (P Q) of free variables, builds and evals (with-vars (P Q) (or Q (or
(not P) P))).
(define (ev xs)
  (eval `(with-vars ,(free-vars xs) ,xs)))

(define-syntax-rule (tauta fm) (ev 'fm))

; (tauta (or (then P Q) (then Q (not P))))
; (tauta (or P (not P))) ; excluded middle
; (tauta (or (and P Q) (or (not P) (not Q))))
;  (tauta (equiv (then P Q) (then (not Q) (not P)))) ;equiv
; (tauta (then (and (then (not A) B) (then (not A) (not B))) A)) ;reductio
ad absurdum
; (tauta (equiv (not (and A B)) (or (not A) (not B)))) ; De Morgan's law
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140501/9b29eae0/attachment.html>

Posted on the users mailing list.