Esempio n. 1
0
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))
Esempio n. 2
0
 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)))
Esempio n. 3
0
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))
Esempio n. 4
0
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