Beispiel #1
0
 class Test(KnowledgeEngine):
     @Rule(
         FORALL(Fact(key_a="k" << W()), Fact(key_b="k" << W()),
                Fact(key_c="k" << W())))
     def any_fact_once(self):
         nonlocal executed
         executed += 1
Beispiel #2
0
def test_featurecheck_call_or():
    """
    Or is normally not checked with FeatureCheck because is normalized
    out during DNF.

    """
    from experta.matchers.rete.check import FeatureCheck
    from experta import L, P, W, Fact

    check = FeatureCheck(0, L('mydata') | P(lambda _: True) & W())
    assert check(Fact('mydata'))
    check = FeatureCheck(0, L('mydata') | W('X'))
    assert check(Fact('mydata')) is True

    check = FeatureCheck(0, W('X') | L('mydata'))
    assert check(Fact('mydata')) == {'X': 'mydata'}

    check = FeatureCheck(0, L('mydata') | ~L('otherdata'))
    assert check(Fact('mydata'))
    check = FeatureCheck(0, ~L('otherdata') | L('mydata'))
    assert check(Fact('mydata'))

    check = FeatureCheck(0, ~L('mydata') | L('otherdata'))
    assert not check(Fact('mydata'))
    check = FeatureCheck(0, L('otherdata') | ~L('mydata'))
    assert not check(Fact('mydata'))
Beispiel #3
0
def test_featurecheck_is_borg_basic_wildcard():
    from experta.matchers.rete.check import FeatureCheck
    from experta import W

    assert FeatureCheck('somekey', W('X')) \
        is FeatureCheck('somekey', W('X'))

    assert FeatureCheck('somekey', W('X')) \
        is not FeatureCheck('somekey', W('Y'))
Beispiel #4
0
def test_featurecheck_call_not_wildcard():
    from experta.matchers.rete.check import FeatureCheck
    from experta import W, Fact

    # Positional match (negated)
    check = FeatureCheck(0, ~W())
    assert not check(Fact('somedata'))

    # Positional match (negated) with binding
    check = FeatureCheck(0, ~W('X'))
    assert check(Fact('somedata')) == {(False, 'X'): 'somedata'}
Beispiel #5
0
def test_featurecheck_call_and():
    from experta.matchers.rete.check import FeatureCheck
    from experta import L, P, W, Fact

    # Positional, composed and matching 
    check = FeatureCheck(0, L('mydata') & P(lambda _: True) & W())
    assert check(Fact('mydata'))


    # Positional, composed and matching (with binding)
    check = FeatureCheck(0, L('mydata') & W('X'))
    assert check(Fact('mydata')) == {'X': 'mydata'}

    # Positional, composed and matching (with binding negated)
    check = FeatureCheck(0, L('mydata') & ~W('X'))
    assert check(Fact('mydata')) == {(False, 'X'): 'mydata'}
Beispiel #6
0
    class KE(KnowledgeEngine):
        @DefFacts()
        def _initial_action(self):
            yield Fact(action="greet")

        @Rule(Fact(action='greet'), NOT(Fact(name=W())))
        def ask_name(self):
            self.declare(Fact(name="foo"))

        @Rule(Fact(action='greet'), NOT(Fact(location=W())))
        def ask_location(self):
            self.declare(Fact(location="bar"))

        @Rule(Fact(action='greet'), Fact(name=MATCH.name),
              Fact(location=MATCH.location))
        def greet(self, name, location):
            nonlocal executed
            executed = (name, location)
Beispiel #7
0
class RandomFracEngine(KnowledgeEngine):
    @Rule(Fact(id=MATCH.id, contentEditable=True, value=W()))
    def input_random(self, id):
        return Sai(selection=id,
                   action='UpdateTextArea',
                   inputs={'value': str(randint(0, 100))})

    @Rule(Fact(id='done'))
    def click_done(self):
        return Sai(selection='done',
                   action='ButtonPressed',
                   inputs={'value': -1})
Beispiel #8
0
def test_featurecheck_call_wildcard():
    from experta.matchers.rete.check import FeatureCheck
    from experta import W, Fact

    # Positional field not present
    check = FeatureCheck(0, W())
    assert not check(Fact())

    # Positional field present
    check = FeatureCheck(0, W())
    assert check(Fact('something'))

    # Named field not present
    check = FeatureCheck('mykey', W())
    assert not check(Fact(otherkey='something'))

    # Named field present
    check = FeatureCheck('mykey', W())
    assert check(Fact(mykey='something'))

    # Binding present
    check = FeatureCheck(0, W('X'))
    assert check(Fact('something')) == {'X': 'something'}

    # Binding not present
    check = FeatureCheck(0, W('X'))
    assert check(Fact()) is False
Beispiel #9
0
def test_declare_raises_typeerror_if_conditionalelement_found():
    from experta import KnowledgeEngine, L, W, P, Fact

    ke = KnowledgeEngine()

    with pytest.raises(TypeError):
        ke.declare(Fact(L(1)))

    with pytest.raises(TypeError):
        ke.declare(Fact(W()))

    with pytest.raises(TypeError):
        ke.declare(Fact(P(lambda _: True)))

    with pytest.raises(TypeError):
        ke.declare(Fact(~L(1)))

    with pytest.raises(TypeError):
        ke.declare(Fact(L(1) | L(2)))

    with pytest.raises(TypeError):
        ke.declare(Fact(L(1) & L(2)))
Beispiel #10
0
 class Person_KE(KnowledgeEngine):
     @Rule(NOT(ConflictResolver(resolved=True)),
           AND(Person(age=W('age')), Person(age=~W("age"))))
     def same_name(self, age):
         nonlocal executions
         executions.append(age)
Beispiel #11
0
 class Person_KE(KnowledgeEngine):
     @Rule(Person(age=W('age')), Person(age=~W("age")))
     def same_name(self, age):
         nonlocal executions
         executions.append(age)
Beispiel #12
0
 class Person_KE(KnowledgeEngine):
     @Rule(Person(name=W("name")), NOT(Person(surname=W('name'))))
     def same_name(self, name):
         nonlocal executions
         executions.append(name)
Beispiel #13
0
 class Test(KnowledgeEngine):
     @Rule(Fact(a=W('X'), b=W('X')))
     def rule1(self, X):
         nonlocal result
         result.append(X)
