AI-ExpertSystem-Advanced

 view release on metacpan or  search on metacpan

lib/AI/ExpertSystem/Advanced.pm  view on Meta::CPAN

        is => 'rw',
        isa => 'Str',
        default => 'terminal');

=item B<found_factor>

In your knowledge database you can give different I<weights> to the facts of
each rule (eg to define what facts have more I<priority>). During the
L<mixed()> algorithm it will be checking what causes are found in the
L<inference_facts> and in the L<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 L<mixed()> algorithm to know the two
ways this factor can be used.

=cut
has 'found_factor' => (
        is => 'rw',
        isa => 'Num',
        default => '0.5');

=item B<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.

=back

=cut
has 'shot_rules' => (
        is => 'ro',
        isa => 'HashRef[Str]');

=head1 Constants

=over 4

=item * B<FACT_SIGN_NEGATIVE>

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

=cut
use constant FACT_SIGN_NEGATIVE => '-';

=item * B<FACT_SIGN_POSITIVE>

Used for those facts that happen.

=cut
use constant FACT_SIGN_POSITIVE => '+';

=item * B<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.

=back

=cut
use constant FACT_SIGN_UNSURE   => '~';

=head1 Methods

=head2 B<shoot($rule, $algorithm)>

Shoots the given rule. It will do the following verifications:

=over 4

=item *

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

=item *

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
L<inference_facts> with a negative sign, otherwise a positive sign will be
used.

=item *

Will add the rule to the L<shot_rules> hash.

=back

=cut
sub shoot {
    my ($self, $rule, $algorithm) = @_;

    $self->{'shot_rules'}->{$rule} = gettimeofday;

    my $rule_causes = $self->get_causes_by_rule($rule);
    my $rule_goals = $self->get_goals_by_rule($rule);
    my $any_negation = 0;
    $rule_causes->populate_iterable_array();
    while(my $caused_fact = $rule_causes->iterate) {
        # Now, from the current rule fact, any of the facts were marked
        # as *negative* from the initial facts, inference or asked facts?
        $any_negation = 0;
        foreach my $dict (qw(initial_facts_dict inference_facts asked_facts)) {
            # Also make sure we are going to read from position 0 in our dicts
            $self->{$dict}->populate_iterable_array();
            while(my $dict_fact = $self->{$dict}->iterate) {
                if ($dict_fact eq $caused_fact) {
                    if ($self->is_fact_negative(
                                $dict,
                                $dict_fact)) {
                        $any_negation = 1;
                        last;
                    }
                }
            }
        }



( run in 1.085 second using v1.01-cache-2.11-cpan-e1769b4cff6 )