2

我开始学习 Prolog,我的代码遇到了编译器错误。我正在尝试编写一些代码来检查满足某些条件的家庭是否处于贫困之中。最后一行几行是贫困条件,这就是我得到Opertator Expected错误的地方。我想说的是,给定家庭ID,如果那个家庭的人数是一个,并且收入低于11170,那么这个家庭是贫困的。对于一个人数大于 8 的家庭,贫困水平为 38890 加上每增加一个家庭成员 3960。我该如何纠正这些错误?family_in_poverty应该返回truefalse

family(10392,
       person(tom, fox, born(7, may, 1960), works(cnn, 152000)),
       person(ann, fox, born(19, april, 1961), works(nyu, 65000)),
       % here are the children...
       [person(pat, fox, born(5, october, 1983), unemployed),
        person(jim, fox, born(1, june, 1986), unemployed),
        person(amy, fox, born(17, december, 1990), unemployed)]).

family(38463, 
       person(susan, rothchild, born(13, september, 1972), works(osu, 75000)),
       person(jess, rothchild, born(20, july, 1975), works(nationwide, 123500)),
       % here are the children...
       [person(ace, rothchild, born(2, january, 2010), unemployed)]).

married(FirstName1, LastName1, FirstName2, LastName2) :-
    family(_, person(FirstName1, LastName1, _, _),
           person(FirstName2, LastName2, _, _), _).

married(FirstName1, LastName1, FirstName2, LastName2) :-
    family(_, person(FirstName2, LastName2, _, _),
           person(FirstName1, LastName1, _, _), _).

householdIncome(ID, Income) :-
    family(ID, person(_, _, _, works(_, Income1)),
           person(_, _, _, works(_, Income2)), _),
    Income is Income1 + Income2.

exists(Person) :- family(_, Person, _, _).
exists(Person) :- family(_, _, Person, _).
exists(Person) :- family(_, _, _, Children), member(Person, Children).

householdSize(ID, Size) :-
    family(ID, _, _, Children),
    length(Children, ChildrenCount),
    Size is 2 + ChildrenCount.

:- use_module(library(lists)). % load lists library for sumlist predicate

average(List, Avg) :-
    sumlist(List, Sum),
    length(List, N),
    Avg is Sum / N.

family_in_poverty(FamilyID) :- householdSize(FamilyID, 1), householdIncome(ID, X), X <= 11170.
family_in_poverty(FamilyID) :- householdSize(FamilyID, 2), householdIncome(ID, X), X <= 15130.
........
family_in_poverty(FamilyID) :- householdSize(FamilyID, Y), householdIncome(ID, X), X <= 38890 + (Y - 8)*3960, Y > 8.
4

4 回答 4

3

Prolog 不is <=用于数字比较,仅=<用于小于或等于。

当您使用is关键字时,这是一个中缀谓词is/2,它将右侧计算为数值表达式并将结果与​​左侧统一。

于 2012-04-29T21:09:08.830 回答
1

不确定这是否会有所帮助,但请尝试进一步分解它。一行用于计算,另一行用于比较:

family_in_poverty(FamilyID) :- 
  householdSize(FamilyID, Y), 
  householdIncome(ID, X), 
  M is 38890 + (Y - 8)*3960,
  X =< M, 
  Y > 8.
于 2012-04-29T21:30:26.450 回答
1

错误应该已经显示在这里:

|: family_in_poverty(FamilyID) :- householdSize(FamilyID, 1), householdIncome(ID, X), X <= 11170.
ERROR: user://1:88:0: Syntax error: Operator expected

如果您不确定您的 Prolog 系统支持哪些运算符,或者您自己定义了哪些运算符,您可以通过 current_op/3 列出当前定义。以下是 SWI Prolog 的典型结果:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.1.3)
Copyright (c) 1990-2011 University of Amsterdam, VU Amsterdam
?- setof(Z,current_op(X,Y,Z),L), write(X-Y-L), nl, fail; true.
1-fx-[$]
200-fy-[+,-,@,\]
200-xfx-[**]
200-xfy-[^]
250-yfx-[?]
400-yfx-[*,/,//,<<,>>,div,mod,rdiv,rem,xor]
500-yfx-[+,-,/\,\/]
600-xfy-[:]
700-xfx-[<,=,=..,=:=,=<,==,=@=,=\=,>,>=,@<,@=<,@>,@>=,\=,\==,\=@=,as,is]
900-fy-[\+]
990-xfx-[:=]
1000-xfy-[,]
1050-xfy-[*->,->]
1100-xfy-[;]
1105-xfy-[|]
1150-fx-[discontiguous,dynamic,initialization,meta_predicate,    
    module_transparent,multifile,public,thread_initialization,thread_local,volatile]
1200-fx-[:-,?-]
1200-xfx-[-->,:-]

如您所见,没有定义运算符 <=。现在,当 Prolog 系统遇到“term atom ...”形式的输入并且 atom 未定义为中缀或后缀运算符时,它会发出语法错误消息“Operator Expected”等。

您可能想要做的是算术比较。算术比较小于或等于由 Prolog 中的运算符 =< 表示。运算符甚至在 ISO 核心标准中定义。它的行为使得左侧和右侧进行算术评估,然后进行算术比较。

还有另一个运算符@=<,它不求值,也不是算术比较,而是词法比较。在比较整数和浮点数的算术比较中,整数首先被扩展为浮点数。在词法比较中,类型被比较。所以:

 ?- 1 =< 1.0.
 true
 ?- 1 @=< 1.0.
 false

最好的祝福

SWI Prolog 算术比较: http ://www.swi-prolog.org/pldoc/doc_for?object=section%282,%274.26%27,swi%28%27/doc/Manual/arith.html%27%29% 29

SWI Prolog 词法比较: http ://www.swi-prolog.org/pldoc/doc_for?object=section%283,%274.7.1%27,swi%28%27/doc/Manual/compare.html%27% 29%29

于 2012-04-29T21:59:28.963 回答
0

Prolog 中的简单经验法则:不等号始终指向等号。示例:=<、>=、@=<、@>= 等。这与命令式语言不同,其中不等号通常首先出现。

于 2013-09-24T15:46:25.030 回答