2011-05-07 106 views
3

我想学习序言,我有一个非常大的问题将我的编程知识转换为这种语言。我无法解决真正的新手问题。学习序言

,比如我有这个

a(b(1)). 
a(b(2)). 
a(b(3)). 
a(b(4)). 
a(b(6)). 

的行使要打印(使用writeln(X))所有B(Y)如果Y是偶数。

我能找到,如果它是一个即使使用此号码,如果我没看错的

a(b(X)) mod 2 =:= 0 

,但我无法理解如何进行检查,并打印所有数字。

回答

7

在序言一个非常基本的概念是模式匹配
有很多教程解释它,就像this一个
,你可能还需要检查第二章的第一和休息。

的原因,我真的很喜欢序言之一是,我只是写我想要什么:

我想打印所有具有特定属性的X.
让我们先描述属性。

X具有如果 它所属的数据库 属性是偶数

has_attribute(X):- 
    belongs_db(X), 
    is_even(X). 

在数据库X所属如果有一个子句A(B(X))

belongs_in_db(X):- 
    a(b(X)). 

X即使2的除法的其余部分为0:

is_even(X):- 
    0 =:= X mod 2. 

现在我们可以问has_attribute(X),prolog会回复,列出每个X. ,但我们希望所有的X.这样做,我们将使用findall/3谓词 查找所有具有我想要属性的X并将它们放入一个名单

findall(X,has_attribute(X),List). 

现在我们已经在列表中的所有X和我们想打印出来 一个简单的方法是只使用writeln/1:

writeln(List) 

所以,到底:

run:- 
    findall(X,has_attribute(X),List), 
    writeln(List). 

has_attribute(X):- 
    a(b(X), 
    0 =:= X mod 2. 

另一方面,您可能需要以其他方式打印数字。 对于这一点,你应该使用recursion

如果列表是空的,我做

my_print_list([]). 

如果列表中有haed和尾我会打印第一个元素,然后尾巴:

my_print_list([Head|Tail]):- 
    writeln(Head), 
    my_print_list(Tail). 
+0

谢谢,这清理了很多东西。 – 2011-05-07 12:27:32

0
 
is_even(N) :- 
     0 =:= N mod 2. 

all_even_number :- 
     a(b(X)), 
     is_even(X), 
     writeln(X), 
     fail. 
all_even_number.