def is_equal_to(a1, a2): # verificăm atomi cu același nume de predicat și același număr de argumente if not (is_atom(a1) and is_atom(a2) and get_head(a1) == get_head(a2) and len(get_args(a1)) == len(get_args(a2))): return False return all([ equal_terms(get_args(a1)[i], get_args(a2)[i]) for i in range(len(get_args(a1))) ])
def equal_terms(t1, t2): if is_constant(t1) and is_constant(t2): return get_value(t1) == get_value(t2) if is_variable(t1) and is_variable(t2): return get_name(t1) == get_name(t2) if is_function_call(t1) and is_function(t2): if get_head(t1) != get_head(t2): return all([equal_terms(get_args(t1)[i], get_args(t2)[i]) for i in range(len(get_args(t1)))]) return False
def get_conclusion(formula): # TODO ans = None for i in get_args(formula): if is_atom(i): ans = i return ans
def get_premises(formula): # TODO ans = [] for i in get_args(formula): if is_negative_literal(i): ans.append(i) return ans
def checkMathPredicates(name, atom, subst = None): args = get_args(atom) if is_variable(args[0]) or is_variable(args[1]): return False a = get_value(args[0]) b = get_value(args[1]) if name == 'isBigger': return a >= b elif name == 'isSmaller': return a < b elif name == 'equal': return a == b elif name == 'sum': if is_constant(args[2]) and (a + b == get_value(args[2])): return True elif is_variable(args[2]): subst[get_name(args[2])] = make_const(a + b) return True elif name == 'dif': if is_constant(args[2]) and (a - b == get_value(args[2])): return True elif is_variable(args[2]): subst[get_name(args[2])] = make_const(a - b) return True return False
def checkMathPredicates(name, atom): args = get_args(atom) if is_variable(args[0]) or is_variable(args[1]): return False a = get_value(args[0]) b = get_value(args[1]) if name == 'isBigger': return a >= b elif name == 'equal': return a == b elif name == 'sum': if is_constant(args[2]) and (a + b == get_value(args[2])): return True elif is_variable(args[2]): args[2] = substitute(args[2], {get_name(args[2]): make_const(a + b)}) return True elif name == 'dif': if is_constant(args[2]) and (a - b == get_value(args[2])): return True elif is_variable(args[2]): args[2] = substitute(args[2], {get_name(args[2]): make_const(a - b)}) return True return False
def forward_chaining(kb, theorem, verbose=True): # Salvăm baza de date originală, lucrăm cu o copie local_kb = deepcopy(kb) # Două variabile care descriu starea căutării got_new_facts = True # s-au găsit fapte noi la ultima căutare is_proved = False # a fost demostrată teorema # Verificăm dacă teorema este deja demonstrată for fact in filter(is_fact, local_kb): if unify(fact, theorem): if verbose: print("This already in KB: " + print_formula(fact, True)) is_proved = True break while (not is_proved) and got_new_facts: got_new_facts = False for rule in filter(is_rule, local_kb): # Pentru fiecare regulă new_facts = apply_rule(rule, list(filter(is_fact, local_kb))) new_facts = list( filter( lambda fact: not any( list( filter(lambda orig: is_equal_to(fact, orig), local_kb))), new_facts)) if new_facts: if verbose: print("Applied rule: " + print_formula(rule, True) + ", obtained " + str(len(new_facts)) + " new facts.") if any(filter(lambda t: is_variable(t), get_args(get_conclusion(rule)))) and \ any(filter(lambda fact: is_equal_to(fact, get_conclusion(rule)), new_facts)): print( "Demonstration is too general, the conclusion is not instantiated (facts obtained:", ",".join([print_formula(f, True) for f in new_facts]), ").") return False got_new_facts = True for fact in new_facts: #if verbose: print("New fact: " + print_formula(fact, True)) if unify(fact, theorem) != False: is_proved = True add_statement(local_kb, fact) if verbose: print("Now in KB: " + print_formula(fact, True)) break add_statement(local_kb, fact) if is_proved: break if verbose: if is_proved: print("The theorem is TRUE!") else: print("The theorem is FALSE!") return is_proved
def apply_rule(rule, facts): print(facts) resulting_facts = [] premises = list(map(lambda x: get_args(x)[0], get_premises(rule))) print premises substitutions = [] for premise in premises: print('*** premise ***') print(premise) print('*** end premise ***') new_substitutions = [] for fact in facts: print('*** premise ***') print(fact) print('*** end premise ***') res = unify(premise, fact) if res: substitutions.append(res) for substitution in substitutions: res = unify(premise, fact, substitution) if res: new_substitutions.append(res) for new_subst in new_substitutions: substitutions.append(new_subst) print(substitutions) for subst in substitutions: res = substitute(get_conclusion(rule), subst) if res and res not in resulting_facts: resulting_facts.append(res) return resulting_facts
def apply_rule(rule, facts): # TODO subst = {} prem = {} ans = [] values = {} fact_values = {} for fact in facts: vals = [] for arg in get_args(fact): vals.append(get_value(arg)) if get_head(fact) not in values: values[get_head(fact)] = [tuple(vals)] else: values[get_head(fact)].append(tuple(vals)) if get_head(fact) not in fact_values: fact_values[get_head(fact)] = [fact] else: fact_values[get_head(fact)].append(fact) for r in get_premises(rule): if isinstance(r, Sentence): var = get_name(get_args(get_args(r)[0])[0]) prm = get_head(get_args(r)[0]) prem[(prm, var)] = get_args(r)[0] continue var = get_name(get_args(r)[0]) prem[(get_head(r), var)] = [r] index_h = {} max_index_h = {} for (pred, var) in prem: index_h[(pred, var)] = 0 max_index_h[(pred, var)] = 0 if pred in values: max_index_h[(pred, var)] = len(values[pred]) pred = [] for x in prem: pred.append(x) current_p = 0 subst = {} while 1: p = pred[current_p] prd = p[0] val = p[1] p_index = index_h[p] if p_index == max_index_h[p]: index_h[p] = 0 if current_p == 0: break current_p = current_p - 1 p = pred[current_p] for x in get_args(prem[p]): name = get_name(x) if name in subst: del subst[name] index_h[p] = index_h[p] + 1 continue b_subst = deepcopy(subst) aux_subst = unify(prem[p], fact_values[prd][p_index], subst) if aux_subst!=False: subst = aux_subst if current_p == len(pred) - 1: ans.append(substitute(get_conclusion(rule),subst)) subst = {} current_p = 0 next_index = index_h[p] + 1 index_h[p] = next_index p = pred[current_p] continue else: subst = b_subst index_h[p] = index_h[p] + 1 if index_h[p] == max_index_h[p]: index_h[p] = 0 current_p = current_p - 1 index_h[pred[current_p]] = index_h[pred[current_p]] + 1 p = pred[current_p] for x in get_args(prem[p]): name = get_name(x) if name in subst: del subst[name] continue if current_p < len(pred) - 1: current_p = current_p + 1 continue index_h[p] = index_h[p] + 1 return ans
def is_rule(formula): # TODO for i in get_args(formula): if is_negative_literal(i): return True return False
def get_conclusion(formula): for arg in get_args(formula): if is_positive_literal(arg): return arg
def get_premises(formula): premises = [] for arg in get_args(formula): if is_negative_literal(arg): premises.append(arg) return premises