我是prolog的新手,我一直坚持锻炼。
我有一个名为" languages.pl"的序言数据库。我正在处理一个名为" program.pl"的文件,它有规则。
语言具有名称和创建年份,例如:
COBOL, 1960
PASCAL, 1971
C, 1971
这些语言有前辈,如:
Scheme,Lisp ------ Lisp是前身的os方案。
所以,我希望找到一种语言Lp,它在语言L之前,但至少在他们的创作之间有十年的时间,例如:
?- ling_precedes_decade(Lp, L).
Lp = ’C++’,
L = ’Rust’ .
我喜欢这样的东西:
ling_precedes_decade(Lp, L) :-
language(Lp, X),
language(L, Y),
((X-Y) > 9); ((X-Y) < -9).
但它没有用。
答案 0 :(得分:3)
关于问题发布,有几点需要注意。
您将示例事实列为:
COBOL, 1960
PASCAL, 1971
C, 1971
由于您没有将这些显示为实际的Prolog事实,我只能推测您是如何断言它们的。为了使COBOL
成为原子,正确的方法是使用引号,因为在Prolog中,首字母大写将使COBOL
成为变量。
language('COBOL', 1960).
language('PASCAL', 1971).
language('C', 1971).
然后在您的谓词中,您没有注意到,
与;
的优先规则。 ;
的优先级低于,
。因此,您的谓词行为就好像分组如下:
lang_precedes_decade(Lp, L) :-
( language(Lp, X),
language(L, Y),
((X-Y) > 9) )
; ((X-Y) < -9).
您需要对&#34;或&#34;进行分组。适当地:
lang_precedes_decade(Lp, L) :-
language(Lp, X),
language(L, Y),
( ((X-Y) > 9); ((X-Y) < -9) ).
然后,如果你查询,你会得到这个:
| ?- lang_precedes_decade(Lp, L).
L = 'PASCAL'
Lp = 'COBOL' ? ;
L = 'C'
Lp = 'COBOL' ? ;
L = 'COBOL'
Lp = 'PASCAL' ? ;
L = 'COBOL'
Lp = 'C' ? ;
no
现在请注意,由于检查事实的对称性,您会得到多余的结果。由于language(Lp, X), language(L, Y)
已经捕获对称性(您将获得Lp
和L
交换的解决方案),因此您不需要额外检查{{1 }}:
< -9
这将导致:
lang_precedes_decade(Lp, L) :-
language(Lp, YearLp),
language(L, YearL),
(YearL-YearLp) > 9. % Lp precedes L