Prolog:尝试确定一个人是否是某个国家的公民

发布于 01-09 12:35 字数 414 浏览 3 评论 0原文

我正在编写一个 Prolog 程序,其中以以下格式给出了有关某人公民身份的一组事实(意味着 [姓名] 是 [国家列表] 的公民):

citizen(name, [list of countries])

示例:citizen( JaneDone,[德国,美国])

如果一个人拥有德国公民身份,则查询可以返回。我这样编写查询:

citizenOfGermany(citizenName) :-
    member(citizen, citizen(citizenName)).

但是,无论我向 citizenName 输入什么值,它总是返回一个空列表。这看起来很奇怪,考虑到我认为成员函数检查第一个参数是否在第二个参数内?

I am writing a Prolog program in which given a set of facts about the citizenship(s) of a person in the following format (meaning [name] is a citizen of a [list of countries]):

citizen(name, [list of countries])

Example: citizen(JaneDone, [Germany, United States])

A query is able to return if a person has citizenship in Germany. I am writing my query like this:

citizenOfGermany(citizenName) :-
    member(citizen, citizen(citizenName)).

However, it always returns an empty list no matter what value I feed into citizenName. This seems strange, considering that I thought that the member function checks whether the first parameter is within the second parameter?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的他你的她2025-01-16 12:35:25

你做错了几件事。对于初学者来说,在 Prolog 中,变量以大写字母开头,您需要引用以大写字母开头的原子。

所以:

citizen('JaneDone', ['Germany', 'United States']).

在 Prolog 中,没有任何函数;你需要用谓词来阐明事情。

所以:

citizenOfGermany(CitizenName) :-
    citizen(CitizenName, Countries),
    member('Germany', Countries).

让我们尝试一下:

?- citizenOfGermany(C).
C = 'JaneDone' ;
false.

You've done a few things wrong. For starters, in Prolog, variables start with Capital letters, and you need to quote atoms that start with capital letters.

So:

citizen('JaneDone', ['Germany', 'United States']).

And in Prolog, there aren't any functions; you need to spell things out with predicates.

So:

citizenOfGermany(CitizenName) :-
    citizen(CitizenName, Countries),
    member('Germany', Countries).

And let's try it out:

?- citizenOfGermany(C).
C = 'JaneDone' ;
false.
城歌2025-01-16 12:35:25

一个更基本的问题是:为什么将事实定义为“citizen_of_countries/2”?关系数据库通常没有列表,那么为什么要使用列表来表示事实呢?最好这样做:

citizen_of_country('JaneDone', 'Germany').
citizen_of_country('JaneDone', 'United State').

citizen_of_Germany(CitizenName) :-
    citizen_of_country(CitizenName, 'Germany').

并且,如果您需要所有公民身份的列表:(

citizen_of_countries(Citizen, Countries) :-
    setof(Country, citizen_of_country(Citizen, Country), Countries).

我将其作为练习,说明为什么可以使用 bagof/3 而不是 setof/3findall/3 不应该...提示:citizen_of_countries('Unknown Person', Country) 应该做什么?)

A more fundamental question is: why are you defining your facts as citizen_of_countries/2? Relational databases typically don't have lists, so why are you using a list for a fact? It's better to do this:

citizen_of_country('JaneDone', 'Germany').
citizen_of_country('JaneDone', 'United State').

citizen_of_Germany(CitizenName) :-
    citizen_of_country(CitizenName, 'Germany').

and, if you need a list of all citizenships:

citizen_of_countries(Citizen, Countries) :-
    setof(Country, citizen_of_country(Citizen, Country), Countries).

(I'll leave it as an exercise as to why bagof/3 could be used instead of setof/3 but findall/3 shouldn't ... hint: what should citizen_of_countries('Unknown Person', Countries) do?)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文