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

Prolog: Trying to determine if a person is a citizen of a certain country

我正在编写一个 Prolog 程序,其中给出了以下格式的关于一个人的公民身份的一组事实(意思是 [name] 是 [list of countries] 的公民):

citizen(name, [list of countries])

示例:citizen(JaneDone, [Germany, United States])

查询可以 return 一个人是否拥有德国公民身份。我正在这样写我的查询:

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

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

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

所以:

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

而在 Prolog 中,没有任何函数;你需要用谓词来拼写。

所以:

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

让我们试试看:

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

一个更基本的问题是:你为什么将你的事实定义为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 不应该...提示: [= 应该做什么16=] 做?)