-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EXISTS doesn't want to match #8
Comments
Hi, I am a little confused about the provided code. The patterns inside the EXISTS CE of your rule (FeverGreaterThanFourDays, ConjunctivalInjection) don't seems to match with the FactLists that you provided. Some things that seems weird to me are:
I prepared this example to illustrate the use of EXISTS. If you can provide a more concise example of what you are trying to achieve it would be very helpful. |
Here is a more detailed use case. I'm looking at producing a preliminary and final risk score. The preliminary risk score is calculated from available data, not complete data, and should be produced using as many of the defined criteria that are available. A final score, in contrast, must have all defined criteria set to either present or absent. For the sake of argument, consider a score function that includes 4 observation criteria: o1, o2, o3, o4. Each observation can be modeled as fact with attribute "present" that is True if the observed criteria is present, or false if is not. If a given observation, e.g. fever, has not been evaluated, no observation fact for fever is declared. Both a preliminary score and a final score can be calculated when all four facts (o1, o2, o3, o4) are declared in the knowledge base, as in this example: o1 - present Then consider this case where only two observation facts are declared in the KB: Here a final score cannot be calculated as all four observations have not been explicitly evaluated as either present or absent. However, there is enough information to calculate a preliminary score of 2, because o1 and o4 have been set to present (i.e. True). DECLARE seems like the right way to define a rule to calculate the preliminary score. It would be written as: DECLARE(o1, o2, o3, o4) and should match as many facts as possible, binding attributes appropriately. AND(o1, o2, o3, o4) is what I am using for the final score. Let me know if this clears things up. Thanks! |
I think I understand your needs. I prepared this proof of concept about the MAYBE operator. Please, tell me if this helps. from experta import *
def MAYBE(*patterns):
return AND(
*[OR(p, NOT(p)) for p in patterns]
)
class FeverGreaterThanFourDays(Fact):
pass
class ConjunctivalInjection(Fact):
pass
class PolymorphousRash(Fact):
pass
class PeripheralEdema(Fact):
pass
class KE(KnowledgeEngine):
@Rule(
MAYBE(
AS.f1 << FeverGreaterThanFourDays(
patient_id=MATCH.patient_id,
appointment_id=MATCH.appointment_id,
weight=MATCH.fever_weight,
present=W(),
),
AS.f2 << ConjunctivalInjection(
patient_id=MATCH.patient_id,
appointment_id=MATCH.appointment_id,
weight=MATCH.conjunctival_weight,
present=W(),
),
AS.f3 << PolymorphousRash(
patient_id=MATCH.patient_id,
appointment_id=MATCH.appointment_id,
weight=MATCH.polymorphous_weight,
present=W(),
),
AS.f4 << PeripheralEdema(
patient_id=MATCH.patient_id,
appointment_id=MATCH.appointment_id,
weight=MATCH.peripheral_weight,
present=W(),
)
)
)
def something(self, f1=None, f2=None, f3=None, f4=None):
print("Score:", len(list(filter(None, [f1, f2, f3, f4]))))
k=KE()
k.reset()
k.declare(ConjunctivalInjection(patient_id=1, appointment_id=2, weight=15, present=True))
k.declare(FeverGreaterThanFourDays(patient_id=1, appointment_id=2, weight=12, present=True))
k.declare(PolymorphousRash(patient_id=1, appointment_id=2, weight=0, present=False))
# k.declare(PeripheralEdema(patient_id=1, appointment_id=2, weight=1, present=True))
k.run() |
Hi, I have problem with from experta import *
class FactOne(Fact):
name = Field(str)
class FactTwo(Fact):
name = Field(str)
class MyEngine(KnowledgeEngine):
@DefFacts()
def load(self):
yield FactOne(name = 'aaaaaaaaa')
yield FactTwo(name = 'bbbbbbbbb')
@Rule(
FactOne(name = MATCH.name),
EXISTS(
FactTwo(name = MATCH.name)
)
)
def my_rule(self, name):
print('my_ryle is activated, name: {0}'.format(name))
e = MyEngine() than I get
but also
This is not expected behavior (at least it shouldn't be) |
I have a rule with this structure:
These are some sample facts:
If I replace "EXISTS" with "OR", I can get matches almost as documented--basically I see the rule fire for each fact that matches. Unfortunately this is not what the doc says--it says it should fire for each combination of facts that match, so I'd expect to see it fire on individual facts, then pairs, then triples, etc. I suspect this is just an error in the docs.
This is the result using "OR":
However, with the same set of facts that match with OR, if I change from OR to EXISTS it ceases matching. My expectation is that the rule will fire once, and that the associated function will receive all the weight parameters for matching facts. Instead none of the facts match...
It seems like EXISTS is critical for "aggregating" information from multiple facts. If this is not the intended behavior of EXISTS, is there something else I should use? I need to be able to reason on the largest collection of facts in a set that match.
Let me know if there is a different approach I should use.
The text was updated successfully, but these errors were encountered: