2014-10-08 121 views
3

我有一个家庭作业任务来定义序言中的10个事实来解决这个难题。Prolog逻辑拼图和约束编程

Five translators are working in an international organization: 
Spaniard, Englishman, Frenchman, German and Russian. 
Each of them speaks its native language and also two 
languages from the native languages of other translators. Find 
the languages speaked by each translator if it is known that 
1. The Englishman speaks German. 
2. The Spaniard speaks French. 
3. The German does not speak Spanish. 
4. The Frenchman does not speak German. 
5. Spaniard and Englishman can talk with each other in German. 
6. Englishman and Frenchman can talk with each other in two 
languages. 
7. Four translators speak Russian. 
8. Exactly two translators speak French. 
9. Only one translator who speaks Spanish speaks also Russian. 
10. Russian and Englishman have no common languages except 
their native languages. 

我已经定义了8个约束,降低了我的解决办法的空间15,但我不知道如何定义的最后两个事实。

% lahendusstruktuur 
structure(
    [translator(inglane,_,_,inglise), 
    translator(sakslane,_,_,saksa), 
    translator(hispaanlane,_,_,hispaania), 
    translator(prantslane,_,_,prantsuse), 
    translator(venelane,_,_,vene)]). 

% abipredikaadid 
nationality(translator(B,_,_,_),B). 
language1( translator(_,B,_,_),B). 
language2( translator(_,_,B,_),B). 
native_language(
      translator(_,_,_,B),B). 

% keelte faktid (andmebaas) 
possible_language(vene). 
possible_language(inglise). 
possible_language(hispaania). 
possible_language(prantsuse). 
possible_language(saksa). 

% tabeli täitmine 
solve(S):- 
    structure(S), 
    fill_structure(S), 
    fact1(S), 
    fact2(S), 
    fact3(S), 
    fact4(S), 
    fact5(S), 
    fact6(S), 
    fact7(S), 
    fact8(S), 
    %fact9(S), 
    %fact10(S), 
    true. 

fill_structure([A,B,C,D,E]):- 
    fill_line(A,inglane), 
    fill_line(B,sakslane), 
    fill_line(C,hispaanlane), 
    fill_line(D,prantslane), 
    fill_line(E,venelane). 

fill_line(X,Nationality):- 
    nationality(X,Nationality), 
    possible_language(Keel1), 
    language1(X,Keel1), 
    possible_language(Keel2), 
    language2(X,Keel2), 
    native_language(X,Native), 
    Keel1\=Native, 
    Keel2\=Native, 
    Keel1 @> Keel2. 

% keelte generaator 
speaks(Nationality,Language,S):- 
    member(X,S), 
    nationality(X,Nationality), 
    language(X,Language). 

language(X,L):-native_language(X,L). 
language(X,L):-language1(X,L). 
language(X,L):-language2(X,L). 

% faktid 1-10 
%1. The Englishman speaks German. 
fact1(X):- 
    speaks(inglane,saksa,X). 
%2. The Spaniard speaks French. 
fact2(X):- 
    speaks(hispaanlane,saksa,X). 
%3. The German does not speak Spanish. 
fact3(X):- 
    \+speaks(sakslane,hispaania,X). 

% The Frenchman does not speak German. 
fact4(X):- 
    \+speaks(prantslane,saksa,X). 

% Spaniard and Englishman can talk with each other in German. 
fact5(X):- 
    speaks(hispaanlane,saksa,X), 
    speaks(inglane,saksa,X). 

%6. Englishman and Frenchman can talk with each other in two languages. 
fact6(X):- 
    findall(Keel, 
     (
     speaks(inglane,Keel,X), 
     speaks(prantslane,Keel,X) 
    ), 
     Keelte_hulk), 
     Keelte_hulk=[_,_]. 

%% Four translators speak Russian. 
fact7(X):- 
    findall(Inimene, 
    (
    speaks(Inimene,vene,X), 
    speaks(Inimene,vene,X), 
    speaks(Inimene,vene,X), 
    speaks(Inimene,vene,X)),Inimeste_hulk), 
    Inimeste_hulk=[_,_,_,_]. 
/* 
    (speaks(inglane,vene,X), 
    speaks(sakslane, vene,X), 
    speaks(hispaanlane, vene,X), 
    \+ speaks(prantslane, vene,X)); 
    (speaks(inglane,vene,X), 
    speaks(sakslane, vene,X), 
    \+speaks(hispaanlane, vene,X), 
    speaks(prantslane, vene,X)); 
    (speaks(inglane,vene,X), 
    \+speaks(sakslane, vene,X), 
    speaks(hispaanlane, vene,X), 
    speaks(prantslane, vene,X)); 
    (speaks(inglane,vene,X), 
    \+speaks(sakslane, vene,X), 
    speaks(hispaanlane, vene,X), 
    speaks(prantslane, vene,X)). */ 

    %Exactly two translators speak French. 
fact8(X):- 
    findall(Inimene, 
    (
    speaks(Inimene,prantsuse,X), 
    speaks(Inimene,prantsuse,X)),Inimeste_hulk), 
    Inimeste_hulk=[_,_]. 

例如,我试图为事实这样的解决方案10.

fact10(X):- 
    speaks(inglane,inglise,X), speaks(venelane,inglise,X), 
    speaks(venelane,inglise,X), speaks(venelane,vene,X), 
    \=(speaks(inglane,hispaania,X),speaks(venelane, hispaania,X), 
    \=(speaks(inglane,prantsuse,X),speaks(venelane, prantsuse,X), 
    \=(speaks(inglane,saksa,X),speaks(venelane,saksa,X). 

这降低了溶液的空间,但是在此之后它仍然包含这样的元件,其不应该在减少解集。

我使用这个函数来得到我的解决方案集大小

findall(_, solve(X), Solutions), length(Solutions,N). 

而这对于解决方案集元素

solve(X). 

我没有离开的想法如何来描述这两个事实。如果有人可以帮助,我将不胜感激:)。

对不起,我的英语不是我的第一语言。

回答

0

与你不同的方法是使用带有限域的约束规划结构(即Prolog的clpfd库)。这里有两个MiniZinc模型可能会给你一些启发。由于这是一项家庭作业,我甚至不会尝试在“纯粹的”Prolog中解决它,即不使用clpfd。

下面是一个使用的套阵列的模型:http://hakank.org/minizinc/five_translators.mzn

而且相同的主要方法,但使用0/1矩阵来代替:http://hakank.org/minizinc/five_translators.mzn

(我不知道在所有的,这将帮助你,但它是一个有趣的问题...)

0

我认为这种关系将与第9条解决您的问题:http://www.swi-prolog.org/pldoc/man?predicate=bagof%2f3

喜欢的东西

这里

  • 的bagof子句标识一个变量(第一个参数)来表示的那种我们感兴趣的
  • 将涉及该变量的条件的事情,不以任何方式解决的Prolog可以
  • 收集针对该条件适用的所有变量,成列表(第三个参数)

然后你验证清单的长度1。

我不想做你的功课你,所以我不会在条件填写,但如果你正在寻找有长颈鹿,喝伏特加所有翻译,这将是

(has(Translator,giraffe),drinks(Translator,vodka)) 

bagof也可用于条件10.