clipsexpert-system

Comparing contents of 2 lists with values not ordered the same


I have these templates,

(deftemplate classroom
    (slot classroom_number (type INTEGER))
    (multislot students (type SYMBOL))
)

(deftemplate students_to_classroom_lookup
    (multislot students (type SYMBOL))
)

and these facts which represent classrooms and students belonging to that classroom.

(deffacts classrooms
    (classroom (classroom_number 1) (students Paul Lucy Peter Sebastian))
    (classroom (classroom_number 2) (students Peter Paul Lucy Sebastian Arthur))
    (classroom (classroom_number 3) (students Paul Lucy Peter))
    (classroom (classroom_number 4) (students Lucy Peter Paul))
)

Then I have this fact, that follows the "students_to_classroom_lookup" template and is entered by keyboard while the program is running.

(students_to_classroom_lookup (students Paul Peter Sebastian Lucy))

I want to find the classroom number that has exactly these and only these students.

Please note that content of,

(students_to_classroom_lookup (students Paul Peter Sebastian Lucy))

is based on user input, in another run of the program the contents of "students" could be Paul Sebastian Lucy Peter or just Lucy Peter Paul.

I have tried this rule:

(defrule match_classroom_and_students
    (classroom (classroom_number ?number) (students $?students))
    (students_to_classroom_lookup (students $?students_lookup&:(subsetp $?students $?students_lookup)))
=>
    (printout t "Classroom number " ?number crlf)
)

Output:

Classroom number 1
Classroom number 3
Classroom number 4

Expected output:

Classroom number 1

I appreciate all help.


Solution

  • For an exact match of sets A and B, A must be a subset of B and B must be a subset of A:

    (defrule match_classroom_and_students
        (classroom (classroom_number ?number) (students $?students))
        (students_to_classroom_lookup (students $?students_lookup&:(subsetp $?students $?students_lookup)
                                                                 &:(subsetp $?students_lookup $?students)))
    =>
        (printout t "Classroom number " ?number crlf)
    )