package AI::ExpertSystem::Simple::Rule;
use strict;
use warnings;
our $VERSION = '1.2';
sub new {
my ($class, $name) = @_;
die "Rule->new() takes 1 argument" if(scalar(@_) != 2);
die "Rule->new() argument 1 (NAME) is undefined" if(!defined($name));
my $self = {};
$self->{_name} = $name;
$self->{_conditions} = ();
$self->{_tested} = ();
$self->{_counter} = 0;
$self->{_actions} = ();
$self->{_state} = 'active';
return bless $self, $class;
}
sub reset {
my ($self) = @_;
# Check the input
die "Rule->reset() takes no arguments" if scalar(@_) != 1;
$self->{_state} = 'active';
$self->{_counter} = 0;
foreach my $name (keys %{$self->{_tested}}) {
$self->{_tested}->{$name} = 0;
$self->{_counter}++;
}
}
sub add_condition {
my ($self, $name, $value) = @_;
die "Rule->add_condition() takes 2 arguments" if(scalar(@_) != 3);
die "Rule->add_condition() argument 1 (NAME) is undefined" if(!defined($name));
die "Rule->add_condition() argument 2 (VALUE) is undefined" if(!defined($value));
if(defined($self->{_conditions}->{$name})) {
die "Rule->add_condition() has already been set";
}
$self->{_conditions}->{$name} = $value;
$self->{_tested}->{$name} = 0;
$self->{_counter}++;
}
sub add_action {
my ($self, $name, $value) = @_;
die "Rule->add_action() takes 2 arguments" if(scalar(@_) != 3);
die "Rule->add_action() argument 1 (NAME) is undefined" if(!defined($name));
die "Rule->add_action() argument 2 (VALUE) is undefined" if(!defined($value));
if(defined($self->{_actions}->{$name})) {
die "Rule->add_action() has already been set";
}
$self->{_actions}->{$name} = $value;
}
sub name {
my ($self) = @_;
die "Rule->name() takes no arguments" if(scalar(@_) != 1);
return $self->{_name};
}
sub state {
my ($self) = @_;
die "Rule->state() takes no arguments" if(scalar(@_) != 1);
return $self->{_state};
}
sub given {
my ($self, $name, $value) = @_;
die "Rule->given() takes 2 arguments" if(scalar(@_) != 3);
die "Rule->given() argument 1 (NAME) is undefined" if(!defined($name));
die "Rule->given() argument 2 (VALUE) is undefined" if(!defined($value));
if(defined($self->{_conditions}->{$name})) {
if($self->{_tested}->{$name} == 1) {
# Already done this one
} elsif($self->{_conditions}->{$name} eq $value) {
$self->{_tested}->{$name} = 1;
$self->{_counter}--;
if($self->{_counter} == 0) {
$self->{_state} = 'completed';
}
} else {
$self->{_state} = 'invalid';
}
}
return $self->{_state};
}
sub actions {
my ($self) = @_;
die "Rule->actions() takes no arguments" if(scalar(@_) != 1);
return %{$self->{_actions}};
}
sub conditions {
my ($self) = @_;
die "Rule->conditions() takes no arguments" if(scalar(@_) != 1);
return %{$self->{_conditions}};
}
sub unresolved {
my ($self) = @_;
die "Rule->unresolved() takes no arguments" if(scalar(@_) != 1);
my @list = ();
foreach my $name (keys(%{$self->{_tested}})) {
if($self->{_tested}->{$name} == 0) {
push(@list, $name);
}
}
return @list;
}
1;
=head1 NAME
AI::ExpertSystem::Simple::Rule - A utility class for a simple expert system
=head1 VERSION
This document refers to verion 1.2 of AI::ExpertSystem::Simple::Rule, released June 10, 2003
=head1 SYNOPSIS
This is a utility class for AI::ExpertSystem::Simple
=head1 DESCRIPTION
=head2 Overview
This class handles the rules
=head2 Constructors and initialisation
=over 4
=item new( NAME )
The constructor takes one argument, the NAME of the rule. The consition and actions are added later.
=back
=head2 Public methods
=over 4
=item reset( )
Resets the state of the rule back to active and all the condition attributes to untested.
=item add_condition( NAME, VALUE )
This adds a condition attribute name / value pair.
=item add_action( NAME, VALUE )
This adds an action attribute name / value pair.
=item name( )
Returns the name of the rule.
=item state( )
Returns the current state of the rule.
=item given( NAME, VALUE )
The NAME / VALUE attribute pair is checked against the rule's conditions to see if a condition is met and the state of the rule
is changed in light of the result.
=item actions( )
Returns a list of the actions set in the rule.
=item conditions( )
Returns a list of the conditions matched in the rule.
=item unresolved( )
Returns a list of all the unresolved condition of the rule.
=back
=head2 Private methods
None
=head1 ENVIRONMENT
None
=head1 DIAGNOSTICS
=over 4
=item Rule->new() takes 1 argument
When the constructor is initialised it requires one argument. This message is given if more or less arguments were supplied.
=item Rule->new() argument 1 (NAME) is undefined
The corrct number of arguments were supplied to the constructor, however the first argument, NAME, was undefined.
=item Rule->reset() takes no arguments
When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
=item Rule->add_condition() takes 2 arguments
When the method is called it requires two arguments. This message is given if more or less arguments were supplied.
=item Rule->add_condition() argument 1 (NAME) is undefined
The corrct number of arguments were supplied with the method call, however the first argument, NAME, was undefined.
=item Rule->add_condition() argument 2 (VALUE) is undefined
The corrct number of arguments were supplied with the method call, however the second argument, VALUE, was undefined.
=item Rule->add_condition() has already been set
This method has already been called and the value set. It cannot be called twice.
=item Rule->add_action() takes 2 arguments
When the method is called it requires two arguments. This message is given if more or less arguments were supplied.
=item Rule->add_action() argument 1 (NAME) is undefined
The corrct number of arguments were supplied with the method call, however the first argument, NAME, was undefined.
=item Rule->add_action() argument 2 (VALUE) is undefined
The corrct number of arguments were supplied with the method call, however the second argument, VALUE, was undefined.
=item Rule->add_action() has already been set
This method has already been called and the value set. It cannot be called twice.
=item Rule->name() takes no arguments
When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
=item Rule->state() takes no arguments
When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
=item Rule->given() takes 2 arguments
When the method is called it requires two arguments. This message is given if more or less arguments were supplied.
=item Rule->given() argument 1 (NAME) is undefined
The corrct number of arguments were supplied with the method call, however the first argument, NAME, was undefined.
=item Rule->given() argument 2 (VALUE) is undefined
The corrct number of arguments were supplied with the method call, however the second argument, VALUE, was undefined.
=item Rule->actions() takes no arguments
When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
=item Rule->conditions() takes no arguments
When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
=item Rule->unresolved() takes no arguments
When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
=back
=head1 BUGS
None
=head1 FILES
See Rules.t in the test directory
=head1 SEE ALSO
AI::ExpertSystem::Simple - The base class for the expert system
AI::ExpertSystem::Simple::Goal - A utility class
AI::ExpertSystem::Simple::knowledge - A utility class
=head1 AUTHORS
Peter Hickman (peterhi@ntlworld.com)
=head1 COPYRIGHT
Copyright (c) 2003, Peter Hickman. All rights reserved.
This module is free software. It may be used, redistributed and/or
modified under the same terms as Perl itself.