【问题标题】:Prolog: pattern matching within a listProlog:列表中的模式匹配
【发布时间】:2015-03-06 06:12:54
【问题描述】:

定义一个关系 xyz(X),如果 X 是一个 xyz 序列,则该关系为真。 xyz 序列是由数字 0 或数字 1 后跟两个其他 xyz 序列组成的序列。

一些xyz序列:

xyz([0]).
xyz([1,0,1,0,0]).

并且,以下是被视为 xyz 序列:

xyz([1,1,0,0]).
xyz([0,1,0]).
xyz([1,1,0]).
xyz([1,0,1,1,1,1,1,0,1]).

有人可以帮我解决这个问题吗?

【问题讨论】:

标签: prolog dcg


【解决方案1】:

最简单的就是写一个DCG。有关详细介绍,请参阅this tutorial。您可以逐字逐句写下问题陈述以获得解决方案:

xyz --> [0].
xyz --> [1], xyz, xyz.

你需要phrase:

?- phrase(xyz, [1,0,1,0,0]).

这个解决方案留下了一个选择点。

【讨论】:

  • 我以前不知道DCG,它看起来像一些强大的东西。感谢您分享这些信息。我将如何在 xyz(A) 谓词中实施这些 DCG 规则,以便获得“真”,我不必输入 phrase(xyz, [0])' and instead I can query with xyz([0]`?
  • 没关系,这很简单。 xyz(A):- phrase(xyz,A). 在那些 DCG 规则之后。看起来不错,对吧?
  • @am3decoy 是的,如果您不想在谓词中自己调用phrase,那就差不多了。是否要明确调用 phrase 或是否要隐藏它取决于您:我更喜欢直接使用它,但这只是个人喜好问题。
  • @am3decoy 请记住,DCG 与模式匹配并不完全相同:您编写的是语法,而不仅仅是模式(如在正则表达式中)。
  • 是的,我会进一步调查。嘿,如果你不介意,你认为你可以看看我的其他问题之一吗?感谢这里的一位用户,我已经弄清楚了,我只需要知道如何反转列表。我尝试了不同的方法来反转列表,但我没有成功。代码是xyz(X, Y):- f(X, Z,_) -> findall([A|B], (member(A, Z), xyz(A, B)), L), flatten(L, F), sort(F, Y); Y = []. 我只需要反向输出的列表。 stackoverflow.com/questions/28845949/recursion-in-prolog/…
【解决方案2】:

如此简单的语法非常适合理解为 DCG 提供动力的机制(尽管是简化的):

seq(S) :- seq(S, []).

seq([0|R], R).
seq([1|T], R) :- seq(T, Q), seq(Q, R).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 2018-10-01
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多