Prolog谓词解决方案

时间:2016-04-14 10:51:11

标签: list prolog

我正在接受一些过去的考试问题,以便进行我的prolog考试。

以下是问题:

  1. (a)编写一个谓词insert(Xs, Y, Zs),该Zs在获得列表时Y成立 将Xs插入列表? - insert([1,2,3], 4, Zs). 。查询如:

    Zs = [4, 1, 2, 3]
    
    Zs = [1, 4, 2, 3]
    
    Zs = [1, 2, 4, 3]
    
    Zs = [1, 2, 3, 4]. 
    
  2. 应该成功四次并给出以下答案:

    using(Something myObject = new Something())
    {
        PopulateSomethingObject(myObject);
        x = myObject.SomeNumber();
    }
    

    我有点担心,因为我不知道从哪里开始。任何人都可以提供帮助,因为我需要示例解决方案来练习我的考试。

    非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

我们首先更改此谓词的可怕名称:谓词应描述持有什么该做什么。这个名字应该反映出来。我建议list_with_element/3,并鼓励您尝试找到更好的名称,最好明确每个参数代表什么。

然后,我们按照我们的目的去做:描述使这种关系成立的案例。

例如:

list_with_element([], E, [E]).
list_with_element([L|Ls], E, [E,L|Ls]).
list_with_element([L|Ls0], E, [L|Ls]) :-
        ...

我将填写...作为一项简单的练习。陈述条款头是真实所必需的条件!

编辑:我想多说一下上面的模式。根据我的经验,一个很好的方法 - 并且肯定在开始时 - 推理描述列表的谓词是考虑两个基本情况:

  1. 原子[],表示空列表
  2. 表单'.'(E, Es)的条款,也写为[E|Es],其中E是列表的第一个元素,Es也是列表。
  3. 这遵循列表的归纳定义。

    这种特殊情况的缺点是这种方法导致情况(2)再次需要分成两个子句,并且出乎意料地需要三个子句来处理两个基本案例。这显然与我们直观的期望相反,即两个条款就足够了。确实如此,但我们需要小心,不要意外地失去解决方案。在这种情况下,上面的前两个条款包含在以下事实中:

    list_with_element(Ls, E, [E|Ls]).
    
    每个经验丰富的Prolog编码器都会以这种方式编写这样的谓词,或者就像在这种情况下直接使用select/3一样。这就是@lurker感知和暗示的内容,而@tas正确地显示了一个不同的子句(很容易出现意外)完全包含我们想要表达的所有情况。

    因此,我仍然发现首先明确地考虑空列表要容易得多,确保正确处理该案例,然后继续处理更复杂的案例,然后看看是否可以更紧凑地编写现有程序。这是我也用于此示例代码的方式,但我没有尽可能地缩短它。请注意,使用单调代码,可以获得多余的事实!

    请注意,具体是确定只需将前两个子句替换为:

    list_with_element([L|Ls], E, [E|Ls]).
    

    因为该条款不包含上述情况(1)。

答案 1 :(得分:1)

我想这个问题可能正在寻找的答案就是这样:

insert(List, Element, NewList) :-
    append(Front, Back, List), % split list in two
    append(Front, [Element|Back], NewList). % reassemble list

如果您想要声明性阅读:

  

NewList在List的正面和背面之间有元素。

仔细检查先前的问题或研究材料中是否出现append/3或具有相同语义的谓词。

请注意,如果我理解正确的话,这本质上是与suggestion by @mat完全相同的解决方案。有关详细信息,请参阅append/3的教科书定义。或者甚至更好,查看append/3的教科书定义并对其进行修改,以便用于"插入"。

答案 2 :(得分:1)

有一个内置的谓词select/3可以做同样的事情,尽管参数的顺序不同。

请记住(如果定义正确)谓词可以在不同的方向上工作。例如,它可以告诉你删除元素后列表的样子,它可以(虽然它相当简单)告诉你要从一个列表中删除哪个元素来获取另一个元素,或者它可以告诉你什么列表,删除给定元素后,将类似于给定列表。
(提示:你可能想看看最后一个)。