Деконструкция с помощью переменных в заголовочных пунктах (Пролог) - PullRequest
2 голосов
/ 27 марта 2019

В настоящее время я использую SWI-Prolog для написания кода.Когда я использовал Prolog несколько лет назад, я мог поклясться, что смог установить для имен переменных значение «deconstructions» в заголовке предложения, но сейчас мне кажется, что оно работает неправильно (по крайней мере, в SWI-Prolog).

Игрушечный глупый пример:

    example(X = [Row|Rows]) :-
      do_something_with_x(X), 
      do_something_with_row(Row),
      ...

Я хочу назвать его, например, example( [1,2,3] ), и я хочу, чтобы и X, и [Row|Rows] были сопоставлены с одним и тем же аргументом предиката, а именно с первым аргументом (здесь, [1,2,3]), в теле предиката.

Кто-нибудь знает, возможно ли это?

Ответы [ 3 ]

4 голосов
/ 27 марта 2019

Действительно, это та функциональность, которая отсутствует в Прологе (в Хаскеле она называется «как шаблоны»; в foo( x@(a:b) ) = ... x относится к целому, в то время как a и b относятся к его частям). ).

Самое близкое, что вы можете сделать, это

pred(X) :- X = [A|B], 
    ... .

но также

pred(X, [A|B]) :- 
    ... . 

, в то время как всегда вызывая его с тем же самым используемым значением дважды : Z = ... , pred(Z, Z), ....

Продолжая эту идею, вы могли бы на самом деле определить

pred( X = [A|B], ... ) :- ... .

, как вы хотели, и позаботьтесь о том, чтобы всегда называли это так: Z = ... , pred( Z = Z , ...). Вы можете даже определить некоторые мета-предикаты, чтобы сделать этот перевод автоматическим, например

call_at( Pred, Arg ) :- call(Pred, Arg = Arg).

Сам = здесь синтаксический , и его протокол использования - это то, что придает ему особое значение, то есть семантика. На языке Лисп термины Пролога всегда неоценимы, символичны.

2 голосов
/ 27 марта 2019

Вы всегда можете написать:

example([Row|Rows]) :-
  do_something_with_x([Row|Rows]),
  do_something_with_row(Row),
  ...
0 голосов
/ 27 марта 2019

Вот глупый кусок кода, который просто печатает свои аргументы.Он делает это, чтобы показать, каковы аргументы и раздражать пуристов:

example(X = [H|T]) :-
    format("X: ~w; H: ~w; T: ~w~n", [X, H, T]).

И теперь вы можете использовать это:

?- example(List = [a,b,c]).
X: _9150; H: a; T: [b,c]
true.

?- example(foo = [bar|baz]).
X: foo; H: bar; T: baz
true.

?- example(X).
X: _8700; H: _8706; T: _8708
X =  (_8700=[_8706|_8708]).

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

...