Ejemplo n.º 1
0
class DeveloperInterface(QWidget):
    """Graphic interface of the project (developer edition)"""

    #
    #   memRules: Ruleset to be saved to file. This is not for propagation
    #   variables: The work memory. It stores the values of the different
    #       variables that had a value assigned to them.
    #   ruleHeap: Full copy of memRules in order to be used for propagation
    #
    def __init__(self, parent=None):
        super(DeveloperInterface, self).__init__(parent)

        self.memRules = Rules("rulelist.json")
        self.variables = WorkMemory()

        self.inst_lbl = QLabel(
            "Escribe una sentencia antecedente->consecuente")
        self.id_lbl = QLabel("Id:")
        self.val_lbl = QLabel("Value:")
        self.solv_lbl = QLabel("No se ha llegado a una solucion")

        self.st_edit = QLineEdit()
        self.var_edit = QLineEdit()

        self.values = QComboBox()
        self.values.addItem("T")
        self.values.addItem("F")

        self.refresh_button = QPushButton("Evaluate!")
        self.propagate_button = QPushButton("Propagate!")

        self.statements = QPlainTextEdit()
        self.rules = QPlainTextEdit()
        self.solutions = QPlainTextEdit()

        self.statements.setReadOnly(True)
        self.rules.setReadOnly(True)
        self.solutions = QPlainTextEdit()

        self.hlayout = QHBoxLayout()
        self.hlayout.addWidget(self.st_edit)
        self.hlayout.addWidget(self.refresh_button)

        self.hlayout2 = QHBoxLayout()
        self.hlayout2.addWidget(self.id_lbl)
        self.hlayout2.addWidget(self.var_edit)
        self.hlayout2.addWidget(self.val_lbl)
        self.hlayout2.addWidget(self.values)
        self.hlayout2.addWidget(self.propagate_button)

        self.main_layout = QGridLayout()
        self.main_layout.addWidget(self.inst_lbl, 0, 0)
        self.main_layout.addLayout(self.hlayout, 1, 0)
        self.main_layout.addWidget(self.statements, 2, 0)
        self.main_layout.addLayout(self.hlayout2, 3, 0)
        self.main_layout.addWidget(self.rules, 4, 0)
        self.main_layout.addWidget(self.solv_lbl, 5, 0)
        self.main_layout.addWidget(self.solutions, 6, 0)

        self.refresh_button.clicked.connect(self.Evaluate)
        self.propagate_button.clicked.connect(self.Propagation)

        self.st_edit.setText("((a ^ b) ^ c) -> d")

        self.setLayout(self.main_layout)
        self.setWindowTitle("My first expert system")
        self.UpdateCache()
        self.PrintWorkMemory()

    def Evaluate(self):
        """Evaluates the statement and adds it to the rules"""
        statement = self.st_edit.text().strip()

        if (statement == ""):
            return

        new_cnf = CNFStatement(statement)
        cnf_list = new_cnf.Branch()

        for cnf in cnf_list:
            print("New Statement:", cnf)
            self.memRules.CreateRule(cnf)

        self.memRules.Save()
        self.UpdateCache()
        self.PrintWorkMemory()

    def UpdateCache(self):
        """Updates the rule buffer. Also displays all rules found until now"""
        self.ruleHeap = self.memRules.copy()
        self.rules.setPlainText(str(self.ruleHeap))

    def PrintWorkMemory(self):
        self.statements.setPlainText(str(self.memRules))

    def Propagation(self):
        var = self.var_edit.text().strip()
        value = self.values.currentText().strip()
        self.ruleHeap.Propagate(var, value)
        self.rules.setPlainText(str(self.ruleHeap))
