在子句头中使用var解构(Prolog)

时间:2019-03-27 01:50:02

标签: prolog pattern-matching

我目前正在使用SWI-Prolog编写一些代码。多年前,当我使用Prolog时,我可以发誓我可以在子句头中将变量名设置为“解构”,但现在看来对我来说不正确(至少在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 个答案:

答案 0 :(得分:4)

实际上,这是Prolog中缺少的功能(在Haskell中,它称为“原样”;在foo( x@(a:b) ) = ...中,x指的是整个,而a和{ {1}}参见其部分)。

您最能做的是

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). 本身是 syntactic ,其使用协议为其赋予了特殊的含义,即语义。用Lisp的话来说,Prolog的术语始终是未经评估的,象征性的。

答案 1 :(得分:2)

您可以随时写:

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

答案 2 :(得分:0)

这是一段愚蠢的代码,只显示其参数。这样做是为了表明论点是什么,并激怒纯粹主义者:

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]).

以此类推。玩吧。但是仍然需要说明您的程序真正想要实现的目标。