[rules-dev] else

Mark Proctor mproctor at codehaus.org
Sun Aug 21 09:06:30 EDT 2011


On 21/08/2011 13:45, Wolfgang Laun wrote:
>
>
> On 20 August 2011 21:05, Michael Anstis <michael.anstis at gmail.com 
> <mailto:michael.anstis at gmail.com>> wrote:
>
>     I like Mario's suggestion.
>
>     Use of a switch statement could also be an option (to muddy the
>     waters further):-
>
>
> Any good reason for calling a "switch" what is usually an if/elsif? 
> Also, would the branches have an implied "break"? Or should any number 
> of branches fire for a single match of the CEs preceding the "switch"? 
> If so, what if "a1" (in the example) retracts tha fact matching "D()", 
> and then "a2" needs to be executed?
>
> Anybody making proposals is cordially invited not just to provide a 
> syntax silhouette.
>
> Thank you
> -W
>
>
>     rule R1
>         when
>             D()
>             switch
>                 A()
>                   then
>                       a1
>                 B()
>                   then
>                       b1
>                 C()
>                   then
>                       c1
>             switch
>         then
>             d1
>     end
>
>     I definitely don't like the ">" "{..}" notation.
>
>     Cheers,
>
>     Mike
>
>     On 20 August 2011 00:34, Mark Proctor <mproctor at codehaus.org
>     <mailto:mproctor at codehaus.org>> wrote:
>
>         For further info, this is what ilog do. They only allow an
>         implicit "else" on the last "evaluate" expression. Which while
>         simple is quite restrictive.:
>         http://publib.boulder.ibm.com/infocenter/brjrules/v7r1/index.jsp?topic=/com.ibm.websphere.ilog.jrules.doc/Content/Business_Rules/Documentation/_pubskel/JRules/ps_JRules_Global1895.html
>
>         rule  ruleName  {
>             when
>                {conditioni  evaluate (expression)}
>             then
>                 {[action1...actionm]}
>             else
>                 {[action1  ...actionp]}
>         };
>
>         OPSJ is the only engine that i know of that uses labels:
>
>         x.name  <http://x.name>  == obj,
>         x.weight == "light",
>         x.location != g.location);
>         mky: monkey;
>         [4] (mky.holds == obj);
>         } do {
>         makegoal("walkto", loc);
>         } else( 4 ) {
>         makegoal("holds", obj);
>         }
>
>         Although I would encourage people to think beyond simple
>         "if/else", the proposal I put forward would allow for tree
>         like data flows for signal processing - which will map very
>         nicely to GUI tooling.
>
I proposed something like this, based around the OPSJ labels approach. 
It helps if you think of a "then" block as a function literal and the 
{func_lit_name} as an inline code fragment that calls the function literal.
So this:
$o : Object() from stream
( A() | {a} from $o or
   B() | {b} from $o or
   C() | {c} from $o )

becomes:
case( Object() from stream; // notice the semi colon to separate the 
object that specifies the default 'from'
           A() | {a},
           B() | {b},
           C() | {c} )
then
...
then.a
....
then.b
....
then.c
end.

The above would currently work like 'or'. All matching branches would 
activate. I thought about a short cut or. I think the answer there is to 
build a prolog like 'cut' operator, which we need for queries anyway. 
However adding 'cut' is far from trivial as it'll involve substantial 
changes to the current Rete algorithm, but assuming we could eventually 
make those changes, maybe something like:
case( Object() from stream; // notice the semi colon to separate the 
object that specifies the default 'from'
           A() | {a} | cut,
           B() | {b}| cut,
           C() | {c} | cut)

When thinking about the | symbol, think of unix pipes. The pipe 
indicates to filter the output of the pattern, the pipe allows chaining 
of these "filters", much like unix, such that the propagation then goe 
sfrom the labelled "functional literal" to the cut CE. I plan to allow 
the | symbol to be used to integrate user pluggable filters, such as 
"distinct". The following will filter all A() matches using a distinct 
filter, making sure only distinct matches are execute by the "a" 
functional literal. The cut symbpol ensures that only the first match is 
found, all other matches (join attempts) will be stopped - including 
those in the various 'or' branches if they exist.
A() | distinct | {a} | cut

For consistency we will allow time windows to be used as filters. Over 
the last 30 seconds find the distinct A and activate on it, but do not 
find any more matches after that.
A() | time.window(30s) | distinct | {a} | cut.

