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 findAllSubstitutions(action, atoms, subst): if not atoms: print(subst) applyLE(action, subst) applyLA(action, subst) return atom = atoms[0] name = get_head(atom) if name in env: facts = env[name] elif name in math_predicates: return findAllSubstitutions(action, atoms[1:], subst) else: facts = state for fact in facts: newSubst = unify(atom, fact) if newSubst != False and newSubst != None: copySubst = deepcopy(subst) copySubst.update(newSubst) remaining = deepcopy(atoms[1:]) for i in range(len(remaining)): remaining[i] = substitute(remaining[i], newSubst) findAllSubstitutions(action, remaining, copySubst)
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 preconditionsSatisfied(atoms): atom = atoms[0] #print("checking " + str(atom)) name = get_head(atom) if name in env: #print("NAME IN ENV") facts = env[name] elif name in math_predicates: res = checkMathPredicates(name, atom) if res == True and len(atoms) == 1: return True elif res == True: return preconditionsSatisfied(atoms[1:]) else: return False else: facts = state #print(facts) hasUnified = False for fact in facts: s = unify(atom, fact) #print("with " + str(fact) + " unify is " + str(s)) if s != False and s != None: hasUnified = True #print("unify " + str(atom) + " with " + str(fact) + " under ") #print(s) if len(atoms) == 1: return True remaining = deepcopy(atoms[1:]) for i in range(len(remaining)): remaining[i] = substitute(remaining[i], s) #print("remaining " + str(remaining)) res = preconditionsSatisfied(remaining) if res == False: return False if hasUnified: return True return False
def findSubstitutions(action, atoms, subst, allSubst, state): if not atoms: #print("found subst " + str(subst)) if len(subst) != 0: allSubst.append(subst) return True atom = atoms[0] name = get_head(atom) if name in env: facts = env[name] elif name in math_predicates: newSubst = {} res = checkMathPredicates(name, atom, newSubst) if res == False: return False else: if newSubst != {}: #TODO update the remaining with the newSubst? subst.update(newSubst) return findSubstitutions(action, atoms[1:], subst, allSubst, state) else: facts = state hasUnifiedWithAll = True for fact in facts: #TODO pot sa aplic newSubst in unify si sa nu mai fac remaining? newSubst = unify(atom, fact) if newSubst != False and newSubst != None: copySubst = deepcopy(subst) copySubst.update(newSubst) remaining = deepcopy(atoms[1:]) for i in range(len(remaining)): remaining[i] = substitute(remaining[i], newSubst) res = findSubstitutions(action, remaining, copySubst, allSubst, state) if not res: hasUnifiedWithAll = False return hasUnifiedWithAll
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