Beispiel #14
0
class Bipolar(KnowledgeEngine):
    """
    Coleta dos dados
    """

    @Rule(Sintomas(verifica_humor_deprimido=None))
    def ask_verifica_humor_deprimido(self):
        self.declare(Sintomas(verifica_humor_deprimido=ask(
            "verifica_humor_deprimido? ")))

    @Rule(Sintomas(fisiologico=None))
    def ask_data_fisiologico(self):
        self.declare(Sintomas(fisiologico=ask("fisiologico? ")))

    @Rule(Sintomas(prejuizo_social=None))
    def ask_data_prejuizo_social(self):
        self.declare(Sintomas(prejuizo_social=ask("prejuizo_social? ")))

    @Rule(Sintomas(prejuiso_profissional=None))
    def ask_data_prejuiso_profissional(self):
        self.declare(
            Sintomas(prejuiso_profissional=ask("prejuiso_profissional? ")))

    @Rule(Sintomas(prejuizo_si=None))
    def ask_data_prejuizo_si(self):
        self.declare(Sintomas(prejuizo_si=ask("prejuizo_si? ")))

    @Rule(Sintomas(prejuizo_outros=None))
    def ask_data_prejuizo_outros(self):
        self.declare(Sintomas(prejuizo_outros=ask("prejuizo_outros? ")))

    @Rule(Sintomas(psicose=None))
    def ask_data_psicose(self):
        self.declare(Sintomas(psicose=ask("psicose? ")))

    @Rule(NOT(Sintomas(autoestima_inflada=W())))
    def ask_data_autoestima_inflada(self):
        self.declare(Sintomas(autoestima_inflada=ask("autoestima_inflada? ")))

    @Rule(NOT(Sintomas(grandiosidade=W())))
    def ask_data_grandiosidade(self):
        self.declare(Sintomas(grandiosidade=ask("grandiosidade? ")))

    @Rule(NOT(Sintomas(loquaz=W())))
    def ask_data_loquaz(self):
        self.declare(Sintomas(loquaz=ask("loquaz? ")))

    @Rule(NOT(Sintomas(pressao_continuar_falando=W())))
    def ask_data_pressao_continuar_falando(self):
        self.declare(Sintomas(pressao_continuar_falando=ask(
            "pressao_continuar_falando? ")))

    @Rule(NOT(Sintomas(fuga_ideias=W())))
    def ask_data_fuga_ideias(self):
        self.declare(Sintomas(fuga_ideias=ask("fuga_ideias? ")))

    @Rule(NOT(Sintomas(pensamento_acelerado=W())))
    def ask_data_pensamento_acelerado(self):
        self.declare(
            Sintomas(pensamento_acelerado=ask("pensamento_acelerado? ")))

    @Rule(NOT(Sintomas(aumento_atividade_objetivo=W())))
    def ask_data_aumento_atividade_objetivo(self):
        self.declare(Sintomas(aumento_atividade_objetivo=ask(
            "aumento_atividade_objetivo? ")))

    @Rule(NOT(Sintomas(agitacao_psicomotora=W())))
    def ask_data_agitacao_psicomotora(self):
        self.declare(
            Sintomas(agitacao_psicomotora=ask("agitacao_psicomotora? ")))

    @Rule(NOT(Sintomas(reducao_sono=W())))
    def ask_data_reducao_sono(self):
        self.declare(Sintomas(reducao_sono=ask("reducao_sono? ")))

    @Rule(NOT(Sintomas(distrabilidade=W())))
    def ask_data_distrabilidade(self):
        self.declare(Sintomas(distrabilidade=ask("distrabilidade? ")))

    @Rule(NOT(Sintomas(envolvimento_atividade_risco=W())))
    def ask_data_envolvimento_atividade_risco(self):
        self.declare(Sintomas(envolvimento_atividade_risco=ask(
            "envolvimento_atividade_risco? ")))

    @Rule(NOT(Sintomas(irritavel=W())))
    def ask_data_irritavel(self):
        self.declare(Sintomas(irritavel=ask("irritavel? ")))

    @Rule(NOT(Sintomas(verifica_perda_interesse=W())))
    def aks_perda_interesse(self):
        self.declare(
            Sintomas(verifica_perda_interesse=ask("perda_interesse? ")))

    @Rule(NOT(Sintomas(perda_prazer=W())))
    def ask_data_perda_prazer(self):
        self.declare(Sintomas(perda_prazer=ask("perda_prazer? ")))

    @Rule(NOT(Sintomas(perda_peso=W())))
    def ask_data_perda_peso(self):
        self.declare(Sintomas(perda_peso=ask("perda_peso? ")))

    @Rule(NOT(Sintomas(ganho_peso=W())))
    def ask_data_ganho_peso(self):
        self.declare(Sintomas(ganho_peso=ask("ganho_peso? ")))

    @Rule(NOT(Sintomas(reducao_alimentacao=W())))
    def ask_data_reducao_alimentacao(self):
        self.declare(
            Sintomas(reducao_alimentacao=ask("reducao_alimentacao? ")))

    @Rule(NOT(Sintomas(aumento_alimentacao=W())))
    def ask_data_aumento_alimentacao(self):
        self.declare(
            Sintomas(aumento_alimentacao=ask("aumento_alimentacao? ")))

    @Rule(NOT(Sintomas(insonia=W())))
    def ask_data_insonia(self):
        self.declare(Sintomas(insonia=ask("insonia? ")))

    @Rule(NOT(Sintomas(hipersonia=W())))
    def ask_data_hipersonia(self):
        self.declare(Sintomas(hipersonia=ask("hipersonia? ")))

    @Rule(NOT(Sintomas(retardo_psicomotor=W())))
    def ask_data_retardo_psicomotor(self):
        self.declare(Sintomas(retardo_psicomotor=ask("retardo_psicomotor? ")))

    @Rule(NOT(Sintomas(fadiga=W())))
    def ask_data_fadiga(self):
        self.declare(Sintomas(fadiga=ask("fadiga? ")))

    @Rule(NOT(Sintomas(perda_energia=W())))
    def ask_data_perda_energia(self):
        self.declare(Sintomas(perda_energia=ask("perda_energia? ")))

    @Rule(NOT(Sintomas(inutilidade=W())))
    def ask_data_inutilidade(self):
        self.declare(Sintomas(inutilidade=ask("inutilidade? ")))

    @Rule(NOT(Sintomas(culpa_excessiva=W())))
    def ask_data_culpa_excessiva(self):
        self.declare(Sintomas(culpa_excessiva=ask("culpa_excessiva? ")))

    @Rule(NOT(Sintomas(culpa_inapropriada=W())))
    def ask_data_culpa_inapropriada(self):
        self.declare(Sintomas(culpa_inapropriada=ask("culpa_inapropriada? ")))

    @Rule(NOT(Sintomas(capacidade_diminuida=W())))
    def ask_data_capacidade_diminuida(self):
        self.declare(
            Sintomas(capacidade_diminuida=ask("capacidade_diminuida? ")))

    @Rule(NOT(Sintomas(indecisao=W())))
    def ask_data_indecisao(self):
        self.declare(Sintomas(indecisao=ask("indecisao? ")))

    @Rule(NOT(Sintomas(pensamentos_morte=W())))
    def ask_data_pensamentos_morte(self):
        self.declare(Sintomas(pensamentos_morte=ask("pensamentos_morte? ")))

    @Rule(NOT(Sintomas(sofrimento_clinico=W())))
    def ask_data_sofrimento_clinico(self):
        self.declare(Sintomas(sofrimento_clinico=ask("sofrimento_clinico? ")))

    @Rule(NOT(Sintomas(prejuiso_social=W())))
    def ask_data_prejuiso_social(self):
        self.declare(Sintomas(prejuiso_social=ask("prejuiso_social? ")))

    @Rule(NOT(Sintomas(prejuiso_area_importancia=W())))
    def ask_data_prejuiso_area_importancia(self):
        self.declare(Sintomas(prejuiso_area_importancia=ask(
            "prejuiso_area_importancia? ")))

    @Rule(AND(
        NOT(Sintomas(verifica_mudanca_comportamental=W())),
        AND(
            OR(Sintomas(autoestima_excessiva=0),
               Sintomas(autoestima_excessiva=1)),
            Sintomas(autoestima_excessiva=MATCH.autoestima_excessiva)
        ),
        AND(
            OR(Sintomas(reducao_sono=0), Sintomas(reducao_sono=1)),
            Sintomas(reducao_sono=MATCH.reducao_sono)
        ),
        AND(
            OR(Sintomas(aumento_fala=0), Sintomas(aumento_fala=1)),
            Sintomas(aumento_fala=MATCH.aumento_fala)
        ),
        AND(
            OR(Sintomas(mudanca_modo_pensar=0), Sintomas(mudanca_modo_pensar=1)),
            Sintomas(mudanca_modo_pensar=MATCH.mudanca_modo_pensar)
        ),
        AND(
            OR(Sintomas(distrabilidade=0), Sintomas(distrabilidade=1)),
            Sintomas(distrabilidade=MATCH.distrabilidade)
        ),
        AND(
            OR(Sintomas(agitacao=0), Sintomas(agitacao=1)),
            Sintomas(agitacao=MATCH.agitacao)
        ),
        AND(
            OR(Sintomas(envolvimento_atividade_risco=0),
               Sintomas(envolvimento_atividade_risco=1)),
            Sintomas(
                envolvimento_atividade_risco=MATCH.envolvimento_atividade_risco)
        )
    ))
    def define_mudanca_comportamental(self,
                                      autoestima_excessiva,
                                      reducao_sono,
                                      aumento_fala,
                                      mudanca_modo_pensar,
                                      distrabilidade,
                                      agitacao,
                                      envolvimento_atividade_risco
                                      ):
        self.declare(Sintomas(verifica_mudanca_comportamental=verifica_conjunto(
            [
                autoestima_excessiva,
                reducao_sono,
                aumento_fala,
                mudanca_modo_pensar,
                distrabilidade,
                agitacao,
                envolvimento_atividade_risco
            ], 3)))

    @Rule(AND(
        NOT(Sintomas(verifica_sintomas_depressivos=W())),
        AND(
            OR(Sintomas(humor_deprimido=0), Sintomas(humor_deprimido=1)),
            Sintomas(humor_deprimido=MATCH.humor_deprimido)
        ),
        AND(
            OR(Sintomas(perda_interesse=0), Sintomas(perda_interesse=1)),
            Sintomas(perda_interesse=MATCH.perda_interesse)
        ),
        AND(
            OR(Sintomas(alteracao_alimentacao=0),
               Sintomas(alteracao_alimentacao=1)),
            Sintomas(alteracao_alimentacao=MATCH.alteracao_alimentacao)
        ),
        AND(
            OR(Sintomas(alteracao_sono=0), Sintomas(alteracao_sono=1)),
            Sintomas(alteracao_sono=MATCH.alteracao_sono)
        ),
        AND(
            OR(Sintomas(alteracao_comportamentao=0),
               Sintomas(alteracao_comportamentao=1)),
            Sintomas(alteracao_comportamentao=MATCH.alteracao_comportamentao)
        ),
        AND(
            OR(Sintomas(cansaco=0), Sintomas(cansaco=1)),
            Sintomas(cansaco=MATCH.cansaco)
        ),
        AND(
            OR(Sintomas(sentimento_depressivo=0),
               Sintomas(sentimento_depressivo=1)),
            Sintomas(sentimento_depressivo=MATCH.sentimento_depressivo)
        ),
        AND(
            OR(Sintomas(alteracao_pensamento=0),
               Sintomas(alteracao_pensamento=1)),
            Sintomas(alteracao_pensamento=MATCH.alteracao_pensamento)
        ),
        AND(
            OR(Sintomas(pensamentos_morte=0), Sintomas(pensamentos_morte=1)),
            Sintomas(pensamentos_morte=MATCH.pensamentos_morte)
        )
    ))
    def define_sintomas_depressivos(self,
                                    humor_deprimido,
                                    perda_interesse,
                                    alteracao_alimentacao,
                                    alteracao_sono,
                                    alteracao_comportamentao,
                                    cansaco,
                                    sentimento_depressivo,
                                    alteracao_pensamento,
                                    pensamentos_morte
                                    ):
        self.declare(Sintomas(verifica_sintomas_depressivos=verifica_conjunto(
            [
                humor_deprimido,
                perda_interesse,
                alteracao_alimentacao,
                alteracao_sono,
                alteracao_comportamentao,
                cansaco,
                sentimento_depressivo,
                alteracao_pensamento,
                pensamentos_morte
            ], 5)))

    """
    Verificação das regras 
    """

    @Rule(AND(Sintomas(mudanca_comportamental=1), Sintomas(fisiologico=1), Sintomas(psicose=1)))
    def mania(self):
        self.declare(Sintomas(mania=1))

    @Rule(AND(Sintomas(mudanca_comportamental=1), Sintomas(fisiologico=0), Sintomas(psicose=1)))
    def nao_mania(self):
        self.declare(Sintomas(mania=0))

    @Rule(AND(Sintomas(mudanca_comportamental=0), Sintomas(fisiologico=0), Sintomas(psicose=W())))
    def nao_2_mania(self):
        self.declare(Sintomas(mania=0))

    @Rule(AND(Sintomas(mudanca_comportamental=1), Sintomas(fisiologico=1), Sintomas(psicose=0)))
    def hipomania(self):
        self.declare(Sintomas(hipomania=1))

    @Rule(AND(Sintomas(mudanca_comportamental=1), Sintomas(fisiologico=0), Sintomas(psicose=0)))
    def nao_hipomania(self):
        self.declare(Sintomas(hipomania=0))

    @Rule(AND(Sintomas(mudanca_comportamental=0), Sintomas(fisiologico=W()), Sintomas(psicose=0)))
    def nao_2_hipomania(self):
        self.declare(Sintomas(hipomania=0))

    @Rule(OR(Sintomas(prejuizo_social=1), Sintomas(prejuiso_profissional=1)))
    def prejuiso_acentuado(self):
        self.declare(Sintomas(prejuizo_acentuado=1))

    @Rule(OR(Sintomas(prejuizo_si=1), Sintomas(prejuizo_outros=1)))
    def risco_potencial(self):
        self.declare(Sintomas(risco_potencial=1))

    @Rule(NOT(OR(Sintomas(prejuizo_si=1), Sintomas(prejuizo_outros=1))))
    def risco_potencial(self):
        self.declare(Sintomas(risco_potencial=0))

    @Rule(OR(OR(Sintomas(prejuizo_acentuado=1), Sintomas(risco_potencial=1)), Sintomas(psicose=1)))
    def perturbacao_humor(self):
        self.declare(Sintomas(perturbacao_humor=1))

    @Rule(NOT(OR(OR(Sintomas(prejuizo_acentuado=1), Sintomas(risco_potencial=1)), Sintomas(psicose=1))))
    def perturbacao_humor(self):
        self.declare(Sintomas(perturbacao_humor=0))

    @Rule(OR(Sintomas(autoestima_inflada=1), Sintomas(grandiosidade=1)))
    def autoestima_excessiva(self):
        self.declare(Sintomas(autoestima_excessiva=1))

    @Rule(OR(Sintomas(loquaz=1), Sintomas(pressao_continuar_falando=1)))
    def aumento_fala(self):
        self.declare(Sintomas(aumento_fala=1))

    @Rule(OR(Sintomas(fuga_ideias=1), Sintomas(pensamento_acelerado=1)))
    def mudanca_modo_pensar(self):
        self.declare(Sintomas(mudanca_modo_pensar=1))

    @Rule(OR(Sintomas(aumento_atividade_objetivo=1), Sintomas(agitacao_psicomotora=1)))
    def agitacao(self):
        self.declare(Sintomas(agitacao=1))

    @Rule(Sintomas(verifica_mudanca_comportamental=1))
    def mudanca_comportamental(self):
        self.declare(Sintomas(mudanca_comportamental=1))

    @Rule(OR(Sintomas(verifica_humor_deprimido=1), Sintomas(irritavel=1)))
    def humor_deprimido(self):
        self.declare(Sintomas(humor_deprimido=1))

    @Rule(OR(Sintomas(verifica_perda_interesse=1), Sintomas(perda_prazer=1)))
    def perda_interesse(self):
        self.declare(Sintomas(perda_interesse=1))

    @Rule(OR(
        OR(Sintomas(perda_peso=1), Sintomas(ganho_peso=1)),
        OR(Sintomas(reducao_alimentacao=1), Sintomas(aumento_alimentacao=1))
    ))
    def alteracao_alimentacao(self):
        self.declare(Sintomas(Sintomas(alteracao_alimentacao=1)))

    @Rule(OR(Sintomas(insonia=1), Sintomas(hipersonia=1)))
    def alteracao_sono(self):
        self.declare(Sintomas(alteracao_sono=1))

    @Rule(OR(Sintomas(agitacao=1), Sintomas(retardo_psicomotor=1)))
    def alteracao_comportamentao(self):
        self.declare(Sintomas(alteracao_comportamentao=1))

    @Rule(OR(Sintomas(fadiga=1), Sintomas(perda_energia=1)))
    def cansaco(self):
        self.declare(Sintomas(cansaco=1))

    @Rule(OR(Sintomas(inutilidade=1), Sintomas(culpa_excessiva=1), Sintomas(culpa_inapropriada=1)))
    def sentimento_depressivo(self):
        self.declare(Sintomas(sentimento_depressivo=1))

    @Rule(OR(Sintomas(capacidade_diminuida=1), Sintomas(indecisao=1)))
    def alteracao_pensamento(self):
        self.declare(Sintomas(alteracao_pensamento=1))

    @Rule(AND(
        OR(Sintomas(humor_deprimido=1), Sintomas(perda_interesse=1)),
        Sintomas(verifica_sintomas_depressivos=1)
    ))
    def sintomas_depressivos(self):
        self.declare(Sintomas(sintomas_depressivos=1))

    @Rule(OR(
        OR(Sintomas(sofrimento_clinico=1), Sintomas(prejuiso_social=1)),
        OR(Sintomas(prejuiso_profissional=1),
           Sintomas(prejuiso_area_importancia=1))
    ))
    def transtorno(self):
        self.declare(Sintomas(transtorno=1))

    @Rule(AND(Sintomas(sintomas_depressivos=1), Sintomas(fisiologico=1)))
    def depressao(self):
        self.declare(Sintomas(depressao=1))
        self.facts()
        self.get_rules()

    @Rule(AND(Sintomas(mania=1), Sintomas(depressao=1)))
    def bipolar_i(self):
        self.declare(Sintomas(bipolar_i=1))

    @Rule(AND(Sintomas(hipomania=1), Sintomas(depressao=1)))
    def bipolar_ii(self):
        self.declare(Sintomas(bipolar_ii=1))

    @Rule(AND(
        OR(Sintomas(pensamentos_morte=1),
           Sintomas(psicose=1),
           Sintomas(transtorno=1)),
        Sintomas(mania=0),
        Sintomas(hipomania=0),
        Sintomas(depressao=0)
    ))
    def outro_transtorno(self):
        self.declare(Sintomas(outro_transtorno=1))

    @Rule(Sintomas(bipolar_i=1))
    def tem_bipolar_i(self):
        self.halt()

    @Rule(Sintomas(bipolar_ii=1))
    def tem_bipolar_ii(self):
        self.halt()

    @Rule(OR(
        AND(Sintomas(mania=0), Sintomas(depressao=1)),
        AND(Sintomas(hipomania=0), Sintomas(depressao=1))
    ))
    def tem_depressao(self):
        self.halt()

    @Rule(Sintomas(outro_transtorno=1))
    def tem_outro_transtorno(self):
        self.halt()

    @Rule(Sintomas(outro_transtorno=0))
    def nao_tem_outro_transtorno(self):
        self.halt()
