基于CLIPS编写defrule规则,从student模板计算输出学生年龄
计算CLIPS学生模板中年龄的规则实现
Got it, let's tackle this problem step by step. You already have your student template set up and some asserted student facts, so we just need to write a rule that calculates each student's age based on their god_rozhdeniya (birth year) slot.
First, let's recap your existing template for reference:
(deftemplate student (multislot fio (type SYMBOL)(cardinality 1 3)) (slot den_rozhdeniya (type INTEGER)) (slot mecyaz_rozhdeniya (type SYMBOL)) (slot god_rozhdeniya (type INTEGER)) (multislot data_postupleniya (type SYMBOL NUMBER)) (slot facultet (default fit)(type SYMBOL)) (slot gruppa (type SYMBOL INTEGER)) (multislot adress (type SYMBOL INTEGER)) (multislot telefon (type NUMBER)) (slot sredniy_ball(range 0 10) (type INTEGER FLOAT)) )
Basic Age Calculation (Year-Only)
This rule will calculate age by subtracting the student's birth year from the current system year, and print the result alongside the student's full name for clarity:
(defrule calculate-student-age ; Match any student fact, bind birth year and full name slots ?student <- (student (fio ?first ?middle ?last) (god_rozhdeniya ?birth-year) ) => ; Extract current year from system date (current-date returns a string like "Thu Oct 17 2024") (bind ?current-year (str-to-int (sub-string 7 11 (current-date)))) ; Calculate age as current year minus birth year (bind ?age (- ?current-year ?birth-year)) ; Print the result to the console (printout t "Student: " ?first " " ?middle " " ?last " | Age: " ?age crlf) )
Breakdown of the rule:
?student <- (student ...): Matches any assertedstudentfact, binds the entire fact to?student, and extracts the full name (fio) and birth year (god_rozhdeniya) into variables.(bind ?current-year ...): Retrieves the current date string, extracts the 4-digit year (positions 7-11), and converts it to an integer.(bind ?age (- ?current-year ?birth-year)): Computes the age using simple year subtraction.printout t ...: Outputs the student's name and calculated age to the CLIPS console.
Precise Age Calculation (Accounting for Birthday)
If you want a more accurate age that checks whether the student has had their birthday this year (using den_rozhdeniya and mecyaz_rozhdeniya), use this enhanced rule:
(defrule calculate-precise-student-age ?student <- (student (fio ?first ?middle ?last) (den_rozhdeniya ?birth-day) (mecyaz_rozhdeniya ?birth-month) (god_rozhdeniya ?birth-year) ) => ; Get current date components (bind ?current-date-str (current-date)) (bind ?current-month (sub-string 4 7 ?current-date-str)) (bind ?current-day (str-to-int (sub-string 8 10 ?current-date-str))) (bind ?current-year (str-to-int (sub-string 7 11 ?current-date-str))) ; Calculate base age (bind ?age (- ?current-year ?birth-year)) ; Adjust age if birthday hasn't occurred yet this year (if (or (str-compare ?birth-month ?current-month) (and (eq ?birth-month ?current-month) (> ?birth-day ?current-day)) ) then (bind ?age (- ?age 1)) ) ; Print precise age (printout t "Student: " ?first " " ?middle " " ?last " | Precise Age: " ?age crlf) )
Key additions here:
- Extracts current month and day from the system date string.
- Compares the student's birthday month/day to the current date. If the birthday hasn't happened yet this year, subtracts 1 from the base age to reflect the actual current age.
内容的提问来源于stack exchange,提问作者Iulia
相关产品推荐
相关产品推荐

