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))
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()