Beispiel #15
0
class Mania(KnowledgeEngine):
    """
    Coleta dos dados
    """

    result = {
        'variable': None,
        'isFinalAnswer': False,
        'answer': None,
    }
    is_rest = True

    def ask(self, variable):
        if not self.is_rest:
            return ask(variable)
        else:
            self.result['variable'] = variable
            self.result['isFinalAnswer'] = False
            self.result['answer'] = None
            self.halt()

    def send(self, message):
        if not self.is_rest:
            print(message)
        else:
            self.result['variable'] = None
            self.result['isFinalAnswer'] = True
            self.result['answer'] = message
        self.halt()

    @Rule(Sintomas(fisiologico=None))
    def ask_data_fisiologico(self):
        self.declare(Sintomas(fisiologico=self.ask("fisiologico")))

    @Rule(Sintomas(prejuizo_social=None))
    def ask_data_prejuizo_social(self):
        self.declare(Sintomas(prejuizo_social=self.ask("prejuizo_social")))

    @Rule(Sintomas(prejuiso_profissional=None))
    def ask_data_prejuiso_profissional(self):
        self.declare(
            Sintomas(prejuiso_profissional=self.ask("prejuiso_profissional")))

    @Rule(Sintomas(psicose=None))
    def ask_data_psicose(self):
        self.declare(Sintomas(psicose=self.ask("psicose")))

    @Rule(Sintomas(autoestima_inflada=None))
    def ask_data_autoestima_inflada(self):
        self.declare(
            Sintomas(autoestima_inflada=self.ask("autoestima_inflada")))

    @Rule(Sintomas(grafndiosidade=None))
    def ask_data_grandiosidade(self):
        self.declare(Sintomas(grandiosidade=self.ask("grandiosidade")))

    @Rule(Sintomas(loquaz=None))
    def ask_data_loquaz(self):
        self.declare(Sintomas(loquaz=self.ask("loquaz")))

    @Rule(Sintomas(pressao_continuar_falando=None))
    def ask_data_pressao_continuar_falando(self):
        self.declare(
            Sintomas(pressao_continuar_falando=self.ask(
                "pressao_continuar_falando")))

    @Rule(Sintomas(fuga_ideias=None))
    def ask_data_fuga_ideias(self):
        self.declare(Sintomas(fuga_ideias=self.ask("fuga_ideias")))

    @Rule(Sintomas(pensamento_acelerado=None))
    def ask_data_pensamento_acelerado(self):
        self.declare(
            Sintomas(pensamento_acelerado=self.ask("pensamento_acelerado")))

    @Rule(Sintomas(aumento_atividade_objetivo=None))
    def ask_data_aumento_atividade_objetivo(self):
        self.declare(
            Sintomas(aumento_atividade_objetivo=self.ask(
                "aumento_atividade_objetivo")))

    @Rule(Sintomas(agitacao_psicomotora=None))
    def ask_data_agitacao_psicomotora(self):
        self.declare(
            Sintomas(agitacao_psicomotora=self.ask("agitacao_psicomotora")))

    @Rule(Sintomas(reducao_sono=None))
    def ask_data_reducao_sono(self):
        self.declare(Sintomas(reducao_sono=self.ask("reducao_sono")))

    @Rule(Sintomas(distrabilidade=None))
    def ask_data_distrabilidade(self):
        self.declare(Sintomas(distrabilidade=self.ask("distrabilidade")))

    @Rule(Sintomas(envolvimento_atividade_risco=None))
    def ask_data_envolvimento_atividade_risco(self):
        self.declare(
            Sintomas(envolvimento_atividade_risco=self.ask(
                "envolvimento_atividade_risco")))

    @Rule(
        AND(
            NOT(Sintomas(mudanca_comportamental=W())),
            AND(
                OR(Sintomas(autoestima_excessiva=0),
                   Sintomas(autoestima_excessiva=1)),
                Sintomas(autoestima_excessiva=MATCH.autoestima_excessiva)),
            AND(OR(Sintomas(reducao_sono=0), Sintomas(reducao_sono=1)),
                Sintomas(reducao_sono=MATCH.reducao_sono)),
            AND(OR(Sintomas(aumento_fala=0), Sintomas(aumento_fala=1)),
                Sintomas(aumento_fala=MATCH.aumento_fala)),
            AND(
                OR(Sintomas(mudanca_modo_pensar=0),
                   Sintomas(mudanca_modo_pensar=1)),
                Sintomas(mudanca_modo_pensar=MATCH.mudanca_modo_pensar)),
            AND(OR(Sintomas(distrabilidade=0), Sintomas(distrabilidade=1)),
                Sintomas(distrabilidade=MATCH.distrabilidade)),
            AND(OR(Sintomas(agitacao=0), Sintomas(agitacao=1)),
                Sintomas(agitacao=MATCH.agitacao)),
            AND(
                OR(Sintomas(envolvimento_atividade_risco=0),
                   Sintomas(envolvimento_atividade_risco=1)),
                Sintomas(envolvimento_atividade_risco=MATCH.
                         envolvimento_atividade_risco))))
    def define_mudanca_comportamental(self, autoestima_excessiva, reducao_sono,
                                      aumento_fala, mudanca_modo_pensar,
                                      distrabilidade, agitacao,
                                      envolvimento_atividade_risco):
        self.declare(
            Sintomas(mudanca_comportamental=verifica_conjunto([
                autoestima_excessiva, reducao_sono, aumento_fala,
                mudanca_modo_pensar, distrabilidade, agitacao,
                envolvimento_atividade_risco
            ], 3)))

    """
    Verificação das regras 
    """

    @Rule(
        AND(Sintomas(mudanca_comportamental=1), Sintomas(fisiologico=1),
            Sintomas(psicose=1)))
    def mania(self):
        self.declare(Sintomas(mania=1))
        self.send("mania:1")

    @Rule(
        AND(Sintomas(mudanca_comportamental=1), Sintomas(fisiologico=1),
            Sintomas(psicose=0)))
    def hipomania(self):
        self.declare(Sintomas(hipomania=1))
        self.send("hipomania:1")

    @Rule(Sintomas(fisiologico=0))
    def nao_fisiologico(self):
        self.declare(Sintomas(mania=0))
        self.declare(Sintomas(hipomania=0))
        self.send(":0")

    @Rule(Sintomas(mudanca_comportamental=0))
    def nao_mudanca_comportamental(self):
        self.declare(Sintomas(mania=0))
        self.declare(Sintomas(hipomania=0))
        self.send(":0")

    @Rule(OR(Sintomas(prejuizo_social=1), Sintomas(prejuiso_profissional=1)))
    def prejuiso_acentuado(self):
        self.declare(Sintomas(prejuizo_acentuado=1))

    @Rule(AND(Sintomas(prejuizo_social=0), Sintomas(prejuiso_profissional=0)))
    def nao_prejuiso_acentuado(self):
        self.declare(Sintomas(prejuizo_acentuado=0))

    @Rule(OR(Sintomas(autoestima_inflada=1), Sintomas(grandiosidade=1)))
    def autoestima_excessiva(self):
        self.declare(Sintomas(autoestima_excessiva=1))

    @Rule(AND(Sintomas(autoestima_inflada=0), Sintomas(grandiosidade=0)))
    def nao_autoestima_excessiva(self):
        self.declare(Sintomas(autoestima_excessiva=0))

    @Rule(OR(Sintomas(loquaz=1), Sintomas(pressao_continuar_falando=1)))
    def aumento_fala(self):
        self.declare(Sintomas(aumento_fala=1))

    @Rule(AND(Sintomas(loquaz=0), Sintomas(pressao_continuar_falando=0)))
    def nao_aumento_fala(self):
        self.declare(Sintomas(aumento_fala=0))

    @Rule(OR(Sintomas(fuga_ideias=1), Sintomas(pensamento_acelerado=1)))
    def mudanca_modo_pensar(self):
        self.declare(Sintomas(mudanca_modo_pensar=1))

    @Rule(AND(Sintomas(fuga_ideias=0), Sintomas(pensamento_acelerado=0)))
    def nao_mudanca_modo_pensar(self):
        self.declare(Sintomas(mudanca_modo_pensar=0))

    @Rule(
        OR(Sintomas(aumento_atividade_objetivo=1),
           Sintomas(agitacao_psicomotora=1)))
    def agitacao(self):
        self.declare(Sintomas(agitacao=1))

    @Rule(
        AND(Sintomas(aumento_atividade_objetivo=0),
            Sintomas(agitacao_psicomotora=0)))
    def nao_agitacao(self):
        self.declare(Sintomas(agitacao=0))
