Как представить «где-то слева» в prolog?

#prolog #rule #dcg

#пролог #правило #dcg

Вопрос:

В Прологе, как представить ситуацию «где-то слева». Например, есть список «List» и два термина «X» и «Y», как представить правило: X находится где-то слева от Y в списке.

Комментарии:

1. Или вы могли бы обратиться к своему CSCI460 TA (me) за помощью. Пожалуйста, сделайте свою собственную работу.

2. О, извините, не могли бы вы сказать мне, нарушаю ли я правило курса, когда я обращаюсь за помощью подобным образом в stack overflow.

Ответ №1:

Это может быть сведено к проблеме сопоставления подпоследовательностей.

 subsequence([], _).
subsequence([X|Sub], [X|Seq]) :-
    subsequence(Sub, Seq).
subsequence(Sub, [_|Seq]) :-
    subsequence(Sub, Seq).
  

Тогда ваш запрос «слева от» будет subsequence([X, Y], List), ! .

Комментарии:

1. @user918304: если бы вы попробовали это решение, вы бы обнаружили, что оно работает так, как вы хотите; нет необходимости Y немедленно следовать X .

Ответ №2:

Вы хотите описать некоторые свойства списков. Грамматики часто являются лучшим способом решения этой проблемы.

 ... --> [].
... --> [_], ... .

?- Xs = "abc", phrase((...,[X], ..., [Y], ...), Xs).
   Xs = "abc", X = a, Y = b
;  Xs = "abc", X = a, Y = c
;  Xs = "abc", X = b, Y = c
;  false.
  

Ответ №3:

это можно сделать многими способами.
nth1(N,List,X) — это предикат, который является истинным, если N-й элемент списка равен X.

Реализация с использованием nth1 довольно проста; попробуйте решить ее, прежде чем увидеть мой код.

 left(X,Y,L):-
    nth1(NX,L,X),
    nth1(NY,L,Y),
    NX<NY.
  

Другие способы решить это с помощью append / 3:

 left(X,Y,L):-
   append(_,[X|T],L),
   member(Y,L).
  

или просто рекурсия:

 left(X,Y,[X|T]):-
   member(Y,T).
left(X,Y,[H|T]):-
   H==X,
   left(X,Y,T).
  

Ответ №4:

Если у вас уже есть предикат append / 3, вы можете использовать:

 left(A,B,S) :-
    append(_,[B,A|_],S).
  

Если вы спросите:

 ?- left(1,2,[1,2,3,4]).
false.

?- left(2,1,[1,2,3,4]).
true
  

-Leo