Ejemplo n.º 2
0
class QuestionWidget(QWidget):
    """Widget for creating and answering the questions that are needed in the reasoning"""
    def __init__(self, objective, parent=None):
        super(QuestionWidget, self).__init__(parent)
        self.objective = objective
        self.memRules = Rules("rulelist.json")
        self.reasoned = []

        # Get consequents, antecedents and list of rules pertaining the objective
        related = self.memRules.GetRelatedRules(self.objective)
        self.cons = related["CONS"]
        self.ants = related["ANTS"]

        # Generate question list
        self.question_list = []
        for con in self.cons[1:]:
            self.question_list.append(con)
        for ant in self.ants:
            self.question_list.append(ant)
        self.question = ""

        self.ruleHeap = Rules()
        for rule in related["RULES"]:
            self.ruleHeap.CreateRule(rule)

        # Value log will be a workmemory object
        self.valueLog = WorkMemory()

        self.lbl = QLabel('Especifique el valor de "<ID>":')

        self.value_edit = QComboBox()
        self.value_edit.addItem("T")
        self.value_edit.addItem("F")

        self.replace_btn = QPushButton("Replace")
        self.replace_btn.clicked.connect(self.Replace)

        self.rules_heap = QPlainTextEdit()
        self.rules_heap.setReadOnly(True)
        self.value_logs = QPlainTextEdit()
        self.value_logs.setReadOnly(True)

        self.hlayout1 = QHBoxLayout()
        self.hlayout1.addWidget(self.lbl)
        self.hlayout1.addWidget(self.value_edit)
        self.hlayout1.addWidget(self.replace_btn)

        self.hlayout2 = QHBoxLayout()
        self.hlayout2.addWidget(self.rules_heap)
        self.hlayout2.addWidget(self.value_logs)

        self.main_layout = QVBoxLayout()
        self.main_layout.addLayout(self.hlayout1)
        self.main_layout.addLayout(self.hlayout2)

        self.UpdateValueLog()
        self.UpdateRuleHeap()
        self.SetNextQuestion()

        self.setLayout(self.main_layout)
        self.setWindowTitle("Objective Reasoning - Questioning")
        self.show()

    def SetNextQuestion(self):
        idList = self.ruleHeap.GetIdentifiers()

        self.question = ""
        while (self.question not in idList):
            self.question = self.question_list.pop()
            print("IDLIST", idList)
            print("Selected {0} for question".format(self.question))
            if (self.question not in idList):
                msg = QMessageBox()
                msg.setText("SKIP")
                msg.exec()

        self.lbl.setText('Especifique el valor de "{0}":'.format(
            self.question))
        self.UpdateValueLog()
        self.UpdateRuleHeap()

    def Replace(self):
        # Get the rule
        value = self.value_edit.currentText().strip()
        # Add it to the logs
        self.valueLog.AddRule(self.question, value)
        # Propagate rule
        self.ruleHeap.Propagate(self.question, value)
        # If solutions are found, add them to logs and propagate them
        solutions = self.ruleHeap.GetSolutions()
        for sol in solutions:
            sol_st = Statement(sol)
            if (sol_st.root.sign):
                val = "T"
            else:
                val = "F"
            if (sol_st.root.symbol.mask not in ["T", "F"]):
                self.valueLog.AddRule(sol_st.root.symbol.mask, val)
                self.ruleHeap.Propagate(sol_st.root.symbol.mask, val)
                self.reasoned.append(sol_st.root.symbol.mask)

        self.UpdateValueLog()
        self.UpdateRuleHeap()
        if (self.ruleHeap.IsSolved()):
            # Enter finished state
            if (self.valueLog.RuleExists(self.objective)):
                self.Explain()
            else:
                self.Fail()
        else:
            try:
                self.SetNextQuestion()
            except:
                self.Fail()

    def UpdateValueLog(self):
        self.value_logs.setPlainText(
            str(self.valueLog) + "\n\nCONS: " + str(self.cons) + "\n\nANTS: " +
            str(self.ants) + "\n\nQUESTIONS: " + str(self.question_list) +
            "\n\nQUESTION: " + str(self.question) + "\n\nOBJECTIVE: " +
            str(self.objective))

    def UpdateRuleHeap(self):
        self.rules_heap.setPlainText(str(self.ruleHeap))

    def Finish(self):
        self.id_cmb.setReadOnly(True)
        self.replace_btn.setEnabled(False)

    def Fail(self):
        message = QMessageBox()
        message.setText(
            "I couldn't find a solution for this problem.Reasoning tree was exhausted before an answer was found"
        )
        message.exec()

    def Explain(self):
        explain_str = "Solution has been found: {0}\n".format(
            self.valueLog.GetRule(self.objective))
        for re in self.reasoned:
            past_lst = self.valueLog.GetPastKeys(re)
            explain_str += "\n{0} is {1} because:\n".format(
                re, self.valueLog.GetRule(re))
            for p in past_lst:
                explain_str += "\t{0} = {1}\n".format(p,
                                                      self.valueLog.GetRule(p))
        msg = QMessageBox()
        msg.setText(explain_str)
        msg.exec()