Beispiel #16
0
 class Test(KnowledgeEngine):
     @Rule(Fact("a" << W()), Fact("b" << W()), TEST(lambda a, b: a > b),
           Fact("c" << W()), TEST(lambda b, c: b > c))
     def is_greater(self, a, b, c):
         nonlocal executed
         executed[(a, b, c)] += 1
Beispiel #17
0
 class Test(KnowledgeEngine):
     @Rule(Fact("a" << W()), TEST(lambda a: isinstance(a, int)))
     def is_number(self, a):
         nonlocal executed
         executed += 1
Beispiel #18
0
class AdditionEngine(KnowledgeEngine):
    sais = []

    @Rule(Fact(id='done'))
    def click_done(self):
        print("FIRED CLICK DONE")
        x = Sai(selection='done',
                action='ButtonPressed',
                inputs={'value': '-1'})
        self.sais.append(x)
        return x

    @Rule(Fact(id=MATCH.field_id, contentEditable=True, value=MATCH.value))
    def check(self, field_id):
        print("FIRED CHECK")
        return Sai(selection=field_id,
                   action='UpdateTextArea',
                   inputs={'value': "x"})

    @Rule(Fact(id=W(), contentEditable=False, value=MATCH.value),
          TEST(lambda value_from: value_from != ""),
          Fact(id=MATCH.field_id, contentEditable=True, value=W()))
    def update_field(self, field_id, value):
        #print("FIRED UPDATE FIELD")
        s = Sai(
            selection=field_id,
            action='UpdateTextField',
            # action='UpdateTextArea',
            inputs={'value': value})
        if int(value) == 3:
            self.sais.append(s)
        return s

    @Rule(
        AS.fact1 << Fact(
            id=MATCH.id1, contentEditable=False, value=MATCH.value1),
        TEST(lambda fact1: 'depth' not in fact1 or fact1['depth'] < max_depth),
        TEST(lambda value1: str(value1).isnumeric()), AS.fact2 << Fact(
            id=MATCH.id2, contentEditable=False, value=MATCH.value2),
        TEST(lambda id1, id2: id1 <= id2),
        TEST(lambda fact2: 'depth' not in fact2 or fact2['depth'] < max_depth),
        TEST(lambda value2: str(value2).isnumeric()),
        NOT(Fact(operator='add', ele1=MATCH.id1, ele2=MATCH.id2)))
    def add(self, id1, value1, fact1, id2, value2, fact2):
        #print("FIRED ADD")
        new_id = 'add(%s, %s)' % (id1, id2)

        new_value = float(value1) + float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        depth1 = 0 if 'depth' not in fact1 else fact1['depth']
        depth2 = 0 if 'depth' not in fact2 else fact2['depth']
        new_depth = 1 + max(depth1, depth2)

        self.declare(
            Fact(id=new_id,
                 operator='add',
                 ele1=id1,
                 ele2=id2,
                 contentEditable=False,
                 value=new_value,
                 depth=new_depth))
