def predict(interp, finding, pattern): """ Obtains the interpretations that can be derived from a given one, by performing a deduction operation taking as hypothesis the unmatched finding of the interpretation. """ for pat in (p for p in ap.KNOWLEDGE if issubclass(p.Hypothesis, type(finding)) and not _singleton_violation(p, interp)): #The exploration stops at the first consistent matching of the finding if finding in _MATCHED_FINDINGS: _MATCHED_FINDINGS.remove(finding) return newint = Interpretation(interp) if is_singleton(pat.Hypothesis): newint.singletons = newint.singletons.copy() newint.singletons.add(pat.Hypothesis) pattern = AbstractionPattern(pat) #We set the known attributes of the new conjecture clone_attrs(pattern.hypothesis, finding) try: #The new predicted observation is focused. newint.focus.push(pattern.hypothesis, pattern) newint.verify_consecutivity_violation(pattern.hypothesis) newint.verify_exclusion(pattern.hypothesis) #And the number of abducible observations is increased. if ap.is_abducible(pat.Hypothesis): newint.nabd += 1 STATS.update(['D+' + str(pat)]) yield newint except InconsistencyError as error: newint.discard(str(error))
def nabd(self): """ Returns the number of abducible abstraction hypothesis in this focus. This number is used to correct the valuation heuristics in the searching algorithm. """ return sum(1 for o, p in self._lst if p is not None and o is p.hypothesis and ap.is_abducible(type(o)))
def abduce(interp, focus, pattern): """ Continues the inference by performing an abduction operation on the current inference focus of the interpretation. """ #If the focus is an hypothesis of a pattern, we require that pattern to #have sufficient supporting evidence. if ((pattern is not None and not pattern.sufficient_evidence) or focus in interp.abstracted or interp.focus.get_delayed_finding(focus) is not None): return if pattern is not None and pattern.automata.obs_proc is not NULL_PROC: pattern = copy.copy(pattern) try: pattern.finish() focus = pattern.hypothesis except InconsistencyError as error: return qobs = type(focus) for pat in (p for p in ap.KNOWLEDGE if issubclass(qobs, tuple(p.abstracted)) and not _singleton_violation(p, interp)): types = [tp for tp in pat.abstracted if issubclass(qobs, tp)] for typ in types: for trans in pat.abstractions[typ]: try: newint = Interpretation(interp) if pattern is not None: newint.observations = newint.observations.copy() newint.observations.add(focus) #Pattern consistency checking pattern = AbstractionPattern(pat) pattern.istate = trans.istate pattern.fstate = trans.fstate pattern.trseq.append((trans, focus)) pattern.evidence[typ].append(focus) trans.tconst(pattern, focus) pattern.check_temporal_consistency() trans.gconst(pattern, focus) #Interpretation updating newint.abstracted = newint.abstracted.copy() newint.abstracted.add(focus) if is_singleton(pat.Hypothesis): newint.singletons = newint.singletons.copy() newint.singletons.add(pat.Hypothesis) if ap.is_abducible(pat.Hypothesis): newint.nabd += 1 newint.focus.pop() newint.focus.push(pattern.hypothesis, pattern) newint.verify_exclusion(pattern.hypothesis) newint.verify_consecutivity_violation(pattern.hypothesis) STATS.update(['A+' + str(pat)]) yield newint except InconsistencyError as error: newint.discard(str(error))
def advance(interp, focus, pattern): """ Continues the inference by recovering the previous focus of attention, or by going to the next unexplained observation. It also resolves all the postponed matchings. """ max_ap_level = ap.get_max_level() #We can not advance if the focus is an hypothesis of a pattern with #insufficient evidence. newint = None if pattern is not None: if not pattern.sufficient_evidence: return #If there is an observation procedure for the focused hypothesis, the #execution takes place now. elif pattern.automata.obs_proc is not NULL_PROC: patcp = copy.copy(pattern) try: patcp.finish() newint = Interpretation(interp) if (focus.end.value != patcp.hypothesis.end.value or focus.start.value != patcp.hypothesis.start.value): newint.verify_consecutivity_violation(patcp.hypothesis) newint.verify_exclusion(patcp.hypothesis) focus = patcp.hypothesis except InconsistencyError: return #If the new focus is a delayed matching, we solve it at this point. finding = interp.focus.get_delayed_finding(interp.focus.top[0]) if finding is not None: newint = newint or Interpretation(interp) try: newint.focus.pop() pattern = newint.focus.top[1] pred, succ = pattern.get_consecutive(finding) _finding_match(newint, finding, focus, pattern.hypothesis.start.value, pattern.hypothesis.end.value, pred, succ, pattern.abstracts(finding)) #The matched hypothesis is included in the observations list newint.observations = newint.observations.copy() newint.observations.add(focus) except InconsistencyError as error: newint.discard(str(error)) return else: #HINT with the current knowledge base, we restrict the advancement to #observations of the first or the last level, not allowing partial #interpretations in the abstraction level. if (len(interp.focus) == 1 and 0 < ap.get_obs_level(type(focus)) < max_ap_level): return #We just move on the focus. newint = newint or Interpretation(interp) if ap.get_obs_level(type(focus)) == 0: newint.unintelligible = newint.unintelligible.copy() newint.unintelligible.add(focus) #If the focus is a hypothesis, it is added to the observations list if pattern is not None: newint.observations = newint.observations.copy() newint.observations.add(focus) newint.focus.pop() #If we have reached the top of the stack, we go ahead to the next #unexplained observation. if not newint.focus: try: unexp = newint.get_observations( start=focus.earlystart + 1, filt=lambda ev: ev not in newint.unintelligible and ev not in newint.abstracted and ap.is_abducible(type(ev))).next() newint.focus.push(unexp, None) except StopIteration: newint.discard('No unexplained evidence after the current point') return #Finally, we remove old observations from the interpretation, since they #won't be used in following reasoning steps, and they affect the #performance of the searching procedure. oldtime = max(newint.past_metrics.time, newint.focus.earliest_time) - C.FORGET_TIMESPAN newint.remove_old(oldtime) yield newint