在 Prolog (SWI) 中,如何建立用户提供的对的知识库并断言相等 [英] In Prolog (SWI), how to build a knowledge base of user supplied pairs and assert to be equal

查看:46
本文介绍了在 Prolog (SWI) 中,如何建立用户提供的对的知识库并断言相等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am very new to Prolog and trying to learn.

对于我的程序,我希望用户提供类型"的字符串对.

For my program, I would like to have the user provide pairs of strings which are "types of".

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

For example, user provides at command line the strings "john" and "man". These atoms would be made to be equal, i.e. john(man).

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

At next prompt, then user provides "man" and "tall", again program asserts these are valid, man(tall).

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

Then the user could query the program and ask "Is john tall?". Or in Prolog: john(tall) becomes true by transitive property.

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

I have been able to parse the strings from the user's input and assign them to variables Subject and Object.

我尝试了一个子句(其中主题和对象是不同的字符串):

I tried a clause (where Subject and Object are different strings):

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

我想断言主题和对象是有效对的事实.如果用户断言它,那么它们属于一起.我如何强制这种对的相等性?

I want to assert the facts that Subject and Object are valid pair. If the user asserts it, then they belong to together. How do I force this equality of the pairs?

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

What's the best way to go about this?

推荐答案

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

Questions of this sort have been asked a lot recently (I guess your professors all share notes or something) so a browse through recent history might have been productive for you. This one comes to mind, for instance.

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

Your code is pretty wide of the mark. This is what you're trying to do:

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

使用方法如下:

?- attribute(man, tall).
true.

?- tall(X).
X = man.

因此,对于此代码,您应该注意以下几点:

So, here's what you should notice about this code:

  • 我们使用 =../2,即univ"运算符,从列表构建结构.这是从某些原子创建事实的唯一方法.
  • 我交换了主语和宾语,因为换个方式几乎肯定不是你想要的.
  • 您想要的谓词是 assertz/1asserta/1,而不是 assert/2.末尾的 a 和 z 只是告诉 Prolog 你想要数据库的开头还是结尾的事实.
  • We're using =../2, the "univ" operator, to build structures from lists. This is the only way to create a fact from some atoms.
  • I've swapped subject and object, because doing it the other way is almost certainly not what you want.
  • The predicate you want is assertz/1 or asserta/1, not assert/2. The a and z on the end just tells Prolog whether you want the fact at the beginning or end of the database.

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

Based on looking at your code, I think you have a lot of baggage you need to shed to become productive with 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满足.
  1. Prolog predicates do not return values. So assert(term_to_atom(... wasn't even on the right track, because you seemed to think that term_to_atom would "return" a value and it would get substituted into the assert call like in a functional or imperative language. Prolog just plain works completely differently from that.
  2. I'm not sure why you have an empty variable in your term_to_atom predicates. I think you did that to satisfy the predicate's arity, but this predicate is pretty useless unless you have one ground term and one variable.
  3. There is an assert/2, but it doesn't do what you want. It should be clear why assert normally only takes one argument.
  4. Prolog facts should look like property(subject...). It is not easy to construct facts and then query them, which is what you'd have to do using man(tall). What you want to say is that there is a property, being tall, and man satisfies it.

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

I would strongly recommend you back up and go through some basic Prolog tutorials at this point. If you try to press forward you're only going to get more lost.

编辑:针对您的评论,我不确定您希望达到的一般程度.在处理中间有 [is,a] 的 4 项列表的基本情况下,这就足够了:

Edit: In response to your comment, I'm not sure how general you want to go. In the basic case where you're dealing with a 4-item list with [is,a] in the middle, this is sufficient:

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

如果要隔离first和last并创建事实,则必须再次使用univ:

If you want to isolate the first and last and create the fact, you have to use univ again:

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

不确定您是否愿意接受最终会结束的冠词(a"、the"):

Not sure if you want to live with the articles ("a", "the") that will wind up on the end though:

?- build_fact([john,could,be,a,man], Fact).
Fact = could_be_a(john, man)

这篇关于在 Prolog (SWI) 中,如何建立用户提供的对的知识库并断言相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