【问题标题】:Using list in Prolog DCG在 Prolog DCG 中使用列表
【发布时间】:2017-03-07 16:47:46
【问题描述】:

我正在尝试将 Prolog 谓词转换为 DCG 代码。即使我熟悉语法语言,我也很难理解 DCG 如何处理列表以及我应该如何使用它。

其实这是我的谓词:

cleanList([], []).
cleanList([H|L], [H|LL]) :-
    number(H),
    cleanList(L, LL),
    !.
cleanList([_|L], LL) :-
    cleanList(L, LL).

这是一个删除非数字元素的简单谓词。 我希望在 DCG 中写入相同的行为。

我尝试了类似的方法(显然不起作用):

cleanList([]) --> [].
cleanList([H]) --> {number(H)}.
cleanList([H|T]) --> [H|T], {number(H)}, cleanList(T).

是否可以向我解释什么是错的或缺少什么?

谢谢!

【问题讨论】:

  • 一个大问题是... --> [H|T], ...。您希望 DCG 读取序列并且 [H|T] 具有任意长度。不知道为什么您在该术语中包含T。您对cleanList(T) 的递归调用已经在输入上扫描T
  • 哦,是的,我明白了!谢谢你的回复,我不明白DCG是如何递归读取序列的,现在可以了。

标签: prolog dcg


【解决方案1】:

DCG 表示法的目的正是隐藏,或者更好地,隐含地,标记列表。所以,你的代码应该是这样的

cleanList([]) --> [].
cleanList([H|T]) --> [H], {number(H)}, cleanList(T).
cleanList(L) --> [H], {\+number(H)}, cleanList(L).

可以提高效率:

cleanList([]) --> [].
cleanList([H|T]) --> [H], {number(H)}, !, cleanList(T).
cleanList(L) --> [_], cleanList(L).

风格说明:Prologger 确实更喜欢避开骆驼 :)

clean_list([]) --> [].
etc...

另外,我更喜欢更紧凑的代码:

clean_list([]) --> [].
clean_list(R) --> [H], {number(H) -> R = [H|T] ; R = T}, clean_list(T).

【讨论】:

  • 我知道我已经接近答案了,感谢您的精确和建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
相关资源
最近更新 更多