diff --git a/NALGrammar.py b/NALGrammar.py index 855452a..ce0514c 100644 --- a/NALGrammar.py +++ b/NALGrammar.py @@ -70,11 +70,10 @@ def new_sentence_from_string(cls, sentence_string: str): assert ( punctuation == NALSyntax.Punctuation.Judgment or punctuation == NALSyntax.Punctuation.Question), " Currently only accepting Judgments and Questions." + # Find statement copula, subject string, and predicate string - subject, predicate, copula, copula_idx = parse_subject_predicate_copula_and_copula_index( - sentence_string[start_idx:end_idx + 1]) + statement = Statement.from_string(sentence_string[start_idx:end_idx + 1]) - statement = Statement(subject, predicate, copula) # Find Truth Value, if it exists start_truth_val_idx = sentence_string.find(NALSyntax.StatementSyntax.TruthValMarker.value) @@ -171,22 +170,59 @@ class Statement: statement ::= """ - def __init__(self, subject, predicate, copula, statement_connector=None): + def __init__(self, subject, predicate=None, copula=None, statement_connector=None): assert_term(subject) - assert_term(predicate) - assert_copula(copula) - self.copula: NALSyntax.Copula = copula - self.term: StatementTerm = StatementTerm(subject, predicate, copula, statement_connector) + + statement_term = subject + if predicate is not None: + statement_term = StatementTerm(subject, predicate, copula) + + if statement_connector is not None: + self.term = CompoundTerm([statement_term], statement_connector) + else: + self.term = statement_term def get_subject_term(self): - return self.term.get_subject_term() + if isinstance(self.term, StatementTerm): + return self.term.get_subject_term() + else: + return self.term def get_predicate_term(self): - return self.term.get_predicate_term() + if isinstance(self.term, StatementTerm): + return self.term.get_predicate_term() + else: + return None + + def get_statement_connector(self): + if not isinstance(self.term, StatementTerm): + return self.term.connector + else: + return None + + def get_copula(self): + if isinstance(self.term, StatementTerm): + return self.term.get_copula() + else: + return None def get_formatted_string(self): return self.term.get_formatted_string() + @classmethod + def from_string(cls,statement_string): + statement_string = statement_string.replace(" ", "") + statement_connector = None + if NALSyntax.TermConnector.get_term_connector_from_string( + statement_string[1:3]) == NALSyntax.TermConnector.Negation: + # found a negation statement connector + statement_connector = NALSyntax.TermConnector.Negation + statement_string = statement_string[4:-1] + + term = StatementTerm.from_string(statement_string) + return cls(subject=term.get_subject_term(), predicate=term.get_predicate_term(), + copula=term.get_copula(),statement_connector=statement_connector) + class EvidentialValue: """ @@ -337,6 +373,7 @@ def __str__(self): def _calculate_syntactic_complexity(self): assert False, "Complexity not defined for Term base class" + def contains_variable(self): return VariableTerm.VARIABLE_SYM in str(self) \ or VariableTerm.QUERY_SYM in str(self) @@ -384,6 +421,23 @@ def from_string(cls, term_string): return term + @classmethod + def simplify(cls, term): + if isinstance(term,AtomicTerm): + return term + elif isinstance(term, StatementTerm): + simplified_subject_term = Term.simplify(term.get_subject_term()) + simplified_predicate_term = Term.simplify(term.get_predicate_term()) + return StatementTerm(subject=simplified_subject_term, predicate=simplified_predicate_term, copula=term.copula) + elif isinstance(term, CompoundTerm): + if term.connector is NALSyntax.TermConnector.Negation: + if len(term.subterms) == 1: + pass + elif term.connector is NALSyntax.TermConnector.ExtensionalDifference:pass + elif term.connector is NALSyntax.TermConnector.IntensionalDifference:pass + elif term.connector is NALSyntax.TermConnector.ExtensionalImage:pass + elif term.connector is NALSyntax.TermConnector.IntensionalImage:pass + return term class VariableTerm(Term): class Type(enum.Enum): @@ -617,24 +671,38 @@ class StatementTerm(CompoundTerm): (P --> Q) """ - def __init__(self, subject: Term, predicate: Term, copula, statement_connector=None): + def __init__(self, subject: Term, predicate: Term, copula): assert_term(subject) assert_term(predicate) assert_copula(copula) - self.copula = copula subterms = [subject, predicate] + self.copula = copula if NALSyntax.Copula.is_symmetric(copula): subterms.sort(key=lambda t: str(t)) # sort alphabetically - CompoundTerm.__init__(self,subterms, statement_connector) + CompoundTerm.__init__(self,subterms, None) @classmethod - def from_string(cls, term_string): + def from_string(cls, statement_string): + """ - :param term_string: string to turn into a Statement Term - :return: The Statement Term created from the term_string + Parameter: statement_string - String of NAL syntax "(term copula term)" + + Returns: top-level subject term, predicate term, copula, copula index """ - subject, predicate, connector, _ = parse_subject_predicate_copula_and_copula_index(term_string) - return cls(subject, predicate, connector) + + statement_string = statement_string.replace(" ", "") + + # get copula + copula, copula_idx = get_top_level_copula(statement_string) + assert (copula is not None), "Copula not found. Exiting.." + + subject_str = statement_string[1:copula_idx] # get subject string + predicate_str = statement_string[ + copula_idx + len(copula.value):len(statement_string) - 1] # get predicate string + + return cls(subject=Term.from_string(subject_str), predicate=Term.from_string(predicate_str), + copula=copula) + def _calculate_syntactic_complexity(self): """ @@ -656,8 +724,11 @@ def get_subject_term(self) -> Term: def get_predicate_term(self) -> Term: return self.subterms[1] + def get_copula(self): + return self.copula + def get_copula_string(self): - return str(self.copula.value) + return str(self.get_copula().value) def get_formatted_string(self): """ @@ -668,33 +739,9 @@ def get_formatted_string(self): " " + self.get_copula_string() + " " + \ self.get_predicate_term().get_formatted_string() \ + NALSyntax.StatementSyntax.End.value - if self.connector is not None: - statement_string = NALSyntax.StatementSyntax.Start.value \ - + self.connector.value \ - + NALSyntax.StatementSyntax.TermDivider.value\ - + statement_string\ - + NALSyntax.StatementSyntax.End.value return statement_string -def parse_subject_predicate_copula_and_copula_index(statement_string): - """ - Parameter: statement_string - String of NAL syntax "(term copula term)" - - Returns: top-level subject term, predicate term, copula, copula index - """ - statement_string = statement_string.replace(" ","") - - # get copula - copula, copula_idx = get_top_level_copula(statement_string) - assert (copula is not None), "Copula not found. Exiting.." - - subject_str = statement_string[1:copula_idx] # get subject string - predicate_str = statement_string[copula_idx + len(copula.value):len(statement_string) - 1] # get predicate string - - return Term.from_string(subject_str), Term.from_string(predicate_str), copula, copula_idx - - def get_top_level_copula(string): """ Searches for top-level copula in the string. diff --git a/NALInferenceRules.py b/NALInferenceRules.py index d95feab..3bb558c 100644 --- a/NALInferenceRules.py +++ b/NALInferenceRules.py @@ -262,7 +262,7 @@ def Revision(j1: NALGrammar.Sentence, j2: NALGrammar.Sentence): result_statement = NALGrammar.Statement(j1.statement.get_subject_term(), j1.statement.get_predicate_term(), - j1.statement.copula) + j1.statement.get_copula()) result = NALGrammar.Judgment(result_statement, result_truth) # merge in the parent sentences' evidential bases @@ -369,10 +369,10 @@ def Negation(j: NALGrammar.Sentence): Returns: """ NALGrammar.assert_sentence(j) - # Statement + result_statement = NALGrammar.Statement(j.statement.get_subject_term(), j.statement.get_predicate_term(), - j.statement.copula, + j.statement.get_copula(), statement_connector=NALSyntax.TermConnector.Negation) occurrence_time = j.stamp.occurrence_time @@ -411,7 +411,7 @@ def Conversion(j: NALGrammar.Sentence): # Statement result_statement = NALGrammar.Statement(j.statement.get_predicate_term(), j.statement.get_subject_term(), - j.statement.copula) + j.statement.get_copula()) occurrence_time = j.stamp.occurrence_time @@ -447,7 +447,7 @@ def Contraposition(j): result_statement = NALGrammar.Statement(negated_predicate_term, negated_subject_term, - j.statement.copula) + j.statement.get_copula()) if j.punctuation == NALSyntax.Punctuation.Judgment: result_truth = F_Contraposition(j.value.frequency,j.value.confidence) @@ -583,7 +583,7 @@ def Deduction(j1: NALGrammar.Sentence, j2: NALGrammar.Sentence): # Statement result_statement = NALGrammar.Statement(j2.statement.get_subject_term(), j1.statement.get_predicate_term(), - j1.statement.copula) + j1.statement.get_copula()) if j1.punctuation == NALSyntax.Punctuation.Judgment and j2.punctuation == NALSyntax.Punctuation.Judgment: @@ -634,22 +634,22 @@ def Analogy(j1: NALGrammar.Sentence, j2: NALGrammar.Sentence): #j1=M-->P, j2=S<->M result_statement = NALGrammar.Statement(j2.statement.get_subject_term(), j1.statement.get_predicate_term(), - j1.statement.copula) # S-->P + j1.statement.get_copula()) # S-->P elif j1.statement.get_subject_term() == j2.statement.get_subject_term(): # j1=M-->P, j2=M<->S result_statement = NALGrammar.Statement(j2.statement.get_predicate_term(), j1.statement.get_predicate_term(), - j1.statement.copula) # S-->P + j1.statement.get_copula()) # S-->P elif j1.statement.get_predicate_term() == j2.statement.get_predicate_term(): #j1=P-->M, j2=S<->M result_statement = NALGrammar.Statement(j1.statement.get_subject_term(), j2.statement.get_subject_term(), - j1.statement.copula) # P-->S + j1.statement.get_copula()) # P-->S elif j1.statement.get_predicate_term() == j2.statement.get_subject_term(): # j1=P-->M, j2=M<->S result_statement = NALGrammar.Statement(j1.statement.get_subject_term(), j2.statement.get_predicate_term(), - j1.statement.copula) # P-->S + j1.statement.get_copula()) # P-->S else: assert(False), "Error: Invalid inputs to nal_analogy: " + j1.get_formatted_string() + " and " + j2.get_formatted_string() @@ -699,22 +699,22 @@ def Resemblance(j1: NALGrammar.Sentence, j2: NALGrammar.Sentence): # j1=M<->P, j2=S<->M result_statement = NALGrammar.Statement(j2.statement.get_subject_term(), j1.statement.get_predicate_term(), - j1.statement.copula) # S<->P + j1.statement.get_copula()) # S<->P elif j1.statement.get_subject_term() == j2.statement.get_subject_term(): # j1=M<->P, j2=M<->S result_statement = NALGrammar.Statement(j2.statement.get_predicate_term(), j1.statement.get_predicate_term(), - j1.statement.copula) # S<->P + j1.statement.get_copula()) # S<->P elif j1.statement.get_predicate_term() == j2.statement.get_predicate_term(): # j1=P<->M, j2=S<->M result_statement = NALGrammar.Statement(j2.statement.get_subject_term(), j1.statement.get_subject_term(), - j1.statement.copula) # S<->P + j1.statement.get_copula()) # S<->P elif j1.statement.get_predicate_term() == j2.statement.get_subject_term(): # j1=P<->M, j2=M<->S result_statement = NALGrammar.Statement(j2.statement.get_predicate_term(), j2.statement.get_subject_term(), - j1.statement.copula) # S<->P + j1.statement.get_copula()) # S<->P else: assert ( False), "Error: Invalid inputs to nal_resemblance: " + j1.get_formatted_string() + " and " + j2.get_formatted_string() @@ -768,7 +768,7 @@ def Abduction(j1: NALGrammar.Sentence, j2: NALGrammar.Sentence): # Statement result_statement = NALGrammar.Statement(j2.statement.get_subject_term(), j1.statement.get_subject_term(), - j1.statement.copula) + j1.statement.get_copula()) if j1.punctuation == NALSyntax.Punctuation.Judgment and j2.punctuation == NALSyntax.Punctuation.Judgment: # Get Truth Value @@ -810,7 +810,7 @@ def Induction(j1: NALGrammar.Sentence, j2: NALGrammar.Sentence): NALGrammar.assert_sentence(j2) # Statement result_statement = NALGrammar.Statement(j2.statement.get_predicate_term(), - j1.statement.get_predicate_term(), j1.statement.copula) + j1.statement.get_predicate_term(), j1.statement.get_copula()) if j1.punctuation == NALSyntax.Punctuation.Judgment and j2.punctuation == NALSyntax.Punctuation.Judgment: # Get Truth Value @@ -852,7 +852,7 @@ def Exemplification(j1: NALGrammar.Sentence, j2: NALGrammar.Sentence): NALGrammar.assert_sentence(j2) # Statement result_statement = NALGrammar.Statement(j2.statement.get_predicate_term(), - j1.statement.get_subject_term(), j1.statement.copula) + j1.statement.get_subject_term(), j1.statement.get_copula()) if j1.punctuation == NALSyntax.Punctuation.Judgment and j2.punctuation == NALSyntax.Punctuation.Judgment: # Get Truth Value @@ -957,8 +957,8 @@ def IntensionalIntersectionOrDisjunction(j1, j2): NALGrammar.assert_sentence(j1) NALGrammar.assert_sentence(j2) - j1_copula = j1.statement.copula - j2_copula = j2.statement.copula + j1_copula = j1.statement.get_copula() + j2_copula = j2.statement.get_copula() # Statement connector = None copula = None @@ -1050,8 +1050,8 @@ def ExtensionalIntersectionOrConjunction(j1, j2): NALGrammar.assert_sentence(j1) NALGrammar.assert_sentence(j2) - j1_copula = j1.statement.copula - j2_copula = j2.statement.copula + j1_copula = j1.statement.get_copula() + j2_copula = j2.statement.get_copula() # Statement connector = None copula = None diff --git a/NARS.py b/NARS.py index b52e98d..74bb9e3 100644 --- a/NARS.py +++ b/NARS.py @@ -216,10 +216,10 @@ def process_judgment_task(self, task: NARSDataStructures.Task): Revise this judgment with the most confident belief, then insert it into the belief table """ - if task.is_from_input: - derived_sentences = NARSInferenceEngine.do_inference_one_premise(j1) - for derived_sentence in derived_sentences: - self.experience_task_buffer.put(NARSDataStructures.Task(derived_sentence)) + #if task.is_from_input: + derived_sentences = NARSInferenceEngine.do_inference_one_premise(j1) + for derived_sentence in derived_sentences: + self.experience_task_buffer.put(NARSDataStructures.Task(derived_sentence)) # revise the judgment self.process_judgment_sentence(j1, statement_concept) diff --git a/NARSGUI.py b/NARSGUI.py index 8e25024..78d0116 100644 --- a/NARSGUI.py +++ b/NARSGUI.py @@ -446,10 +446,12 @@ def listbox_datastructure_item_click_callback(event): label = tk.Label(item_info_window, text="", justify=tk.LEFT) label.grid(row=2, column=0) - label = tk.Label(item_info_window, text="Beliefs", font=('bold')) + # beliefs table listbox + beliefs_capacity_text = "("+str(len(object.belief_table)) + "/" + str(object.belief_table.capacity)+")" + label = tk.Label(item_info_window, text="Beliefs " + beliefs_capacity_text, font=('bold')) label.grid(row=4, column=0, columnspan=2) - # beliefs table listbox + belief_listbox = tk.Listbox(item_info_window, height=object_listbox_height, width=object_listbox_width, font=('', 8)) belief_listbox.grid(row=5, column=0, columnspan=2) @@ -463,7 +465,8 @@ def listbox_datastructure_item_click_callback(event): object.belief_table)) # define callback # desires table listbox - label = tk.Label(item_info_window, text="Desires", font=('bold')) + desires_capacity_text = "("+str(len(object.desire_table)) + "/" + str(object.desire_table.capacity)+")" + label = tk.Label(item_info_window, text="Desires " + desires_capacity_text, font=('bold')) label.grid(row=4, column=2, columnspan=2) desire_listbox = tk.Listbox(item_info_window, height=object_listbox_height, width=object_listbox_width, diff --git a/NARSInferenceEngine.py b/NARSInferenceEngine.py index 5c52152..55db849 100644 --- a/NARSInferenceEngine.py +++ b/NARSInferenceEngine.py @@ -23,6 +23,7 @@ def do_semantic_inference_two_premise(j1: NALGrammar.Sentence, j2: NALGrammar.Se """ NALGrammar.assert_sentence(j1) NALGrammar.assert_sentence(j2) + print("doing infernece " + j1.get_formatted_string() + " and " + j2.get_formatted_string()) if j1.statement.term.connector is not None or j2.statement.term.connector is not None: return [] @@ -42,13 +43,16 @@ def do_semantic_inference_two_premise(j1: NALGrammar.Sentence, j2: NALGrammar.Se j2_subject_term = j2.statement.get_subject_term() j1_predicate_term = j1.statement.get_predicate_term() j2_predicate_term = j2.statement.get_predicate_term() - j1_copula = j1.statement.copula - j2_copula = j2.statement.copula + j1_copula = j1.statement.get_copula() + j2_copula = j2.statement.get_copula() # check if the result will lead to tautology tautology = (j1_subject_term == j2_predicate_term and j1_predicate_term == j2_subject_term) or\ (j1_subject_term == j2_subject_term and j1_predicate_term == j2_predicate_term - and not (j1_copula == NALSyntax.Copula.Inheritance and j2_copula == NALSyntax.Copula.Inheritance)) + and + ((not NALSyntax.Copula.is_symmetric(j1_copula) and NALSyntax.Copula.is_symmetric(j2_copula)) # S-->P and P<->S + or + (NALSyntax.Copula.is_symmetric(j1_copula) and not NALSyntax.Copula.is_symmetric(j2_copula)))) # S-->P and P<->S # check if copula are the same different_copulas = (j1_copula != j2_copula) @@ -281,6 +285,9 @@ def do_inference_one_premise(j): Generates beliefs that are equivalent to j but in a different form. """ derived_sentences = [] + + if j.statement.get_statement_connector() is not None: return derived_sentences + if isinstance(j, NALGrammar.Judgment): # Negation (--,(S-->P)) derived_sentence = NALInferenceRules.Negation(j) @@ -288,13 +295,14 @@ def do_inference_one_premise(j): derived_sentences.append(derived_sentence) # Conversion (P --> S) - if not NALSyntax.Copula.is_symmetric(j.statement.copula) and j.value.frequency > 0: + if not NALSyntax.Copula.is_symmetric(j.statement.get_copula()) \ + and j.value.frequency > 0: derived_sentence = NALInferenceRules.Conversion(j) print_inference_rule(inference_rule="Conversion") derived_sentences.append(derived_sentence) # Contraposition ((--,P) ==> (--,S)) - if j.statement.copula == NALSyntax.Copula.Implication and j.value.frequency < 1: + if j.statement.get_copula() == NALSyntax.Copula.Implication and j.value.frequency < 1: derived_sentence = NALInferenceRules.Contraposition(j) print_inference_rule(inference_rule="Contraposition") derived_sentences.append(derived_sentence)