Prolog传值问题

1. 问题背景

  • 关系图(Relationship)
    在这里插入图片描述
  • 核心代码
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
  • 问题:需要查询jim的grandparent
  • 关系图(Relatinoship)
    在这里插入图片描述
  • 我的代码
    parent(_ jim), parent(P, _).
  • 查询结果
    • 发现与真实的结果相差甚远,
      在这里插入图片描述
    • 于trace后发现原因,是因为在执行完第一个parent(_, jim)之后,在parent(P, _)没有传值,所以其实第一个parent查出了jim的父母,pat 但是因为第二个parent(P, _) 的影响, P 的值可以是随意的,第一个parent 的限制并没有传到第二个parent这里。
      在这里插入图片描述
    • 但是这个地方也没有redo回 parent(_, jim) ,很奇怪

2. 效率问题

  • 以下两个查询语句都可以查询jim的祖父母,parent(X,Y), parent(Y, jim).parent(Y,jim), parent(X, Y), 但是后者效率更快,因为更精确,直接得到Y的值然后查询;然而第一个是随即乱查,查完之后再拿随机的值来对比。
  • Simpelst first, 明确的值first。原因:明确的值可以减少我们的搜索流程。
  • Trace: parent(X,Y), parent(Y, jim). 在这里插入图片描述
  • Trace: parent(Y,jim), parent(X, Y)
    在这里插入图片描述

3. Unary clause 和 Binary clause

  • Unary clause - 通常用于表示object的属性(properties)
female(pam).
male(tom).
male(bob).
female(liz).
female(pat).
female(ann).
male(jim).
  • Binary clause - 通常用于表示object与object之间的联系(relationship)
sex(pam, feminine).
sex(tom, masculine).
sex(bob, masculine).

4. Some baisc terms

  1. facts: simple facts
parent(pam, bob).
parent(tom, bob).
parent(tom, liz).
  1. questions: query that wants to be satisfied
-? parent(X, bob).
  1. rules: some rules
offspring(Y, X) :- parent(X, Y).
  • Difference between facts and rules
    • Facts: something that is always.
    • Rules: something that is conditional, including a condition part and a conclusion part.
      • head: conclusion part, body: condition part.
      • For all X, Y: Y is an offspring of X if X is the parent of Y.
        在这里插入图片描述
  • More exmpales,
    • Definition of mother, which can be written as mother(X,Y) :- female(X), parent(X,Y).
    • For all X, Y: X is the mother of Y if X is female and X is the parent of Y.

5. 书写格式

  • For clearity of codes, we will often choose to write the head of a clause and each goal of the body on a seperate line.
  • We will also indent goals in order to make the difference between the head and the goals more visible.

6. 无记忆问题(重复自己)

  • Prolog在查询的时候,并不会代入之前我们查询的条件,我们之前也验证了,当我们输入goals parent(_ jim), parent(P, _). 的时候,没有办法查询到jim的祖父母,而是把所有的 parent 的relationship给查出来了,原因就是prolog的无记忆性,它在过了parent(_, jim) 之后,由于这个_ 是匿名变量,并不会传参给下一个,所以下一个查询语句就变成了 parnet(P, _) 就相当于第一个条件不存在一样,自然把所有的parent的 relationship都给查出来了。
  • 同样我们也遇到了sister查询的问题
    sister(X,Y) :- female(X), parent(Z, X), parent(Z, Y).
  • 这样的rules查出来的 sister 会带有自己,是因为前方一路传参虽然没有错,(但是由于无记忆性),它的参数边传递会边掉。所以最后查出来的 Z 虽然是我们想要的,这个相当于就是一个新的clause, parent(Z, _) 自然就会把 Z 的所有子女给打印出来了。
  • 所以对于这类无记忆性问题的解决办法之一,可以最后加一个判断,给把相同的排除掉
    sister(X,Y) :- female(X), parent(Z, X), parent(Z, Y), different(X, Y).
  • 解决!
  • 注意 这个地方different(X, Y) 是个伪代码,我们假设Prolog有这个代码,如果你直接这样复制是不会生效,有用的!

7. Summary

  • Prolog clauses are of three types: facts, rules and questions.
    • Facts declare things that are always, unconditionally true.
    • Rules declare things that are true depending on a given condition.
    • Questions are that the user can ask the program what things are true.
  • Prolog clauses consist of the head and the body.
    • The body is a list of goals separated by commas. Commas are understood as conjunctions.
    • Facts are clauses that have the empty body (only conclusion).
    • Questions only have the body (only condition).
    • Rules have the head and the (non-empty) body (both conclusion and condition).
  • Reading & Understanding
    • Rules语句: hasachild(X) :- parent(X,Y).
    • For all X and Y, if X is a parent of Y then X has a child.
    • For all X, X has a child if there is some Y such that X is a parent of Y.
©️2020 CSDN 皮肤主题: 护眼 设计师:闪电赇 返回首页