Prolog - 在回溯上生成交替符号:[a]; [A,B]。 [A,B,A]; [A,B,A,B]

时间:2017-01-18 19:02:05

标签: list prolog dcg

我已经把我的思绪包裹了很多,无法弄清楚。 是否可以创建一个带有回溯的脚本以这种格式生成列表:

[a]
[a,b]
[a,b,a]
[a,b,a,b]
...

我已经制作了一个可以同时产生两个元素但是我的头开始受伤试图创造一个产生" a"并且下一次" b"和下一个" a"等等。

以下是一次两个元素的脚本:

ab([a]).
ab([b,a|T]):-ab([a|T]).
ab([a,b|T]):-ab([b|T]).

3 个答案:

答案 0 :(得分:8)

在描述列表时,请始终考虑使用 DCG表示法

这样就可以非常方便地关注你想要描述的本质,而不需要那么多额外的变量和参数。

例如,考虑:

abs --> [a], abs_rest.

abs_rest --> [].
abs_rest --> [b], ( [] | abs ).

示例查询和回答:

?- phrase(abs, ABs).
ABs = [a] ;
ABs = [a, b] ;
ABs = [a, b, a] ;
ABs = [a, b, a, b] ;
ABs = [a, b, a, b, a] ;
ABs = [a, b, a, b, a, b] .

有关这种方便的形式主义的更多信息,请参阅

答案 1 :(得分:4)

我同意@mat应尽可能使用 来解决这类问题。

这是一套不同的规则。

abs --> [a].
abs --> [a,b].
abs --> [a,b], abs.

?- phrase(abs, Ls).
Ls = [a] ;
Ls = [a, b] ;
Ls = [a, b, a] ;
Ls = [a, b, a, b] ;
Ls = [a, b, a, b, a] ;
Ls = [a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a] ;
Ls = [a, b, a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a, b, a] 

有趣的是,这些规则是从这种变化开始的

abs2 --> [].
abs2 --> [a].
abs2 --> [a,b], abs2.

?- phrase(abs2, Ls).
Ls = [] ;
Ls = [a] ;
Ls = [a, b] ;
Ls = [a, b, a] ;
Ls = [a, b, a, b] ;
Ls = [a, b, a, b, a] ;
Ls = [a, b, a, b, a, b] ;
Ls = [a, b, a, b, a, b, a] ;
Ls = [a, b, a, b, a, b, a, b] 

这是Using Definite Clause Grammars in SWI-Prolog

的练习之一

如果您不想使用DCG,那么我同意@mat并建议您使用listing/1以标准的Prolog语法查看DCG。

listing(abs).

abs([a|A], A).
abs([a, b|A], A).
abs([a, b|A], B) :-
        abs(A, B).

listing(abs2).  

abs2(A, A).
abs2([a|A], A).
abs2([a, b|A], B) :-
        abs2(A, B).

正如普通Prolog规则一样,它们可以这样使用:

abs(X,[]).
X = [a] ;
X = [a, b] ;
X = [a, b, a] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a] ;
X = [a, b, a, b, a, b] ;
X = [a, b, a, b, a, b, a]

abs2(X,[]).
X = [] ;
X = [a] ;
X = [a, b] ;
X = [a, b, a] ;
X = [a, b, a, b] ;
X = [a, b, a, b, a] ;
X = [a, b, a, b, a, b] 

答案 2 :(得分:1)

你写的谓词过于笼统:

{
  "_source": [
    "name"
  ],
  "query": {
    "nested": {
      "path": "experience",
      "query": {
        "bool": {
          "must_not": {
            "exists": {
              "field": "experience.resignation_date"
            }
          }
        }
      }
    }
  }
}

原因是以下规则

?- ab([b,a]).
true

可以说你描述了一个中间结果,它不能解决你的实际问题。要解决此问题,您可以声明ab([b,a|T]) :- ab([a|T]). 序列以ab开头,其余字母为a序列,其中ba序列再次以{{定义1}}序列:

ba

或者,您可以将ab视为状态机  每当最后一个元素为ab([a]). ab([a|Xs]) :- ba(Xs). ba([b]). ba([b|Xs]) :- ab(Xs). 时生成abs,反之亦然。  如果我们引入一个额外的参数来追踪历史,我们得出:

a

现在我们将b序列定义为最后添加abs(a,[a]). abs(b,[b]). abs(a,[a|Xs]) :- abs(b,Xs). abs(b,[b|Xs]) :- abs(a,Xs). 的序列:

ab

玩得开心:)