AI-ExpertSystem-Advanced

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

NAME
    AI::ExpertSystem::Advanced - Expert System with backward, forward and
    mixed algorithms

DESCRIPTION
    Inspired in AI::ExpertSystem::Simple but with additional features:

    *   Uses backward, forward and mixed algorithms.

    *   Offers different views, so user can interact with the expert system
        via a terminal or with a friendly user interface.

    *   The knowledge database can be stored in any format such as YAML, XML
        or databases. You just need to choose what driver to use and you are
        done.

    *   Uses certainty factors.

SYNOPSIS
    An example of the mixed algorithm:

        use AI::ExpertSystem::Advanced;
        use AI::ExpertSystem::Advanced::KnowledgeDB::Factory;

        my $yaml_kdb = AI::ExpertSystem::Advanced::KnowledgeDB::Factory->new('yaml',
            {
                filename => 'examples/knowledge_db_one.yaml'
            });

        my $ai = AI::ExpertSystem::Advanced->new(
                viewer_class => 'terminal',
                knowledge_db => $yaml_kdb,
                initial_facts => ['I'],
                verbose => 1);
        $ai->mixed();
        $ai->summary();

Attributes
    initial_facts
        A list/set of initial facts the algorithms start using.

        During the forward algorithm the task is to find a list of goals
        caused by these initial facts (the only data we have in that
        moment).

        Lets imagine your knowledge database is about symptoms and diseases.
        You need to find what diseases are caused by the symptoms of a
        patient, these first symptons are the initial facts.

        Initial facts as also asked and inference facts can be negative or
        positive. By default the initial facts are positive.

        Keep in mind that the data contained in this array can be the IDs or
        the name of the fact.

        This array will be converted to initial_facts_dict. And all the data
        (ids or or names) will be made of only IDs.

            my $ai = AI::ExpertSystem::Advanced->new(
                    viewer_class => 'terminal',
                    knowledge_db => $yaml_kdb,
                    initial_facts => ['I', ['F', '-'], ['G', '+']);

        As you can see if you want to provide the sign of a fact, just
        *encapsulate* it in an array, the first item should be the fact and
        the second one the sign.

    initial_facts_dict
        This dictionary (see AI::ExpertSystem::Advanced::Dictionary has the
        sasme data of initial_facts but with the additional feature(s) of
        proviing iterators and a quick way to find elements.

    goals_to_check
            my $ai = AI::ExpertSystem::Advanced->new(
                    viewer_class => 'terminal',
                    knowledge_db => $yaml_kdb,
                    goals_to_check => ['J']);

        When doing the backward() algorithm it's required to have at least
        one goal (aka hypothesis).

        This could be pretty similar to initial_facts, with the difference
        that the initial facts are used more with the causes of the rules
        and this one with the goals (usually one in a well defined knowledge
        database).

        The same rule of initial_facts apply here, you can provide the sign
        of the facts and you can provide the id or the name of them.

        From our example of symptoms and diseases lets imagine we have the
        hypothesis that a patient has flu, we don't know the symptoms it
        has, we want the expert system to keep asking us for them to make
        sure that our hypothesis is correct (or incorrect in case there's
        not enough information).

    goals_to_check_dict
        Very similar to goals_to_check (and indeed of initial_facts_dict).
        We want to make the job easier.

        It will be a dictionary made of the data of goals_to_check.

    inference_facts
        Inference facts are basically the core of an expert system. These
        are facts that are found and copied when a set of facts (initial,
        inference or asked) match with the causes of a goal.

        inference_facts is a AI::ExpertSystem::Advanced::Dictionary, it will
        store the name of the fact, the rule that caused these facts to be
        copied to this dictionary, the sign and the algorithm that triggered
        it.

    knowledge_db
        The object reference of the knowledge database
        AI::ExpertSystem::Advanced is using.

    asked_facts
        During the backward() algorithm there will be cases when there's no
        clarity if a fact exists. In these cases the backward() will be
        asking the user (via automation or real questions) if a fact exists.

        Going back to the initial_facts example of symptoms and diseases.
        Imagine the algorithm is checking a rule, some of the facts of the
        rule make a match with the ones of initial_facts or inference_facts
        but some wont, for these *unsure* facts the backward() will ask the
        user if a symptom (a fact) exists. All these asked facts will be
        stored here.

    visited_rules
        Keeps a record of all the rules the algorithms have visited and also
        the number of causes each rule has.

    verbose
            my $ai = AI::ExpertSystem::Advanced->new(
                    viewer_class => 'terminal',
                    knowledge_db => $yaml_kdb,
                    initial_facts => ['I'],
                    verbose => 1);

        By default this is turned off. If you want to know what happens
        behind the scenes turn this on.

        Everything that needs to be debugged will be passed to the debug()
        method of your viewer.

    viewer
        Is the object AI::ExpertSystem::Advanced will be using for printing
        what is happening and for interacting with the user (such as asking
        the asked_facts).

        This is practical if you want to use a viewer object that is not
        provided by AI::ExpertSystem::Advanced::Viewer::Factory.

    viewer_class
        Is the the class name of the viewer.

        You can decide to use the viewers
        AI::ExpertSystem::Advanced::Viewer::Factory offers, in this case you
        can pass the object or only the name of your favorite viewer.

    found_factor
        In your knowledge database you can give different *weights* to the
        facts of each rule (eg to define what facts have more *priority*).
        During the mixed() algorithm it will be checking what causes are
        found in the inference_facts and in the asked_facts dictionaries,
        then the total number of matches (or total number of certainity
        factors of each rule) will be compared versus the value of this
        factor, if it's higher or equal then the rule will be triggered.

        You can read the documentation of the mixed() algorithm to know the
        two ways this factor can be used.

    shot_rules
        All the rules that are shot are stored here. This is a hash, the key
        of each item is the rule id while its value is the precision time
        when the rule was shot.

        The precision time is useful for knowing when a rule was shot and
        based on that you can know what steps it followed so you can compare
        (or reproduce) them.

Constants
    * FACT_SIGN_NEGATIVE
        Used when a fact is negative, aka, a fact doesn't happen.

    * FACT_SIGN_POSITIVE
        Used for those facts that happen.

    * FACT_SIGN_UNSURE
        Used when there's no straight answer of a fact, eg, we don't know if
        an answer will change the result.

Methods
  shoot($rule, $algorithm)
    Shoots the given rule. It will do the following verifications:

    *   Each of the facts (causes) will be compared against the
        initial_facts_dict, inference_facts and asked_facts (in this order).

    *   If any initial, inference or asked fact matches with a cause but
        it's negative then all of its goals (usually only one by rule) will
        be copied to the inference_facts with a negative sign, otherwise a
        positive sign will be used.

    *   Will add the rule to the shot_rules hash.

  is_rule_shot($rule)
    Verifies if the given $rule has been shot.

  get_goals_by_rule($rule)
    Will ask the knowledge_db for the goals of the given $rule.

    A AI::ExpertSystem::Advanced::Dictionary will be returned.

  get_causes_by_rule($rule)
    Will ask the knowledge_db for the causes of the given $rule.

    A AI::ExpertSystem::Advanced::Dictionary will be returned.

  is_fact_negative($dict_name, $fact)
    Will check if the given $fact of the given dictionary ($dict_name) is
    negative.

  copy_to_inference_facts($facts, $sign, $algorithm, $rule)
    Copies the given $facts (a dictionary, usually goal(s) of a rule) to the
    inference_facts dictionary. All the given goals will be copied with the
    given $sign.

    Additionally it will add the given $algorithm and $rule to the inference
    facts. So later we can know how we got to a certain inference fact.

  compare_causes_with_facts($rule)
    Compares the causes of the given $rule with:

    *   Initial facts

    *   Inference facts

    *   Asked facts

    It will be couting the matches of all of the above dictionaries, so for
    example if we have four causes, two make match with initial facts, other
    with inference and the remaining one with the asked facts, then it will
    evaluate to true since we have a match of the four causes.

  get_causes_match_factor($rule)
    Similar to compare_causes_with_facts() but with the difference that it
    will count the "match factor" of each matched cause and return the total
    of this weight.

    The match factor is used by the mixed() algorithm and is useful to know
    if a certain rule should be shoot or not even if not all of the causes
    exist in our facts.

    The *match factor* is calculated in two ways:

    *   Will do a sum of the weight for each matched cause. Please note that
        if only one cause of a rule has a specified weight then the
        remaining causes will default to the total weight minus 1 and then
        divided with the total number of causes (matched or not) that don't
        have a weight.

    *   If no weight is found with all the causes of the given rule, then
        the total number of matches will be divided by the total number of
        causes.

  is_goal_in_our_facts($goal)
    Checks if the given $goal is in:

    1   The initial facts

    2   The inference facts

    3   The asked facts

  remove_last_ivisited_rule()
    Removes the last visited rule and return its number.

  visit_rule($rule, $total_causes)
    Adds the given $rule to the end of the visited_rules.

  copy_to_goals_to_check($rule, $facts)
    Copies a list of facts (usually a list of causes of a rule) to
    goals_to_check_dict.

    The rule ID of the goals that are being copied is also stored in the
    hahs.

  ask_about($fact)
    Uses viewer to ask the user for the existence of the given $fact.

    The valid answers are:

    + or FACT_SIGN_POSITIVE
        In case user knows of it.

    - or FACT_SIGN_NEGATIVE
        In case user doesn't knows of it.

    ~ or FACT_SIGN_UNSURE
        In case user doesn't have any clue about the given fact.

  get_rule_by_goal($goal)
    Looks in the knowledge_db for the rule that has the given goal. If a
    rule is found its number is returned, otherwise undef.

  forward()
        use AI::ExpertSystem::Advanced;
        use AI::ExpertSystem::Advanced::KnowledgeDB::Factory;

        my $yaml_kdb = AI::ExpertSystem::Advanced::KnowledgeDB::Factory->new('yaml',
                {
                    filename => 'examples/knowledge_db_one.yaml'
                });

        my $ai = AI::ExpertSystem::Advanced->new(
                viewer_class => 'terminal',
                knowledge_db => $yaml_kdb,
                initial_facts => ['F', 'J']);



( run in 0.598 second using v1.01-cache-2.11-cpan-39bf76dae61 )