CLIPS 比较 2 个日期

CLIPS compare 2 dates

我正在尝试比较 2 个日期,看看一个人是否超过 25 岁。我尝试绑定一个变量来减去当前日期和他的生日,然后将变量与25进行比较:

(deftemplate data
  (multislot current_date (type INTEGER))
)
(deffacts today
      (data (current_date 12 4 2018))
    )
(deftemplate driver
  (multislot name)
  (multislot dateBorn)
)

(deffacts drivers
  (driver (name Daniel Silva)(dateBorn 3 4 1985))
  (driver (name Carlos Santos)(dateBorn 3 4 2000))
)

(defrule cantDrive
  (driver(dateBorn $? ?age))
  (data (current_date $? ?date))
  (bind ?data (- ?age ?date))
  (test(< ?data 25))
  =>
  (printout t "He is younger than 25" crlf)
)

上面的代码没有运行,我不明白为什么。有没有什么操作不对?有没有办法比较两个日期?例如,我出生于 26/06/1997,如果我需要至少 25 岁才能租车,我该如何确认? 我可以设置当前日期。

         CLIPS (6.31 2/3/18)
CLIPS> 
(deffunction current-date ()
   (bind ?lt (local-time))
   (format nil "%04d-%02d-%02d" (nth$ 1 ?lt) (nth$ 2 ?lt) (nth$ 3 ?lt)))
CLIPS>    
(deffunction is-leap-year (?year)
   (if (= (mod ?year 400) 0) then (return TRUE))
   (if (= (mod ?year 100) 0) then (return FALSE))
   (if (= (mod ?year 4) 0) then (return TRUE))
   (return FALSE))
CLIPS> 
(defglobal ?*days-before-month* =           (create$ 0 31 59 90 120 151 181 212 243 273 304 334))
CLIPS> (defglobal ?*days-before-month-leap-year* = (create$ 0 31 60 91 121 152 182 213 244 274 305 335))
CLIPS> 
(deffunction days-from-year-begin (?date)
   (bind ?year (string-to-field (sub-string 1 4 ?date)))
   (bind ?month (string-to-field (sub-string 6 7 ?date)))
   (bind ?day (string-to-field (sub-string 9 10 ?date)))
   (if (is-leap-year ?year)
      then
      (return (+ (nth$ ?month ?*days-before-month-leap-year*) ?day))
      else
      (return (+ (nth$ ?month ?*days-before-month*) ?day))))
CLIPS> 
(deffunction days-until-year-end (?date)
   (bind ?year (string-to-field (sub-string 1 4 ?date)))
   (bind ?month (string-to-field (sub-string 6 7 ?date)))
   (bind ?day (string-to-field (sub-string 9 10 ?date)))
   (if (is-leap-year ?year)
      then
      (return (- 366 (+ (nth$ ?month ?*days-before-month-leap-year*) ?day)))
      else
      (return (- 365 (+ (nth$ ?month ?*days-before-month*) ?day)))))
CLIPS> 
(deffunction date-days-diff (?date1 ?date2)
   (bind ?year1 (string-to-field (sub-string 1 4 ?date1)))
   (bind ?year2 (string-to-field (sub-string 1 4 ?date2))) 
   (if (= ?year1 ?year2)
      then
      (return (- (days-from-year-begin ?date1) (days-from-year-begin ?date2))))
   (if (> ?year1 ?year2)
      then
      (bind ?negate FALSE)
      else
      (bind ?negate TRUE)
      (bind ?temp ?date1)
      (bind ?date1 ?date2)
      (bind ?date2 ?temp)
      (bind ?temp ?year1)
      (bind ?year1 ?year2)
      (bind ?year2 ?temp))
   (bind ?day-count (+ (days-until-year-end ?date2) (days-from-year-begin ?date1)))
   (loop-for-count (?year (+ ?year2 1) (- ?year1 1)) do
      (if (is-leap-year ?year)
         then (bind ?day-count (+ ?day-count 366))
         else (bind ?day-count (+ ?day-count 365))))
   (if ?negate
      then 
      (return (- 0 ?day-count))
      else
      (return ?day-count)))
CLIPS> 
(deffunction date-years-diff (?date1 ?date2)
   (bind ?year1 (string-to-field (sub-string 1 4 ?date1)))
   (bind ?year2 (string-to-field (sub-string 1 4 ?date2))) 
   (if (= ?year1 ?year2)
      then
      (return 0))
   (if (> ?year1 ?year2)
      then
      (bind ?negate FALSE)
      else
      (bind ?negate TRUE)
      (bind ?temp ?date1)
      (bind ?date1 ?date2)
      (bind ?date2 ?temp))
   (bind ?year1 (string-to-field (sub-string 1 4 ?date1)))
   (bind ?year2 (string-to-field (sub-string 1 4 ?date2))) 
   (bind ?month1 (string-to-field (sub-string 6 7 ?date1)))
   (bind ?month2 (string-to-field (sub-string 6 7 ?date2))) 
   (bind ?day1 (string-to-field (sub-string 9 10 ?date1)))
   (bind ?day2 (string-to-field (sub-string 9 10 ?date2))) 
   (bind ?years (- ?year1 ?year2))
   (if (= ?month1 ?month2)
      then
      (if (< ?day1 ?day2)
         then
         (bind ?years (- ?years 1)))
      else
      (if (< ?month1 ?month2)
         then
         (bind ?years (- ?years 1))))

   (if ?negate
      then (return (- 0 ?years))
      else (return ?years)))
CLIPS>       
(deftemplate driver
   (slot name)
   (slot dateBorn))
CLIPS> 
(deffacts drivers
   (driver (name "Daniel Silva") (dateBorn "1985-03-04"))
   (driver (name "Carlos Santos") (dateBorn "2000-03-04")))
CLIPS> 
(defrule cantDrive
  (driver (name ?name) (dateBorn ?born))
  (test (< (date-years-diff (current-date) ?born) 25))
  =>
  (printout t ?name " is younger than 25" crlf))
CLIPS> (reset)
CLIPS> (run)
Carlos Santos is younger than 25
CLIPS>