Beispiel #19
0
 class KE(KnowledgeEngine):
     @Rule(Fact(x='x' << W()), NOT(Fact(y='x' << W())))
     def r1(self):
         pass
Beispiel #20
0
class FractionsEngine(KnowledgeEngine):
    @Rule(Fact(id='done'))
    def click_done(self):
        print('clicking done')
        return Sai(selection='done',
                   action='ButtonPressed',
                   inputs={'value': -1})

    @Rule(Fact(id="JCommTable8.R0C0", contentEditable=True, value=""))
    def check(self):
        print('checking box')
        return Sai(selection="JCommTable8.R0C0",
                   action='UpdateTextArea',
                   inputs={'value': "x"})

    @Rule(Fact(id=MATCH.id1, contentEditable=False, value=MATCH.value1),
          TEST(lambda id1, value1: id1 in fields and value1 != ""),
          Fact(id=MATCH.id2, contentEditable=False, value=MATCH.value2),
          TEST(lambda id2, value2: id2 in fields and value2 != ""),
          TEST(lambda id1, id2: id1 < id2),
          NOT(Fact(relation='equal', ele1=MATCH.id1, ele2=MATCH.id2)))
    def equal(self, id1, value1, id2, value2):
        new_id = "equal(%s, %s)" % (id1, id2)
        equality = value1 == value2
        print('declaring equality', id1, id2, equality)
        self.declare(
            Fact(id=new_id,
                 relation='equal',
                 ele1=id1,
                 ele2=id2,
                 r_val=equality))

    @Rule(
        Fact(id='JCommTable8.R0C0', contentEditable=False, value='x'),
        Fact(id=W(), contentEditable=False, value=MATCH.value),
        TEST(lambda value: value != "" and str(value).isnumeric()),
        Fact(id=MATCH.field_id, contentEditable=True, value=W()),
        TEST(lambda field_id: field_id != 'JCommTable8.R0C0' and field_id
             not in answer_field),
    )
    def update_convert_field(self, field_id, value):
        print('updating convert field', field_id, value)
        return Sai(
            selection=field_id,
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': value})

    @Rule(Fact(id=W(), contentEditable=False, value=MATCH.value),
          TEST(lambda value: value != "" and str(value).isnumeric()),
          Fact(id=MATCH.field_id, contentEditable=True, value=W()),
          TEST(lambda field_id: field_id != 'JCommTable8.R0C0'),
          TEST(lambda field_id: field_id in answer_field))
    def update_answer_field(self, field_id, value):
        print('updating answer field', field_id, value)
        return Sai(
            selection=field_id,
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': value})

    @Rule(
        AS.fact1 << Fact(
            id=MATCH.id1, contentEditable=False, value=MATCH.value1),
        TEST(lambda fact1: 'depth' not in fact1 or fact1['depth'] < max_depth),
        TEST(lambda value1: str(value1).isnumeric()), AS.fact2 << Fact(
            id=MATCH.id2, contentEditable=False, value=MATCH.value2),
        TEST(lambda id1, id2: id1 <= id2),
        TEST(lambda fact2: 'depth' not in fact2 or fact2['depth'] < max_depth),
        TEST(lambda value2: str(value2).isnumeric()),
        NOT(Fact(operator='add', ele1=MATCH.id1, ele2=MATCH.id2)))
    def add(self, id1, value1, fact1, id2, value2, fact2):
        new_id = 'add(%s, %s)' % (id1, id2)

        new_value = float(value1) + float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        depth1 = 0 if 'depth' not in fact1 else fact1['depth']
        depth2 = 0 if 'depth' not in fact2 else fact2['depth']
        new_depth = 1 + max(depth1, depth2)

        print('adding', id1, id2)

        self.declare(
            Fact(id=new_id,
                 operator='add',
                 ele1=id1,
                 ele2=id2,
                 contentEditable=False,
                 value=new_value,
                 depth=new_depth))

    @Rule(
        AS.fact1 << Fact(
            id=MATCH.id1, contentEditable=False, value=MATCH.value1),
        TEST(lambda fact1: 'depth' not in fact1 or fact1['depth'] < max_depth),
        TEST(lambda value1: str(value1).isnumeric()), AS.fact2 << Fact(
            id=MATCH.id2, contentEditable=False, value=MATCH.value2),
        TEST(lambda id1, id2: id1 <= id2),
        TEST(lambda fact2: 'depth' not in fact2 or fact2['depth'] < max_depth),
        TEST(lambda value2: str(value2).isnumeric()),
        NOT(Fact(operator='multiply', ele1=MATCH.id1, ele2=MATCH.id2)))
    def multiply(self, id1, value1, fact1, id2, value2, fact2):
        print('multiplying', id1, id2)
        new_id = 'multiply(%s, %s)' % (id1, id2)

        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        depth1 = 0 if 'depth' not in fact1 else fact1['depth']
        depth2 = 0 if 'depth' not in fact2 else fact2['depth']
        new_depth = 1 + max(depth1, depth2)

        self.declare(
            Fact(id=new_id,
                 operator='multiply',
                 ele1=id1,
                 ele2=id2,
                 contentEditable=False,
                 value=new_value,
                 depth=new_depth))
Beispiel #21
0
class Bipolar(KnowledgeEngine):
    """
    Coleta dos dados
    """

    @Rule(NOT(Sintomas(pensamentos_morte=W())))
    def ask_pensamentos_morte(self):
        self.declare(Sintomas(pensamentos_morte=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(alteracao_pensamento=W())))
    def ask_alteracao_pensamento(self):
        self.declare(Sintomas(alteracao_pensamento=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(sentimento_depressivo=W())))
    def ask_sentimento_depressivo(self):
        self.declare(Sintomas(sentimento_depressivo=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(cansaco=W())))
    def ask_cansaco(self):
        self.declare(Sintomas(cansaco=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(alteracao_comportamentao=W())))
    def ask_alteracao_comportamentao(self):
        self.declare(Sintomas(alteracao_comportamentao=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(alteracao_sono=W())))
    def ask_alteracao_sono(self):
        self.declare(Sintomas(alteracao_sono=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(alteracao_alimentacao=W())))
    def ask_alteracao_alimentacao(self):
        self.declare(Sintomas(alteracao_alimentacao=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(perda_interesse=W())))
    def ask_perda_interesse(self):
        self.declare(Sintomas(perda_interesse=ask("prejuiso_area_importancia? ")))

    @Rule(NOT(Sintomas(humor_deprimido=W())))
    def ask_humor_deprimido(self):
        self.declare(Sintomas(humor_deprimido=ask("prejuiso_area_importancia? ")))

    @Rule(AND(
        NOT(Sintomas(verifica_sintomas_depressivos=W())),
        AND(
            OR(Sintomas(humor_deprimido=0), Sintomas(humor_deprimido=1)),
            Sintomas(humor_deprimido=MATCH.humor_deprimido)
        ),
        AND(
            OR(Sintomas(perda_interesse=0), Sintomas(perda_interesse=1)),
            Sintomas(perda_interesse=MATCH.perda_interesse)
        ),
        AND(
            OR(Sintomas(alteracao_alimentacao=0), Sintomas(alteracao_alimentacao=1)),
            Sintomas(alteracao_alimentacao=MATCH.alteracao_alimentacao)
        ),
        AND(
            OR(Sintomas(alteracao_sono=0), Sintomas(alteracao_sono=1)),
            Sintomas(alteracao_sono=MATCH.alteracao_sono)
        ),
        AND(
            OR(Sintomas(alteracao_comportamentao=0), Sintomas(alteracao_comportamentao=1)),
            Sintomas(alteracao_comportamentao=MATCH.alteracao_comportamentao)
        ),
        AND(
            OR(Sintomas(cansaco=0), Sintomas(cansaco=1)),
            Sintomas(cansaco=MATCH.cansaco)
        ),
        AND(
            OR(Sintomas(sentimento_depressivo=0), Sintomas(sentimento_depressivo=1)),
            Sintomas(sentimento_depressivo=MATCH.sentimento_depressivo)
        ),
        AND(
            OR(Sintomas(alteracao_pensamento=0), Sintomas(alteracao_pensamento=1)),
            Sintomas(alteracao_pensamento=MATCH.alteracao_pensamento)
        ),
        AND(
            OR(Sintomas(pensamentos_morte=0), Sintomas(pensamentos_morte=1)),
            Sintomas(pensamentos_morte=MATCH.pensamentos_morte)
        )
    ))
    def define_sintomas_depressivos(self,
                                    humor_deprimido,
                                    perda_interesse,
                                    alteracao_alimentacao,
                                    alteracao_sono,
                                    alteracao_comportamentao,
                                    cansaco,
                                    sentimento_depressivo,
                                    alteracao_pensamento,
                                    pensamentos_morte
                                    ):
        self.declare(Sintomas(verifica_sintomas_depressivos=verifica_conjunto(
            [
                humor_deprimido,
                perda_interesse,
                alteracao_alimentacao,
                alteracao_sono,
                alteracao_comportamentao,
                cansaco,
                sentimento_depressivo,
                alteracao_pensamento,
                pensamentos_morte
            ]
            , 5)))

    @Rule(AND(
        OR(Sintomas(humor_deprimido=1), Sintomas(perda_interesse=1)),
        Sintomas(verifica_sintomas_depressivos=1)
    ))
    def sintomas_depressivos(self):
        print("sintomas_depressivos")
        self.declare(Sintomas(sintomas_depressivos=1))
Beispiel #22
0
class CoreKnowledgeEngine(KnowledgeEngine):
    @Rule(Fact(id='done'))
    def click_done(self):
        # print('clicking done')
        return Sai(selection='done',
                   action='ButtonPressed',
                   inputs={'value': -1})

    @Rule(Fact(id='done'))
    def done(self):
        # print('clicking done')
        return Sai(selection='done',
                   action='ButtonPressed',
                   inputs={'value': '-1'})

    @Rule(Fact(id="JCommTable8.R0C0", contentEditable=True, value=""))
    def check(self):
        # print('checking box')
        return Sai(selection="JCommTable8.R0C0",
                   action='UpdateTextArea',
                   inputs={'value': "x"})

    @Rule(Fact(id=MATCH.id1, contentEditable=False, value=MATCH.value1),
          TEST(lambda id1, value1: id1 in fields and value1 != ""),
          Fact(id=MATCH.id2, contentEditable=False, value=MATCH.value2),
          TEST(lambda id2, value2: id2 in fields and value2 != ""),
          TEST(lambda id1, id2: id1 < id2),
          NOT(Fact(relation='equal', ele1=MATCH.id1, ele2=MATCH.id2)))
    def equal(self, id1, value1, id2, value2):
        new_id = "equal(%s, %s)" % (id1, id2)
        equality = value1 == value2
        # print('declaring equality', id1, id2, equality)
        self.declare(
            Fact(id=new_id,
                 relation='equal',
                 ele1=id1,
                 ele2=id2,
                 r_val=equality))

    @Rule(
        Fact(id='JCommTable8.R0C0', contentEditable=False, value='x'),
        Fact(id=W(), contentEditable=False, value=MATCH.value),
        TEST(lambda value: value != "" and is_numeric_str(value)),
        Fact(id=MATCH.field_id, contentEditable=True, value=W()),
        TEST(lambda field_id: field_id != 'JCommTable8.R0C0' and field_id
             not in answer_field),
    )
    def update_convert_field(self, field_id, value):
        # print('updating convert field', field_id, value)
        return Sai(
            selection=field_id,
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': value})

    @Rule(Fact(id=W(), contentEditable=False, value=MATCH.value),
          TEST(lambda value: value != "" and is_numeric_str(value)),
          Fact(id=MATCH.field_id, contentEditable=True, value=W()),
          TEST(lambda field_id: field_id != 'JCommTable8.R0C0'),
          TEST(lambda field_id: field_id in answer_field))
    def update_answer_field(self, field_id, value):
        # print('updating answer field', field_id, value)
        return Sai(
            selection=field_id,
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': value})

    @Rule(Fact(id=W(), contentEditable=False, value=MATCH.value),
          TEST(lambda value: value != ""),
          Fact(id=MATCH.field_id, contentEditable=True, value=""))
    def update_field(self, field_id, value):
        # print('updating answer field', field_id, value)
        return Sai(selection=field_id,
                   action='UpdateTextField',
                   inputs={'value': value})

    @Rule(
        AS.fact1 << Fact(
            id=MATCH.id1, contentEditable=False, value=MATCH.value1),
        TEST(lambda fact1: 'depth' not in fact1 or fact1['depth'] < max_depth),
        TEST(lambda value1: is_numeric_str(value1)), AS.fact2 << Fact(
            id=MATCH.id2, contentEditable=False, value=MATCH.value2),
        TEST(lambda id1, id2: id1 <= id2),
        TEST(lambda fact2: 'depth' not in fact2 or fact2['depth'] < max_depth),
        TEST(lambda value2: is_numeric_str(value2)),
        NOT(Fact(operator='add', ele1=MATCH.id1, ele2=MATCH.id2)))
    def add(self, id1, value1, fact1, id2, value2, fact2):
        new_id = 'add(%s, %s)' % (id1, id2)

        new_value = float(value1) + float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        depth1 = 0 if 'depth' not in fact1 else fact1['depth']
        depth2 = 0 if 'depth' not in fact2 else fact2['depth']
        new_depth = 1 + max(depth1, depth2)

        # print('adding', id1, id2)

        self.declare(
            Fact(id=new_id,
                 operator='add',
                 ele1=id1,
                 ele2=id2,
                 contentEditable=False,
                 value=new_value,
                 depth=new_depth))

    @Rule(
        AS.fact1 << Fact(
            id=MATCH.id1, contentEditable=False, value=MATCH.value1),
        TEST(lambda fact1: 'depth' not in fact1 or fact1['depth'] < max_depth),
        TEST(lambda value1: is_numeric_str(value1)), AS.fact2 << Fact(
            id=MATCH.id2, contentEditable=False, value=MATCH.value2),
        TEST(lambda id1, id2: id1 <= id2),
        TEST(lambda fact2: 'depth' not in fact2 or fact2['depth'] < max_depth),
        TEST(lambda value2: is_numeric_str(value2)),
        NOT(Fact(operator='multiply', ele1=MATCH.id1, ele2=MATCH.id2)))
    def multiply(self, id1, value1, fact1, id2, value2, fact2):
        # print('multiplying', id1, id2)
        new_id = 'multiply(%s, %s)' % (id1, id2)

        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        depth1 = 0 if 'depth' not in fact1 else fact1['depth']
        depth2 = 0 if 'depth' not in fact2 else fact2['depth']
        new_depth = 1 + max(depth1, depth2)

        self.declare(
            Fact(id=new_id,
                 operator='multiply',
                 ele1=id1,
                 ele2=id2,
                 contentEditable=False,
                 value=new_value,
                 depth=new_depth))

    @Rule(
        AS.fact1 << Fact(
            id=MATCH.id1, contentEditable=False, value=MATCH.value1),
        TEST(lambda fact1: 'depth' not in fact1 or fact1['depth'] < max_depth),
        TEST(lambda value1: is_numeric_str(value1)), AS.fact2 << Fact(
            id=MATCH.id2, contentEditable=False, value=MATCH.value2),
        TEST(lambda id1, id2: id1 <= id2),
        TEST(lambda fact2: 'depth' not in fact2 or fact2['depth'] < max_depth),
        TEST(lambda value2: is_numeric_str(value2)),
        NOT(Fact(operator='lcm', ele1=MATCH.id1, ele2=MATCH.id2)))
    def least_common_multiple(self, id1, value1, fact1, id2, value2, fact2):
        new_id = ' lcm({0}, {1})'.format(id1, id2)

        gcd = math.gcd(int(value1), int(value2))
        new_value = abs(int(value1) * int(value2)) // gcd
        # if new_value.is_integer():
        #     new_value = int(new_value)
        new_value = str(new_value)

        depth1 = 0 if 'depth' not in fact1 else fact1['depth']
        depth2 = 0 if 'depth' not in fact2 else fact2['depth']
        new_depth = 1 + max(depth1, depth2)

        self.declare(
            Fact(id=new_id,
                 operator='lcm',
                 ele1=id1,
                 ele2=id2,
                 contentEditable=False,
                 value=new_value,
                 depth=new_depth))

    @Rule(
        AS.fact1 << Fact(id=MATCH.id1, type='TextField', value=MATCH.value1),
        TEST(lambda value1: value1 != ""),
        TEST(lambda value1: len(value1) > 1),
    )
    def div10(self, id1, value1):
        new_id = 'div10({0})'.format(id1)

        new_value = float(value1) // 10
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        self.declare(
            Fact(id=new_id,
                 operator='div10',
                 depth=1,
                 ele1=id1,
                 contentEditable=False,
                 value=new_value))

    @Rule(AS.fact1 << Fact(id=MATCH.id1, type='TextField', value=MATCH.value1),
          TEST(lambda value1: value1 != ""))
    def addOne(self, id1, value1):
        new_id = 'addOne({0})'.format(id1)

        new_value = float(value1) + 1
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        self.declare(
            Fact(id=new_id,
                 operator='addOne',
                 depth=1,
                 ele1=id1,
                 contentEditable=False,
                 value=new_value))

    @Rule(AS.fact1 << Fact(id=MATCH.id1, type='TextField', value=MATCH.value1),
          TEST(lambda value1: value1 != ""))
    def append25(self, id1, value1):
        new_id = 'append25({0})'.format(id1)
        new_value = value1 + "25"
        self.declare(
            Fact(id=new_id,
                 operator='append25',
                 depth=1,
                 ele1=id1,
                 contentEditable=False,
                 value=new_value))

    @Rule(Fact(id='JCommTable.R0C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable2.R0C0', contentEditable=False, value="*"),
          Fact(id='JCommTable3.R0C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable6.R0C0', contentEditable=True))
    def correct_multiply_num(self, value1, value2):
        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable6.R0C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(Fact(id='JCommTable.R1C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable2.R0C0', contentEditable=False, value="*"),
          Fact(id='JCommTable3.R1C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable6.R1C0', contentEditable=True))
    def correct_multiply_denom(self, value1, value2):
        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable6.R1C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(Fact(id='JCommTable6.R0C0', contentEditable=False),
          Fact(id='JCommTable6.R1C0', contentEditable=False), Fact(id='done'))
    def correct_done(self):
        return Sai(selection='done',
                   action='ButtonPressed',
                   inputs={'value': -1})

    @Rule(Fact(id='JCommTable.R0C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable2.R0C0', contentEditable=False, value="+"),
          Fact(id='JCommTable3.R0C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable.R1C0', contentEditable=False,
               value=MATCH.value3),
          Fact(id='JCommTable3.R1C0',
               contentEditable=False,
               value=MATCH.value3),
          Fact(id='JCommTable6.R0C0', contentEditable=True))
    def correct_add_same_num(self, value1, value2):
        new_value = float(value1) + float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable6.R0C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(Fact(id='JCommTable.R0C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable2.R0C0', contentEditable=False, value="+"),
          Fact(id='JCommTable3.R0C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable.R1C0', contentEditable=False,
               value=MATCH.value3),
          Fact(id='JCommTable3.R1C0',
               contentEditable=False,
               value=MATCH.value3),
          Fact(id='JCommTable6.R1C0', contentEditable=True))
    def correct_copy_same_denom(self, value3):
        return Sai(
            selection='JCommTable6.R1C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': value3})

    @Rule(Fact(id="JCommTable.R1C0", contentEditable=False,
               value=MATCH.denom1),
          Fact(id="JCommTable2.R0C0", contentEditable=False, value="+"),
          Fact(id="JCommTable3.R1C0",
               contentEditable=False,
               value=MATCH.denom2),
          TEST(lambda denom1, denom2: denom1 != denom2),
          Fact(id="JCommTable8.R0C0", contentEditable=True, value=""))
    def correct_check(self):
        # print('checking box')
        return Sai(selection="JCommTable8.R0C0",
                   action='UpdateTextArea',
                   inputs={'value': "x"})

    @Rule(Fact(id='JCommTable2.R0C0', contentEditable=False, value="+"),
          Fact(id="JCommTable8.R0C0", contentEditable=False, value="x"),
          Fact(id='JCommTable.R0C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable3.R1C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable4.R1C0', contentEditable=False),
          Fact(id='JCommTable4.R0C0', contentEditable=True))
    def correct_convert_num1(self, value1, value2):
        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable4.R0C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(Fact(id='JCommTable2.R0C0', contentEditable=False, value="+"),
          Fact(id="JCommTable8.R0C0", contentEditable=False, value="x"),
          Fact(id='JCommTable.R1C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable3.R0C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable4.R0C0', contentEditable=False),
          Fact(id='JCommTable4.R1C0', contentEditable=False),
          Fact(id='JCommTable5.R1C0', contentEditable=False),
          Fact(id='JCommTable5.R0C0', contentEditable=True))
    def correct_convert_num2(self, value1, value2):
        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable5.R0C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(Fact(id='JCommTable2.R0C0', contentEditable=False, value="+"),
          Fact(id="JCommTable8.R0C0", contentEditable=False, value="x"),
          Fact(id='JCommTable.R1C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable3.R1C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable4.R1C0', contentEditable=True))
    def correct_convert_denom1(self, value1, value2):
        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable4.R1C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(Fact(id='JCommTable2.R0C0', contentEditable=False, value="+"),
          Fact(id="JCommTable8.R0C0", contentEditable=False, value="x"),
          Fact(id='JCommTable.R1C0', contentEditable=False,
               value=MATCH.value1),
          Fact(id='JCommTable3.R1C0',
               contentEditable=False,
               value=MATCH.value2),
          Fact(id='JCommTable4.R1C0', contentEditable=False),
          Fact(id='JCommTable5.R1C0', contentEditable=True))
    def correct_convert_denom2(self, value1, value2):
        new_value = float(value1) * float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable5.R1C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(
        Fact(id='JCommTable4.R0C0', contentEditable=False, value=MATCH.value1),
        Fact(id='JCommTable4.R1C0', contentEditable=False, value=MATCH.value3),
        Fact(id='JCommTable7.R0C0', contentEditable=False, value="+"),
        Fact(id='JCommTable5.R0C0', contentEditable=False, value=MATCH.value2),
        Fact(id='JCommTable5.R1C0', contentEditable=False, value=MATCH.value3),
        Fact(id='JCommTable6.R0C0', contentEditable=True),
    )
    def correct_add_convert_num(self, value1, value2):
        new_value = float(value1) + float(value2)
        if new_value.is_integer():
            new_value = int(new_value)
        new_value = str(new_value)

        return Sai(
            selection='JCommTable6.R0C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': new_value})

    @Rule(
        Fact(id='JCommTable4.R0C0', contentEditable=False, value=MATCH.value1),
        Fact(id='JCommTable4.R1C0', contentEditable=False, value=MATCH.value3),
        Fact(id='JCommTable7.R0C0', contentEditable=False, value="+"),
        Fact(id='JCommTable5.R0C0', contentEditable=False, value=MATCH.value2),
        Fact(id='JCommTable5.R1C0', contentEditable=False, value=MATCH.value3),
        Fact(id='JCommTable6.R1C0', contentEditable=True),
    )
    def correct_copy_convert_denom(self, value3):
        return Sai(
            selection='JCommTable6.R1C0',
            # action='UpdateTextField',
            action='UpdateTextArea',
            inputs={'value': value3})