Сопоставление двух векторов с одинаковыми элементами, но не упорядоченными - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь написать общее правило, которое активируется, когда присутствуют два факта, подобных этим:

(Vector v1 3 4 5) (Вектор v2 1 3 10 15 5 2 4)

(Элементы 4 5 3)

Итак, моя проблема в том, что я не знаю, как сопоставить ВСЕ неупорядоченные элементы в векторе, чтобы применить правило.

Я хочу, чтобы правило активировалось, только когда ВСЕ элементы из Элементов присутствуют, не принимая во внимание, если они следуют в том же порядке.

Мне не удалось этого добиться, поэтому я прошу помощи.

Примеры правил, не делающих то, что я хочу:

(defrule Equal

    (Elements $?x)

    (Vector ?name $?y)

    (test (member$ $?x $?y))

    =>

    (printout t ?name crlf)
)

* Проблема этого в том, что он срабатывает, когда оба поля пусты, и в основном, когда в? Y содержится единственный член? X, но я хочу, чтобы правило запускалось, когда ВСЕ элементы в? X находятся в? Y .

Я тоже пытался использовать этот более простой:

(defrule Equal

    (Elements $? $?x $?)

    (Vector ?name $? $?y $?)

    =>

    (printout t ?name crlf)
)

Но в этом случае правило активируется только тогда, когда элементы абсолютно одинаковы и упорядочены одинаково, но я хочу иметь гибкость элементов, не упорядочивая их точно так, как они отображаются в векторе.

1 Ответ

0 голосов
/ 02 мая 2019

Используйте функцию subsetp вместо member $ :

         CLIPS (6.31 4/1/19)
CLIPS> 
(defrule equal
   (elements $?elements)
   (test (> (length$ ?elements) 0))
   (vector ?name $?values)
   (test (subsetp ?elements ?values))
   =>
   (printout t ?name crlf))
CLIPS> 
(assert (vector v1 3 4 5)
        (vector v2 1 3 10 15 5 2 4)
        (vector v3 4 5 7 2)
        (elements 4 5 3))
<Fact-4>
CLIPS> 
(agenda)
0      equal: f-4,f-2
0      equal: f-4,f-1
For a total of 2 activations.
CLIPS> (run)
v2
v1
CLIPS>

Вы также можете сделать это без вызова функции:

CLIPS> (clear)
CLIPS> 
(defrule equal
   (elements ? $?)
   (vector ?name $?list)
   (forall (elements $? ?v $?)
           (vector ?name $? ?v $?))
   =>
   (printout t ?name crlf))
CLIPS> 
(assert (vector v1 3 4 5)
        (vector v2 1 3 10 15 5 2 4)
        (vector v3 4 5 7 2)
        (elements 4 5 3))
<Fact-4>
CLIPS> (agenda)
0      equal: f-4,f-2,*
0      equal: f-4,f-1,*
For a total of 2 activations.
CLIPS> (run)
v2
v1
CLIPS>
...