質問
私は演習を行っており、簡単な結婚相談所のマッチング システムを作成する必要があります。現在、各人は 1 つの趣味を持っており、趣味はアクティブと非アクティブによって分類されており、2 つの趣味が一致し、2 人に異性がいる場合、結婚相談所はこれらが一致すると判断します。
したがって、現在は複数の趣味を許可できるシステムが必要ですが、これについては頭が混乱しているようです。
私が持っているものは次のとおりです。
(deftemplate MAIN::person
(slot name)
(slot age)
(multislot hobby)
(slot town)
(slot sex))
(person (name "Jane")
(age 25)
(hobby fashion gardening)
(town montrose)
(sex female))
(deffacts hobby_types "Hobby categories"
(hobby_type gardening active)
(hobby_type swinging active)
(hobby_type reading inactive)
(hobby_type fashion inactive)
)
(defrule compatible_hobbies
(opposite_sex ?name1 ?name2)
(person (name ?name1) (hobby ?hobby1))
(person (name ?name2) (hobby ?hobby2))
(hobby_type ?hobby1 ?type)
(hobby_type ?hobby2 ?type)
=>
(assert (hobbies_match ?name1 ?name2))
)
まず最初に、マルチスロット フィールドを正しく宣言できますか?また、ある人の趣味のいずれかと一致するように、compatibility_hobbies ルールを調整するにはどうすればよいでしょうか?
解決
マルチスロット趣味は正しく宣言されています。しかし、あなたのルールは趣味を正しく一致させず、ジェーンがジェーンと互換性があることを示す同じ事実を同じ事実に一致させることになります。実際、ルールが事実と一致する場合、その人物の事実のデカルト積 (または多数の望ましくない一致) が生成されます。
ルールを次のように変更しました。
(defrule compatible_hobbies
(person (name ?n1) (hobby $? ?h1 $?))
(person (name ?n2) (hobby $? ?h1 $?))
(hobby_type ?h1 ?x)
(test (neq ?n1 ?n2))
=>
(assert (hobbies_compatible ?n1 ?n2))
)
したがって、次のような2人の人物の事実を主張すると、
(person (name "Jane") (hobby blah1 gardening blah2))
そして (person (name "Jim") (hobby blah3 gardening blah4))
次に、ルールが起動し、ファクト (hobbies_compatibility Jim Jane) がアサートされます (ファクト (hobbies_compatibility "Jim" "Jane") も同様)。
ワイルドカード $?変数は、目的の一致する趣味の前後の一連の記号と一致します。あなたの異性という事実も、おそらく事実ではなくテストであるべきです。