Prolog - 我有一个我需要匹配的特定事实格式

时间:2017-03-17 06:24:23

标签: prolog

好的,基本上我的老师给了我们一个特定的事实格式:

m([first_male_name, second_male_name,...,last_male_name]).
f([first_female_name,...last_female_name).
family([father,mother,[child1,...,childn]]).

我无法弄清楚如何让我的代码正确解释事实。我尝试了几种不同的方法,但我认为我对此的理解存在根本性的错误。这是我的代码中与此问题相关的部分:

male(X) :- m(Males), member(X, Males).
female(X) :- f(Females), member(X, Females).
parent(X,Y) :- (family([X,_,Child]); family([_,X,Child])), member(Y,Child).

m(['David', 'Lance', 'Charles', 'George', 'Henry', 'Jose', 'Lenny', 'Vance', 'Rhett', 'Jacob', 'Mike']).
f(['Sarah', 'Tammy', 'Jasmine', 'Cassondra', 'Kat', 'Laura', 'Tamarah', 'Nina', 'Stephanie', 'Christen', 'Shannon', 'Maryalice']).
family(['David', 'Sarah', ['George', 'Kat']]).

但是当我尝试? - 男(何塞)。它返回Jose ='David'。任何人都有一些洞察错误的方法吗?我非常感谢你的帮助。

编辑: 谢谢您的帮助。我想这只是一个简单的错误,但我怀疑如果没有帮助我会意识到这一点。我现在已经开始工作了。

2 个答案:

答案 0 :(得分:1)

这是对你没有提出的问题的答案,所以真的应该是评论。但这是一个渴望评论的方式。 :)

在Prolog中,对于程序组织,灵活性和效率,最好将您的事实作为个别事实来陈述,而不是作为集合列表。例如,在m的情况下,您有:

m([first_male_name, second_male_name,...,last_male_name]).

与其他语言一样,最好给出你的事实,谓词和变量合理的名称。所以让我们重命名一下:

males([first_male_name, second_male_name,...,last_male_name]).

假设您的谓词具有PersonNamemale的条件。有了上述事实,可以采取以下措施:

some_predicate(...) :-
    ...
    males(ListOfMales),
    member(PersonName, ListOfMales),
    ...

相反,你应该使用个别事实:

male(first_male_name).
male(second_male_name).
...

然后你的谓词变为:

some_predicate(...) :-
    ...
    male(PersonName),
    ...

您甚至不需要现在拥有的谓词male/1。同样适用于female/1

对于family,每个关系应该是它自己的事实。而不是用列表定义单个复杂事实来定义像这样的族:

family([father,mother,[child1,...,childn]]).

更常见的定义方法是:

parents_child(father, mother, child1).
parents_child(father, mother, child2).
...

然后parent(X, Y)成为:

parent(X, Y) :-
    parents_child(_, X, Y) ; parents_child(X, _, Y).

甚至,为了最大的灵活性(例如,如果它是一个破碎的家庭,或父母再婚等等):

father_child(父亲,孩子1)。    father_child(父亲,孩子2)。    ...    mother_child(母亲,孩子1)。    mother_child(母亲,孩子2)。    ...

然后你有:

parent(X, Y) :-
    father_child(X, Y) ; mother_child(X, Y).

答案 1 :(得分:0)

Prolog"变量"以大写字母开头。如果你想制作它们"文字"这是你把它们放在单引号中的原子。

我发现在SWI-Prolog char_type中使用它来学习确切的规则很有用(对于SWI-Prolog我猜)...你可以使用prolog_var_start"启动一个Prolog变量名"或prolog_atom_start"启动一个不带符号的不带引号的Prolog原子"

?- bagof(C, char_type(C, prolog_var_start), Cs) ; true.
Cs = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'|...] [write]
Cs = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ'] ;
true.

?- bagof(C, char_type(C, prolog_atom_start), Cs).
Cs = [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, ª, µ, º, ß, à, á, â, ã, ä, å, æ, ç, è, é, ê, ë, ì, í, î, ï, ð, ñ, ò, ó, ô, õ, ö, ø, ù, ú, û, ü, ý, þ, ÿ].