Hopefully that shows why I want to introduce a general purpose "|" pipe 
symbol for connecting "filters" and use that in a very generic way. 
Rather than introducing various different keywords.

This syntax is not aimed at business users, who will be using the guided 
editor anyway and the verbalisations that come with that, even more so 
true once we start to add natural language. So I'm not overly keen to 
restrict or limit things for a group of people won't use the low level 
syntax anyway.


Mark
>
>
>         Mark
>
>
>
>         On 19/08/2011 13:56, Toni Rikkola wrote:
>>         I got the same feeling that Geoffrey had about readability.
>>
>>         We added "from" its really easy to get, why not add "else".
>>
>>         when
>>             Person( name == "darth" )  else  [darthIsMissing]
>>             A()
>>         then
>>            ....
>>         then.darthIsMissing
>>           log("Darth was never found");
>>         end
>>
>>         or
>>
>>         when
>>             Person( name == "darth" )  else  { log("Darth was never
>>         found"); }
>>             A()
>>         then
>>            ....
>>         end
>>
>>         "Inline then" could be done with inner rules. Similar to what
>>         Mario suggested.
>>
>>         rule "Handle Login"
>>           when
>>             $loginRequest :LoginRequest()
>>             AuthorizedUsers( list contains $loginRequest.user ) else
>>         [unsuccessfulLoginAttempt]
>>
>>               inner rule "Check if Admin"
>>                  $p :AdminRights( user == $loginRequest.user )
>>               then
>>                  showAdminMenu();
>>                end
>>
>>           then
>>             logInUser( $loginRequest.user );
>>
>>           then.unsuccessfulLoginAttempt
>>             log( "There was and unsuccessful login attempt with the
>>         user name " + $loginRequest.user.name
>>         <http://loginRequest.user.name> );
>>         end
>>
>>         Toni
>>
>>         On Aug 19, 2011, at 2:59 PM, Geoffrey De Smet wrote:
>>
>>>         I like Mario's proposal because I can actually read it.
>>>         Those special chars | < are gibberish to me.
>>>
>>>         The only reason we're not debating to use a new readable,
>>>         intuitive keyword, is because of the back-wards
>>>         compatibility issues involved.
>>>         But using unreadable, unintuitive special char just for
>>>         that, is probably not a good idea.
>>>         I wonder if we reserve new keywords by prefix them with
>>>         reserved special char like "@"?
>>>         Then we can introduce as many keywords as we want without
>>>         breaking backwards compatibility.
>>>
>>>         Who's our target users for DRL authors?
>>>         A) Supersmart computer science guys
>>>         B) Blue collar Java programmers
>>>         C) Domain experts (= not programmers)
>>>
>>>         I 'd classify "{notA} < A()" as (given some time to learn
>>>         it) readable for A, but not for B and C.
>>>
>>>         Op 18-08-11 23:35, Mario Fusco schreef:
>>>>         Hi Mark,
>>>>
>>>>         Since you're gathering 2 cents here and there I decided to
>>>>         add also mine even if I am pretty sure that I am still
>>>>         missing the whole picture and anyway at the moment I cannot
>>>>         see all the consequences of what I am going to propose.
>>>>
>>>>         To tell you the truth I find the label syntax not very
>>>>         intuitive and I was wondering if we could avoid it in some
>>>>         way. In the end what the 90% of the users are asking for is
>>>>         just something like:
>>>>
>>>>         rule R
>>>>             when
>>>>                 A()
>>>>             then
>>>>                 do something
>>>>             else
>>>>                 do something else
>>>>         end
>>>>
>>>>         while we are going to give them something that is not
>>>>         exactly the same:
>>>>
>>>>         rule R
>>>>             when
>>>>                 {notA} < A()
>>>>             then
>>>>                 do something
>>>>             then.notA
>>>>                 do something else
>>>>         end
>>>>
>>>>         In particular I was thinking if we could keep the when ...
>>>>         then ... else syntax that should be familiar to the biggest
>>>>         part of the users and at the same time obtain a flexibility
>>>>         similar to the one provided by the labels syntax. Probably
>>>>         we could do it with a kind of nested rules so, for
>>>>         instance, the rule:
>>>>
>>>>         rule R1
>>>>             when
>>>>                 {af} < A() > {at}
>>>>                 B()
>>>>             then
>>>>                 DO
>>>>         then.af <http://then.af/>
>>>>                 DO.af
>>>>         then.at <http://then.at/>
>>>>         DO.at <http://DO.at>
>>>>         end
>>>>
>>>>         could be rewritten as it follows:
>>>>
>>>>         rule R1
>>>>             when
>>>>                 B()
>>>>             then
>>>>                 DO
>>>>                 rule R1A
>>>>                     when
>>>>                         A()
>>>>                     then
>>>>         DO.at <http://DO.at>
>>>>                     else
>>>>                         DO.af
>>>>                 end
>>>>         end
>>>>
>>>>         Of course the nested rule couldn't be used by the Drools
>>>>         engine as it is, but we could implement a kind of
>>>>         "linearization" process at compile time that translates it
>>>>         more or less as:
>>>>
>>>>         rule R1_1
>>>>             when
>>>>                 A()
>>>>                 B()
>>>>             then
>>>>                 DO
>>>>         DO.at <http://DO.at>
>>>>         end
>>>>
>>>>         rule R1_2
>>>>             when
>>>>                 not A()
>>>>                 B()
>>>>             then
>>>>                 DO
>>>>                 DO.af
>>>>         end
>>>>
>>>>         In the same way the "or" example:
>>>>
>>>>         rule R1
>>>>         when
>>>>             (     A() > {a1} or
>>>>                 B() > {b1} or
>>>>                 C() > {c1} )
>>>>             D()
>>>>         then
>>>>             DO
>>>>         then.a1
>>>>             DO.a1
>>>>         then.b1
>>>>             DO.b1
>>>>         then.c1
>>>>             DO.c1
>>>>         end
>>>>
>>>>         could be written as:
>>>>
>>>>         rule R1
>>>>             when
>>>>                 D()
>>>>             then
>>>>                 DO
>>>>                 rule R1A
>>>>                     when
>>>>                         A()
>>>>                     then
>>>>                         DO.a1
>>>>                 end
>>>>                 rule R1B
>>>>                     when
>>>>                         B()
>>>>                     then
>>>>                         DO.b1
>>>>                 end
>>>>                 rule R1C
>>>>                     when
>>>>                         C()
>>>>                     then
>>>>                         DO.c1
>>>>                 end
>>>>         end
>>>>
>>>>         and then linearized at compile time in a similar way as I
>>>>         wrote before.
>>>>
>>>>         Once again I still haven't evaluated all the implications
>>>>         of my suggestion neither I know if we can cover with it all
>>>>         the cases proposed by Mark. I am pretty sure I am missing
>>>>         something important to be honest, but since we are in a
>>>>         "brainstorming phase" I thought it could worth to consider
>>>>         it at least.
>>>>
>>>>         My 2 cents,
>>>>         Mario
>>>>
>>>>
>>>>         _______________________________________________
>>>>         rules-dev mailing list
>>>>         rules-dev at lists.jboss.org  <mailto:rules-dev at lists.jboss.org>
>>>>         https://lists.jboss.org/mailman/listinfo/rules-dev
>>>
>>>         -- 
>>>         With kind regards,
>>>         Geoffrey De Smet
>>>         _______________________________________________
>>>         rules-dev mailing list
>>>         rules-dev at lists.jboss.org <mailto:rules-dev at lists.jboss.org>
>>>         https://lists.jboss.org/mailman/listinfo/rules-dev
>>
>>
>>
>>         _______________________________________________
>>         rules-dev mailing list
>>         rules-dev at lists.jboss.org  <mailto:rules-dev at lists.jboss.org>
>>         https://lists.jboss.org/mailman/listinfo/rules-dev
>
>
>
>         _______________________________________________
>         rules-dev mailing list
>         rules-dev at lists.jboss.org <mailto:rules-dev at lists.jboss.org>
>         https://lists.jboss.org/mailman/listinfo/rules-dev
>
>
>
>     _______________________________________________
>     rules-dev mailing list
>     rules-dev at lists.jboss.org <mailto:rules-dev at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/rules-dev
>
>
>
>
> _______________________________________________
> rules-dev mailing list
> rules-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-dev/attachments/20110821/fb844f5c/attachment-0001.html 


More information about the rules-dev mailing list