Progress with the RuleCompiler
Finally! It's starting to feel like I'm getting somewhere with PyRete's RuleCompiler. Earlier this week I decided to change quite a lot about the allowed syntax in a rule.
I've always kind of thought I'd have to have support for expressing rules in many different ways. For instance, I've tried to support at least three different approaches to expressing:
|CLIPS>(defrule ruleThis way, which used to be the preferred way, you would write the rule as if you were writing procedural code:
| (foo (attribute ?attr&:(> ?attr 10)))
| (bar (attribute ?attr))
| =>)
>>> @prodsys.ruleAnother way, which always felt a bit weird and unnatural to me, was to use a (logical) variable:
... def rule(engine, foo = Foo, bar = Bar):
... if foo.attribute == bar.attribute and \
... foo.attribute > 10:
... pass
>>> @prodsys.ruleThe problem with it, and the reason I don't like it, is that it's not all that clear what is going to happen. There's no way of telling that attr is a logical variable and that makes it look like it's three ordinary comparisons, but it's not. In any other context the code would raise an Exception because the local variable attr is unbound and that's probably how most Python programmers will read it.
... def rule(engine, foo = Foo, bar = Bar):
... if foo.attribute == attr and \
... bar.attribute == attr and \
... attr > 10:
... pass
I thought that the above would cause a lot of confusion which is why I implemented another way of expressing the same thing which looks a lot more like the pattern-matching syntax of CLIPS:
>>> @prodsys.ruleThis is, of course, also slightly problematic but at least there's no interpretation of the code that completely shadows how it's being used in PyRete.
... def rule(engine, foo = Foo, bar = Bar):
... if foo(attribute == attr and attr > 10) and \
... bar(attribute == attr):
... pass
It wasn't until I decided, quite recently, that I'll only support the last type of syntax (pattern matching-style) that I started to get somewhere with the RuleCompiler. It also meant that I could get rid of the object bindings in the parameter list.
The above rule should be written as:
>>> @prodsys.ruleIt's only too bad that it takes me so long to figure these things out.
... def rule(engine):
... if Foo(attribute == attr and attr > 10) and \
... Bar(attribute == attr):
... pass
3 kommentarer:
that's cuz it's not easy :)
plus, if it was easy, it wouldn't be as rewarding.
True!
It's just that I feel like a brute-force search implementation in O(n^2) land and my self-image is more of a best-first search implementation :-)
haha. that's a simple problem to solve. I think of myself as a O(n^10) algorithm, so if I managed to do it faster, it's a success.
though often times, I find that pure dumb luck and banging my head randomly shortens the search time to O(n^2).
Skicka en kommentar