This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Constant terms in macro parameters...

3 posts · 6347 views

Greetings, this is not homework, but I felt it would be here the best place to post...

I'm trying to program a common-lisp macro (sbcl) to set the syntax for defining a rule in a rule-based system.
My goal is to allow users to specify rules in a syntax like this:
(defrule  "name of the rule"
    :when   (s-expression 1)
            (s-expression 2)
            ...
            (s-expression n)
    :perform
            (s-expresion 1)
            (s-expression 2)
            ...
            (s-expression m) )
And I face two problems I currently don't know how to solve:

First, is there an intelligent way to include the constant terms (:when and :perform) without adding them as specific parameters to the macro?

Second, How do I accept two chunks of unknown number of s-expressions without forcing the user to delimit all the lhs and rhs expressions in a list?

Although I have reviewed many codes with rule-based systems (CL-mycyn, Leibniz, Lisa, etc) the only problem seems to be my inexperience with macros and CL in general...
Any help will be greatly appreciated...

Thanks in advance...

Re: Constant terms in macro parameters...

(defmacro defrule (name &rest rest)
  ...)
Now name will be "name of the rule" and rest will be (:when (s-expression 1) ... :perform (s-expresion 1) ...)
Your macro can iterate and collect and do all sorts of things and you look for :when and :perform to switch mode.
I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p

Re: Constant terms in macro parameters...

Seems like it might be easiest—if not the right thing in your case—to just look for any keywords to delimit the associated expressions, rather than specific keywords. Sticking them in a property list makes the rule definition a bit more tractable:
(defun rule-definition-plist (body)
  (loop with plist for (keyword . tail) = body
        until (endp body) finally (return plist)
        do (check-type keyword keyword)
           (setq body (member-if #'keywordp tail))
           (let ((key-expressions (ldiff tail body)))
             (setf (getf plist keyword) key-expressions))))
Of course, the plist will tend to be in the reverse order:
? (rule-definition-plist
   '(:when   (when-expression 1)
             (when-expression 2)
     :perform
             (perform-expression 1)
             (perform-expression 2)))
(:PERFORM ((PERFORM-EXPRESSION 1) (PERFORM-EXPRESSION 2))
 :WHEN ((WHEN-EXPRESSION 1) (WHEN-EXPRESSION 2)))