hello everybody,
I have some trouble in solving the 'Zebra
Puzzle<http://en.wikipedia.org/wiki/Zebra_Puzzle>'
using drools5.
I defined a class named 'House' to represent the data, and the corresponding
enums as well : Color.java, Nation.java, Pet.java, Drink.java,
Cigarette.java, here are those sources:
House.java:
public class House {
// 颜色
public Color color;
// 房子从左数的位置 1-5
public int position;
public Nation nation;
public Pet pet;
public Drink drink;
public Cigarette cigarette;
......
Color.java:
public enum Color {
red, yellow, blue, green, ivory
}
Nation.java:
public enum Nation {
englishman, spaniard, norwegian, ukrainian, japanese
}
Pet.java:
public enum Pet {
dog, fox, snails, horse, zebra
}
Drink.java:
public enum Drink {
orangeJuice, tea, coffee, milk, water
}
Cigarette.java:
public enum Cigarette {
kools, chesterfields, winston, luckyStrike, parliaments
}
And this is my drl file:
package com.sample
import com.sample.fh.*
rule "英国人住在红色的房子里"
when
$h1:House(nation == Nation.englishman, color != Color.red)
$h2:House(color == Color.red)
then
System.out.println("英国人(englishman)住在红色(red)的房子里");
modify($h2){setColor($h1.color)};
modify($h1){setColor(Color.red)};
end
rule "西班牙人养了一条狗"
when
$h1:House(nation == Nation.spaniard)
$h2:House(pet == Pet.dog, nation != Nation.spaniard)
then
System.out.println("西班牙人(spaniard)养了一条狗(dog)");
modify($h2){setPet($h1.pet)};
modify($h1){setPet(Pet.dog)};
end
rule "挪威人住在左边的第一个房子里"
when
$h1:House(position == 1, nation != Nation.norwegian)
$h2:House(nation == Nation.norwegian)
then
System.out.println("挪威人(norwegian)住在左边的第一个房子里");
modify($h2){setNation($h1.nation)};
modify($h1){setNation(Nation.norwegian)};
end
rule "黄房子里的人喜欢抽kools牌的香烟"
when
$h1:House(color == Color.yellow, cigarette != Cigarette.kools)
$h2:House(cigarette == Cigarette.kools)
then
System.out.println("黄房子(yellow)里的人喜欢抽kools牌的香烟");
modify($h2){setCigarette($h1.cigarette)};
modify($h1){setCigarette(Cigarette.kools)};
end
rule "抽chesterfields牌香烟的人与养狐狸的人是邻居"
when
$h1:House(cigarette == Cigarette.chesterfields, pet != Pet.fox)
$h2:House(pet == Pet.fox)
$h3:House(eval(position - $h2.position == 1) || eval(position -
$h2.position == -1))
eval($h1.position - $h2.position != 1 && $h1.position - $h2.position
!= -1)
then
System.out.println("抽chesterfields牌香烟的人与养狐狸(fox)的人是邻居");
int tmp = $h3.position;
modify($h3){setPosition($h1.position)};
modify($h1){setPosition(tmp)};
end
rule "抽chesterfields牌香烟的人与养狐狸的人是同一人"
when
$h1:House(cigarette == Cigarette.chesterfields, pet == Pet.fox)
$h2:House(eval(position - $h1.position == 1) || eval(position -
$h1.position == -1))
then
System.out.println("抽chesterfields牌香烟的人与养狐狸的人是同一人");
modify($h1){setPet($h2.pet)};
modify($h2){setPet(Pet.fox)};
end
rule "挪威人住在蓝色的房子旁边"
when
$h1:House(nation == Nation.norwegian)
$h2:House(color == Color.blue)
$h3:House(eval(position - $h2.position == 1) || eval(position -
$h2.position == -1))
eval($h1.position - $h2.position != 1 && $h1.position - $h2.position
!= -1)
then
System.out.println("挪威人(norwegian)住在蓝色(blue)的房子旁边");
modify($h1){setNation($h3.nation)};
modify($h3){setNation(Nation.norwegian)};
end
rule "抽winston牌香烟的人养了一只蜗牛"
when
$h1:House(cigarette == Cigarette.winston)
$h2:House(pet == Pet.snails, cigarette != Cigarette.winston)
then
System.out.println("抽winston牌香烟的人养了一只蜗牛(Snails)");
modify($h2){setPet($h1.pet)};
modify($h1){setPet(Pet.snails)};
end
rule "抽LuckyStrike牌香烟的人喜欢喝桔子汁"
when
$h1:House(cigarette == Cigarette.luckyStrike)
$h2:House(drink == Drink.orangeJuice, cigarette !=
Cigarette.luckyStrike)
then
System.out.println("抽Lucky Strike牌香烟的人喜欢喝桔子汁(orange juice)");
modify($h2){setDrink($h1.drink)};
modify($h1){setDrink(Drink.orangeJuice)};
end
rule "乌克兰人喜欢喝茶"
when
$h1:House(nation == Nation.ukrainian)
$h2:House(drink == Drink.tea, nation != Nation.ukrainian)
then
System.out.println("乌克兰人(ukrainian)喜欢喝茶(tea)");
modify($h2){setDrink($h1.drink)};
modify($h1){setDrink(Drink.tea)};
end
rule "日本人抽parliaments牌的烟"
when
$h1:House(nation == Nation.japanese)
$h2:House(cigarette == Cigarette.parliaments, nation !=
Nation.japanese)
then
System.out.println("日本人(japanese)抽parliaments牌的烟");
modify($h2){setCigarette($h1.cigarette)};
modify($h1){setCigarette(Cigarette.parliaments)}
end
rule "抽kools牌的香烟的人与养马的人是邻居"
when
$h1:House(cigarette == Cigarette.kools)
$h2:House(pet == Pet.horse)
$h3:House(eval(position - $h2.position == 1) || eval(position -
$h2.position == -1))
eval($h1.position - $h2.position != 1 && $h1.position - $h2.position
!= -1)
then
System.out.println("抽kools牌的香烟的人与养马(horse)的人是邻居");
modify($h1){setCigarette($h3.cigarette)};
modify($h3){setCigarette(Cigarette.kools)};
end
rule "喜欢喝咖啡的人住在绿房子里"
when
$h1:House(drink == Drink.coffee)
$h2:House(color == Color.green, drink != Drink.coffee)
then
System.out.println("喜欢喝咖啡(coffee)的人住在绿(green)房子里");
modify($h2){setColor($h1.color)};
modify($h1){setColor(Color.green)};
end
rule "绿房子在象牙白房子的右边"
when
$h1:House(color == Color.green, position != 1)
$h2:House(color == Color.ivory, position != 5)
$h3:House(eval(position == $h2.position + 1), color != Color.green)
then
System.out.println("绿(green)房子在象牙白(ivory)房子的右边(图中的右边)");
modify($h1){setColor($h3.color)};
modify($h3){setColor(Color.green)};
end
rule "白房子已经在最右边了"
when
$h1:House(color == Color.ivory, position == 5)
$h2:House(color == Color.green, position != 1)
$h3:House(eval(position == $h2.position -1))
then
System.out.println("白房子已经在最右边了");
$h3.setPosition($h1.position);
$h1.setPosition($h2.position - 1);
update($h3);
update($h1);
end
rule "绿房子已经在最左边了"
when
$h1:House(color == Color.green, position == 1)
$h2:House(color == Color.ivory, position != 5)
$h3:House(eval(position == $h2.position + 1))
then
System.out.println("绿房子已经在最左边了");
modify($h3){setPosition($h1.position)};
modify($h1){setPosition($h2.position + 1)};
end
rule "绿房子在最左边且白房子在最右边"
when
$h1:House(color == Color.green, position == 1)
$h2:House(color == Color.ivory, position == 5)
$h3:House()
$h4:House(eval(position - $h3.position == 1))
then
System.out.println("绿房子在最左边且白房子在最右边");
modify($h2){setPosition($h3.position)};
modify($h3){setPosition(5)};
modify($h1){setPosition($h4.position)};
modify($h4){setPosition(1)};
end
rule "中间那个房子里的人喜欢喝牛奶"
when
$h1:House(position == 3, drink != Drink.milk)
$h2:House(drink == Drink.milk)
then
System.out.println("中间那个房子里的人喜欢喝牛奶");
modify($h2){setDrink($h1.drink))};
modify($h1){setDrink(Drink.milk)};
end
rule "output"
when
$h1:House(position == 1)
$h2:House(position == 2)
$h3:House(position == 3)
$h4:House(position == 4)
$h5:House(position == 5)
House(nation == Nation.englishman, color == Color.red)
House(nation == Nation.spaniard, pet == Pet.dog)
House(position == 1, nation == Nation.norwegian)
House(color == Color.yellow, cigarette == Cigarette.kools)
$h6:House(cigarette == Cigarette.chesterfields)
$h7:House(pet == Pet.fox)
eval($h6.position - $h7.position == 1 || $h6.position - $h7.position
== -1)
$h8:House(nation == Nation.norwegian)
$h9:House(color == Color.blue)
eval($h8.position - $h9.position == 1 || $h8.position - $h9.position
== -1)
House(cigarette == Cigarette.winston, pet == Pet.snails)
House(cigarette == Cigarette.luckyStrike, drink ==
Drink.orangeJuice)
House(nation == Nation.ukrainian, drink == Drink.tea)
House(cigarette == Cigarette.parliaments, nation == Nation.japanese)
$h10:House(cigarette == Cigarette.kools)
$h11:House(pet == Pet.horse)
eval($h10.position - $h11.position == 1 || $h10.position -
$h11.position == -1)
House(drink == Drink.coffee, color == Color.green)
$h12:House(color == Color.green)
$h13:House(color == Color.ivory)
eval($h12.position - $h13.position == 1)
House(position == 3, drink == Drink.milk)
then
System.out.println("从左到右:");
System.out.println("第一间房子是"+$h1.color+"色的;住着"+$h1.nation+"人;养"+$h1.pet+"宠物;抽"+$h1.cigarette+"牌香烟;喝"+$h1.drink+"饮料;");
System.out.println("第二间房子是"+$h2.color+"色的;住着"+$h2.nation+"人;养"+$h2.pet+"宠物;抽"+$h2.cigarette+"牌香烟;喝"+$h2.drink+"饮料;");
System.out.println("第三间房子是"+$h3.color+"色的;住着"+$h3.nation+"人;养"+$h3.pet+"宠物;抽"+$h3.cigarette+"牌香烟;喝"+$h3.drink+"饮料;");
System.out.println("第四间房子是"+$h4.color+"色的;住着"+$h4.nation+"人;养"+$h4.pet+"宠物;抽"+$h4.cigarette+"牌香烟;喝"+$h4.drink+"饮料;");
System.out.println("第五间房子是"+$h5.color+"色的;住着"+$h5.nation+"人;养"+$h5.pet+"宠物;抽"+$h5.cigarette+"牌香烟;喝"+$h5.drink+"饮料;");
end
There's some unicode character in the file.But it shouldn't bother the
compilation>...<
The rule named 'output' describes when the computation should stop. The
other rules are absorbed from the original 'Zebra puzzle' problem and each
making a little change to the working memory in order to 'approach' the
solution...(I don't know if I'm doing this wrong..)
No matter how I modify this program, it always result in an infinite loop...
For example, the console prints these messages repeatedly:
白房子已经在最右边了
抽chesterfields牌香烟的人与养狐狸的人是同一人
抽kools牌的香烟的人与养马(horse)的人是邻居
黄房子(yellow)里的人喜欢抽kools牌的香烟
抽kools牌的香烟的人与养马(horse)的人是邻居
黄房子(yellow)里的人喜欢抽kools牌的香烟
抽kools牌的香烟的人与养马(horse)的人是邻居
黄房子(yellow)里的人喜欢抽kools牌的香烟
抽kools牌的香烟的人与养马(horse)的人是邻居
黄房子(yellow)里的人喜欢抽kools牌的香烟
抽kools牌的香烟的人与养马(horse)的人是邻居
黄房子(yellow)里的人喜欢抽kools牌的香烟
......................
I worked quite much time on this problem till now, and I referenced another
solution which is programmed in prolog, but still I didn't figured out the
drools solution to this problem.
Could somebody give a hint? Any help is appreciated,
Thanks!
--
Regards.
Miles. Wen