【问题标题】:Prolog - How can I return a list where each element appears only once?Prolog - 如何返回每个元素只出现一次的列表?
【发布时间】:2021-08-31 22:12:45
【问题描述】:

我有一个谓词 set/2 应该将第二个参数实例化为一个列表,其元素只是第一个参数中每个术语的一次出现。到目前为止我所拥有的是:

set([],OutList).
set([X|InList],OutList) :- \+member(X,InList), append([X], OutList, OutListNew), set(InList,OutListNew).                      
set([X|InList],OutList) :- member(X,InList), set(InList,OutList).

然后调用 set/2:

set([1,1,2,3],X).

返回真。那是一半 - 我希望 X 被实例化为 [1,2,3] - 但我不确定在这种情况下如何使 X 为真。任何帮助和解释将不胜感激。

【问题讨论】:

    标签: list prolog logic unification


    【解决方案1】:

    您的 Prolog 应该警告您在第一个子句中有一个 singleton,即

    set([],OutList).
    

    这意味着当执行到这样的子句时,它成功,但OutList仍然未绑定。

    现在应该清楚您需要用空列表替换OutList

    另一个错误位于第二个子句中。

    append([X], OutList, OutListNew) 应该改为 append([X], OutListNew, OutList)。作为样式注释,可以用这个统一代替:[X|OutListNew]=OutList,然后移到头部。

    【讨论】:

    • 我放弃了; OutList 应该绑定什么?
    • 查看最后一个版本,我已经替换(澄清)了我的提示,并解决了另一个更重要的错误。
    • 说真的,谢谢。两个小时的倾倒痕迹只让我走到了这一步。现在我可以睡觉了!
    【解决方案2】:

    sort/2 删除重复项(msort/2 保留重复项,如果这是您想要的。

    还有:https://www.swi-prolog.org/pldoc/man?predicate=list_to_set/2

    【讨论】:

    • 谢谢!但是我应该编写自己的函数来执行此操作;我正在尝试学习序言。完成 Learn Prolog Now 中的练习。
    • 请仅在答案本身包含所有相关详细信息后才链接到外部网站。链接应该只支持您的答案。
    猜你喜欢
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多