Can I solve the 'Zebra Puzzle' in drools?
by Miles Wen
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
14 years, 9 months
drools-ant
by Abhay B. Chaware
How do I compile only rule (.drl) files into packages ? I read that drools-ant can be used to compile rules, but not getting any information about using the drools-ant. How do I use drools-ant ? Is that the only way to compile rules ? Any other options ?
-abhay
14 years, 9 months
How does Drools support Notifications?
by Jay
Hi there,
As I associate Notification and Deadline with HumanTask node, that is,
extend the HumanTask node with params of Notification(e.g. notification
name/priority/description/recipients..etc), params of Deadline(StartDeadline
and EndDeadline).
What I want is: if deadline is missed, an email notification can be sent to
the recipients. And according to the 2nd constructor of
TaskService(org.drools.task.service.TaskService) and
DefaultEscalatedDeadlineHandler, I can construct the TaskService with a
DefaultEscalatedDeadlineHandler to handle the notification in TaskServer.
But, will it work? According to WS-HumanTask spec, if a task has not been in
"InProgress" state, notification sent, but where will it check the state of
task? Because if the task has been in "InProgress" state, notification can't
be sent. EndDeadline also has a similar story.
So how does Drools support Notification? Because according to this
post:http://blog.athico.com/2008/09/drools-and-ws-humantask.html, it has
been fixed.
Any advice is highly appreciated.
Thanks,
Jay
--
View this message in context: http://drools.46999.n3.nabble.com/How-does-Drools-support-Notifications-t...
Sent from the Drools: User forum mailing list archive at Nabble.com.
14 years, 9 months
Guvnor 5.2 CR1 : problem with collect in guided editor
by Vincent LEGENDRE
Hi all
We gave a try with the CR1 version, and see that all "collect" clauses appears in grey and are not editable (such conditions are also not deletable). Everything was OK with the M2 version (rules were edited with this version).
It is quite strange because all the "collect" condition is greyed, just like a disabled field, and seems to be done by purpose. Is "collect" deprecated ?
Does anyone has the problem ?
14 years, 9 months
Agregate function count, the rule doesn't activates.
by Nicolás Sanchez
Hi,
I have written the next rule :
rule "Too many events in a short period of time"
dialect "mvel"
when
$user : User()
Number(intValue > 3) from accumulate($event : Event(userId == $user.id)
over window:time(1m) from entry-point Event , count($event))
then
//Java code...
end
And the events, I insert in the Event entrypoint, are 4 and have these
timestamps:
Calendar cal1 = Calendar.getInstance();
cal1.set(2010,9,23,10,30,00);
Calendar cal2 = Calendar.getInstance();
cal2.set(2010,9,23,10,30,05);
Calendar cal3 = Calendar.getInstance();
cal3.set(2010,9,23,10,30,10);
Calendar cal4 = Calendar.getInstance();
cal4.set(2010,9,23,10,30,15);
Has the rule any syntax or semantic problem, knowing that i aim to catch if
there has been more than 3 events in the last minute?
--
Nicolás Sanchez
14 years, 9 months
Drools/Camel Integration sending messages
by Andre
hi,
i´m new in the drools-dev family and just playing around: while playing, i
can´t get over the following problem:
i configurated drools/camel/activeMQ, i also receive messsages and can
maipulate the endpoints and so on but when i try to create a new exchange
(actually i´m copying on older one, because trying to type new JmsMessage()
ends in an "could not resolve constructor
org.apache.camel.component.jms.JmsMessage[]")
So at the end ,if i´m just manipulating an copied exchange, the exchange
will not be send by camel directly.
my Question is:
How do i use the drools/camel Integration Component to send
exchanges/messages out of the drl/then-part?
or which context can i use in the drl (e.g: DroolsEndpoint properties)/ is
there any context available?
thx, André
--
View this message in context: http://drools.46999.n3.nabble.com/Drools-Camel-Integration-sending-messag...
Sent from the Drools: User forum mailing list archive at Nabble.com.
14 years, 9 months
Is asterisk no longer valid in temporal constaints?
by Nathan Bell
In 5.1 this was valid syntax:
rule "OrderActiveInLast7Days"
when
$order : DrugOrder((start != null && start before $now),
(stop == null || stop after[-7d,*] $now))
then
#stuff
end
In 5.2.0.CR1 it complains about the asterisk. Is that no longer
supported?
The error I get is "no viable alternative at input '(' in rule
"OrderActiveInLast7Days"". If I remove the part of the constraint in
brackets "[-7d,*]" then it compiles.
Thank You,
Nathan Bell
14 years, 9 months
execute once for an accumulate
by dwipin
I have the following condition and consequence in one of my rules -
when
$position : PositionValuation() // returns 4 records
eval(helper.isSameDay($position.cobDate, $request.cobDate)) // filters 1,
so count =3
$pnl : PnL() from $position.pnl
$totalPnlValue : BigDecimal()
from accumulate(PnLTimeValue(type == "TOTAL", $pnlAmount : grc.value)
from $pnl.dtdAmount ,sum($pnlAmount))
then
logger.debug("variance :"+$totalPnlValue);
exception.setOrganisation($position.organisation);
exception.setCobDate($position.cobDate);
exception.setOrganisation($position.organisation);
exception.setTrade($position.trade);
$outputList.add(exception);
I want to have have the rule executed once for the accumulated value. How do
I achieve this?
Currently this gets executed 3 times.
Thanks,
Dwipin.
--
View this message in context: http://drools.46999.n3.nabble.com/execute-once-for-an-accumulate-tp305942...
Sent from the Drools: User forum mailing list archive at Nabble.com.
14 years, 9 months
Error opening process in Oryx editor (designer-1.0.0.052)
by Grzegorz Błaszczyk
Hi,
I started with a fresh JBoss installation:
* jbpm-5.0.0-installer-full.zip
** designer-1.0.0.052
** jboss-5.1.0.GA
** drools-guvnor 5.2.0.M1
** drools-5.2.0.M1
** eclipse-helios
There was a tiny problem with h2 artifact - it should be downloaded
from a different location (dedicated Nexus in JBoss.org network).
Things done after the installation:
1. samples in Guvnor installed
2. DRL and BPMN files of our process file and subprocesses from a
dedicated eclipse to Guvnor uploaded
3. package classes filtered out and package validated
4. package compiled
Up to now this went smootly.
After that when I open a process editor (Oryx) in Guvnor I get:
java.lang.IllegalArgumentException: No profile with the name drools
was registered
org.oryxeditor.server.EditorHandler.doGet(EditorHandler.java:286)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
com.intalio.web.filter.impl.PluggableFilter.doFilter(PluggableFilter.java:75)
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
In JBoss console I get the same:
ERROR [EditorHandler] No profile with the name drools was registered
ERROR [[EditorHandler]] Servlet.service() for servlet EditorHandler
threw exception
java.lang.IllegalArgumentException: No profile with the name drools
was registered
at org.oryxeditor.server.EditorHandler.doGet(EditorHandler.java:286)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.intalio.web.filter.impl.PluggableFilter.doFilter(PluggableFilter.java:75)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:662)
I added a role in Guvnor named 'drools' with admin privileges but it
didn't solve the problem.
What should I configure to have a 'drools' profile and be able to open
the process in Oryx editor ?
Best regards,
Grzegorz Blaszczyk
14 years, 9 months