0

我对 Prolog 很陌生,正在努力学习。

对于我的程序,我想让用户提供成对的“类型”字符串。

例如,用户在命令行中提供字符串“john”和“man”。这些原子将相等,即 john(man)。

在下一个提示符下,用户提供“man”和“tall”,程序再次断言这些是有效的,man(tall)。

然后用户可以查询程序并询问“约翰高吗?”。或者在 Prolog 中: john(tall) 通过传递属性变为真。

我已经能够解析来自用户输入的字符串并将它们分配给变量SubjectObject.

我尝试了一个子句(其中 Subject 和 Object 是不同的字符串):

attribute(Subject, Object) :-
   assert(term_to_atom(_ , Subject),
   term_to_atom(_ , Object)).

我想断言 Subject 和 Object 是有效对的事实。如果用户断言它,那么它们属于一起。我如何强制这种对的平等?

解决这个问题的最佳方法是什么?

4

2 回答 2

2

最近这类问题被问了很多(我猜你的教授都分享笔记或其他东西),所以浏览最近的历史可能对你很有帮助。例如,我想到了这个。

您的代码非常广泛。这就是你想要做的:

attribute(Subject, Object) :-
  Fact =.. [Object, Subject],
  assertz(Fact).

使用它的工作方式如下:

?- attribute(man, tall).
true.

?- tall(X).
X = man.

所以,关于这段代码,你应该注意以下几点:

  • 我们使用=../2“univ”运算符从列表构建结构。这是从一些原子创建事实的唯一方法。
  • 我已经交换了主语和宾语,因为换一种方式几乎肯定不是你想要的。
  • 您想要的谓词是assertz/1or asserta/1, not assert/2。末尾的 a 和 z 只是告诉 Prolog 你想要在数据库的开头还是结尾的事实。

根据查看您的代码,我认为您需要摆脱很多包袱才能使用 Prolog 提高工作效率。

  1. Prolog 谓词不返回值。所以assert(term_to_atom(...甚至不在正确的轨道上,因为您似乎认为这term_to_atom会“返回”一个值,并且它会assert像函数式或命令式语言一样被替换到调用中。Prolog 的工作原理与此完全不同。
  2. 我不确定为什么您的term_to_atom谓词中有一个空变量。我认为你这样做是为了满足谓词的数量,但是除非你有一个基本术语和一个变量,否则这个谓词是毫无用处的。
  3. 有一个assert/2,但它不会做你想要的。应该清楚为什么 assert 通常只接受一个参数。
  4. Prolog 的事实应该是这样property(subject...)的。构造事实然后查询它们并不容易,这是您必须使用man(tall). 你想说的是有一个属性,个子高,man满足。

我强烈建议您在此时备份并阅读一些基本的 Prolog 教程。如果你试图向前推进,你只会迷失更多。

编辑:针对您的评论,我不确定您想要多通用。在您处理中间有 [is,a] 的 4 项列表的基本情况下,这就足够了:

build_fact([Subject,is,a,Object], is_a(Subject, Object)).

如果要隔离第一个和最后一个并创建事实,则必须再次使用 univ:

build_fact([Subject|Rest], Fact) :-
  append(PredicateAtoms, [Object], Rest),
  atomic_list_concat(PredicateAtoms, '_', Predicate),
  Fact =.. [Predicate, Subject, Object].

不确定您是否愿意接受最终会出现的文章(“a”,“the”):

?- build_fact([john,could,be,a,man], Fact).
Fact = could_be_a(john, man)
于 2013-04-25T17:07:50.263 回答
1

不要做可变事实的头脑。当术语名称集固定时,Prolog 效果最佳。相反,使用预定义的静态术语名称为存储属性创建一个通用位置,例如:

is_a(john, man).

property(man, tall).
property(john, thin).

(想想普通形式的 SQL 表)。然后你可以使用 simpleassertz/1来更新数据库:

add_property(X, Y) :- assertz(property(X, Y)).
于 2013-04-25T17:05:20.693 回答