微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Prolog中获得not效果

如何解决如何在Prolog中获得not效果

我正在尝试创建一个递归调用自身的规则,并找到遍历有向图的所有可能路径。我正在使用 findall() 这样做。函数traverse(Start,End)

我有

traverse(Start,End,[li]) :-
   node(Start,End),append(End,Li).

traverse(Start,[Li]) :-
   node(Start,Z),traverse(Z,append(Start,Li).

/*here I would like to check that Z is not a member of Li before
  I call traverse(Z,I kNow I can check that it is a member
  using member(Z,Li) but how to I check it is not a member in 
  prolog*/

findalltraverses(Start,[list]) :-
   findall(_,traverse(Start,End).

解决方法

开始之前:这种语言叫做 prolog。

您的代码有几个不同级别的错误/错误。这是它们的(不完整)列表:

  • findall 需要一个右括号。
  • findall 需要 3 个参数。第一个位置是您感兴趣的内容,第二个是如何选择数据(哪个调用),第三个是您的答案的容器。您对容器感兴趣,因此 findalltraverses 应将其作为属性。
  • 节点和边之间存在差异。一条边连接两个节点。
  • 变量以大写字母或下划线开头。
  • 如果变量 L 与列表统一,则您不必像 [L] 那样声明它,因为对于示例 L=[1,2,3] [L] 将变为 {{1 }} 是一个列表,其中包含一个包含 [[1,3]]12 的列表。
  • 对于递归调用,您通常有两种情况:结束设置和递归调用设置。你的这个概念是对的。
  • 3 有 3 个参数:lists appendL1L2,其中 L3 和 {{1} } 附加的是 L1
  • 您的谓词 L2 有 3 个属性。没有为 2 个属性定义谓词 L3
  • 您不能覆盖变量。一旦设置了变量的值,就不能再更改它。例如:如果您有一个数字 traverse/3 并且想要增加它,您需要使用不同的变量来保存结果:traverse/2
  • 将单个元素 N 附加到列表 N1 is N+1 作为头元素(意思是将它放在第一个位置)可以通过头尾写法来完成:E。对于 L[E|L]E=1 变为 L=[2,3]
  • 为了避免无限循环,您需要跟踪您已经访问过的节点。但是,如果您对从 [E|L][1,3] 的路径感兴趣,您需要以某种方式转发该路径。不可能仅将列表与访问过的节点一起使用,因为在通过递归后退时不会保留此知识。所以你的 Start 谓词应该有 4 个属性。
  • “不”可以用 End 表示,意思是“无法证明”。

好的,这里截取了一个工作代码。递归结束部分有点不同,因为它不检查从 traverse\+ 是否存在边,而是询问 StartEnd 是否相同。如果是,则结果路径仅包含此节点。这很重要,因为在剪切的代码中,路径将在通过递归(Start返回时构建,而包含访问节点的列表在进入时会增长递归 (End)。

[Start|Path]

让我们测试一下!

[Start|Visited]

看起来不错。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。