#lang scheme
(require "patterns.ss")
(require "argument-lists.ss")
(define-struct ruleset
(name
(rules #:mutable)
namespace)
#:inspector (make-inspector))
(define (rule-print rule port write?)
(when write? (write-string "<" port))
(fprintf port "(~a ~a)"
(rule-name rule)
(ruleset-name (rule-ruleset rule)))
(when write? (write-string ">" port)))
(define-values (struct:rule
make-rule
rule?
rule-field-ref
set-rule-field!)
(make-struct-type 'rule #f 8 0 #f
(list (cons prop:custom-write rule-print))
(make-inspector)))
(define rule-name
(make-struct-field-accessor rule-field-ref 0 'name))
(define set-rule-name!
(make-struct-field-mutator set-rule-field! 0 'name))
(define rule-ruleset
(make-struct-field-accessor rule-field-ref 1 'ruleset))
(define set-rule-ruleset!
(make-struct-field-mutator set-rule-field! 1 'ruleset))
(define rule-goals
(make-struct-field-accessor rule-field-ref 2 'goals))
(define set-rule-goals!
(make-struct-field-mutator set-rule-field! 2 'goals))
(define rule-preconditions
(make-struct-field-accessor rule-field-ref 3 'preconditions))
(define set-rule-preconditions!
(make-struct-field-mutator set-rule-field! 3 'preconditions))
(define rule-actions
(make-struct-field-accessor rule-field-ref 4 'actions))
(define set-rule-actions!
(make-struct-field-mutator set-rule-field! 4 'actions))
(define rule-priority
(make-struct-field-accessor rule-field-ref 5 'priority))
(define set-rule-priority!
(make-struct-field-mutator set-rule-field! 5 'priority))
(define rule-order
(make-struct-field-accessor rule-field-ref 6 'order))
(define set-rule-order!
(make-struct-field-mutator set-rule-field! 6 'order))
(define rule-specificity
(make-struct-field-accessor rule-field-ref 7 'specificity))
(define set-rule-specificity!
(make-struct-field-mutator set-rule-field! 7 'specificity))
(define (add-rule name ruleset goals preconditions actions priority)
(let ((rule (make-rule name ruleset
goals preconditions actions
priority
(+ (length (ruleset-rules ruleset)) 1)
(length preconditions))))
(set-ruleset-rules! ruleset
(append (ruleset-rules ruleset)
(list rule)))))
(define-syntax define-ruleset
(syntax-rules ()
((define-ruleset name)
(define name
(make-ruleset 'name
'()
(current-namespace))))))
(define-syntax define-rule
(syntax-rules (<== ==>)
( (define-rule (name ruleset)
item ...)
(define-rule (name ruleset #:priority 0)
item ...))
( (define-rule (name ruleset #:priority priority)
item)
(add-rule 'name
ruleset
'(item)
'()
#f
priority))
( (define-rule (name ruleset #:priority priority)
item-1 item-2 ...)
(define-rule
"gather goals or data"
(name ruleset #:priority priority)
(item-1)
item-2 ...))
( (define-rule
"gather goals or data"
(name ruleset #:priority priority)
(goal ...))
(add-rule 'name
ruleset
'(goal ...)
'()
#f
priority))
( (define-rule
"gather goals or data"
(name ruleset #:priority priority)
(goal ...)
<== item)
(add-rule 'name
ruleset
'(goal ...)
'(item)
#f
priority))
( (define-rule
"gather goals or data"
(name ruleset #:priority priority)
(goal ...)
<== item-1 item-2 ...)
(define-rule
"gather data or actions"
(name ruleset #:priority priority)
(goal ...)
(item-1)
item-2 ...))
( (define-rule
"gather goals or data"
(name ruleset #:priority priority)
(data ...)
==> item ...)
(add-rule 'name
ruleset
'()
'(data ...)
#'(item ...)
priority))
( (define-rule
"gather goals or data"
(name ruleset #:priority priority)
(goal-or-data ...)
item-1 item-2 ...)
(define-rule
"gather goals or data"
(name ruleset #:priority priority)
(goal-or-data ... item-1)
item-2 ...))
( (define-rule
"gather data or actions"
(name ruleset #:priority priority)
(goal ...)
(data ...))
(add-rule 'name
ruleset
'(goal ...)
'(data ...)
#f
priority))
( (define-rule
"gather-data-or-actions"
(name ruleset #:priority priority)
(goal ...)
(data ...)
==> action ...)
(add-rule 'name
ruleset
'(goal ...)
'(data ...)
#'(action ...)
priority))
( (define-rule
"gather data or actions"
(name ruleset #:priority priority)
(goal ...)
(data-or-action ...)
item-1 item-2 ...)
(define-rule
"gather data or actions"
(name ruleset #:priority priority)
(goal ...)
(data-or-action ... item-1)
item-2 ...))))
(provide
define-ruleset
define-rule)
(provide/contract
(ruleset?
(-> any/c boolean?))
(make-ruleset
(-> symbol? (listof rule?) any/c ruleset?))
(ruleset-name
(-> ruleset? symbol?))
(ruleset-rules
(-> ruleset? (listof rule?)))
(set-ruleset-rules!
(-> ruleset? (listof rule?) void?))
(rule?
(-> any/c boolean?))
(make-rule
(-> symbol?
ruleset?
list?
list?
(or/c syntax? false/c)
real?
real?
real?
rule?))
(rule-name
(-> rule? symbol?))
(rule-ruleset
(-> rule? ruleset?))
(rule-goals
(-> rule? list?))
(rule-preconditions
(-> rule? list?))
(rule-actions
(-> rule? (or/c syntax? false/c)))
(rule-priority
(-> rule? real?))
(rule-order
(-> rule? real?))
(rule-specificity
(-> rule? real?))
(add-rule
(-> symbol?
ruleset?
list?
list?
(or/c syntax? false/c)
real?
void?)))