AI-ExpertSystem-Advanced

 view release on metacpan or  search on metacpan

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


=cut
sub is_fact_negative {
    my ($self, $dict_name, $fact) = @_;

    my $sign = $self->{$dict_name}->get_value($fact, 'sign');
    if (!defined $sign) {
        confess "This fact ($fact) does not exists!";
    }
    return $sign eq FACT_SIGN_NEGATIVE;
}

=head2 B<copy_to_inference_facts($facts, $sign, $algorithm, $rule)>

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

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

=cut
sub copy_to_inference_facts {
    my ($self, $facts, $sign, $algorithm, $rule) = @_;

    while(my $fact = $facts->iterate) {
        $self->{'inference_facts'}->append(
                $fact,
                {
                    name => $fact,
                    sign => $sign,
                    factor => 0.0,
                    algorithm => $algorithm,
                    rule => $rule
                });
    }
}

=head2 B<compare_causes_with_facts($rule)>

Compares the causes of the given C<$rule> with:

=over 4

=item *

Initial facts

=item *

Inference facts

=item *

Asked facts

=back

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.

=cut
sub compare_causes_with_facts {
    my ($self, $rule) = @_;
    
    my $causes = $self->get_causes_by_rule($rule);
    my $match_counter = 0;
    my $causes_total = $causes->size();
    
    while (my $cause = $causes->iterate) {
        foreach my $dict (qw(initial_facts_dict inference_facts asked_facts)) {
            if ($self->{$dict}->find($cause)) {
                $match_counter++;
            }
        }
    }
    return $match_counter eq $causes_total;
}

=head2 B<get_causes_match_factor($rule)>

Similar to L<compare_causes_with_facts()> but with the difference that it will
count the L<match factor> of each matched cause and return the total of this
weight.

The match factor is used by the L<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 I<match factor> is calculated in two ways:

=over 4

=item *

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.

=item *

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.

=back

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

    my $causes = $self->get_causes_by_rule($rule);
    my $causes_total = $causes->size();

    my ($factor_counter, $missing_factor, $match_counter, $nonfactor_match) =
        (0, 0, 0, 0);
    
    while (my $cause = $causes->iterate) {
        my $factor = $causes->get_value($cause, 'factor');



( run in 0.492 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )