File Coverage

blib/lib/AI/ExpertSystem/Simple/Rule.pm
Criterion Covered Total %
statement 75 75 100.0
branch 46 48 95.8
condition n/a
subroutine 12 12 100.0
pod 10 10 100.0
total 143 145 98.6


line stmt bran cond sub pod time code
1             package AI::ExpertSystem::Simple::Rule;
2              
3 1     1   1016 use strict;
  1         3  
  1         45  
4 1     1   6 use warnings;
  1         2  
  1         2004  
5              
6             our $VERSION = '1.2';
7              
8             sub new {
9 4     4 1 1793 my ($class, $name) = @_;
10              
11 4 100       30 die "Rule->new() takes 1 argument" if(scalar(@_) != 2);
12 2 100       13 die "Rule->new() argument 1 (NAME) is undefined" if(!defined($name));
13              
14 1         3 my $self = {};
15              
16 1         4 $self->{_name} = $name;
17 1         3 $self->{_conditions} = ();
18 1         3 $self->{_tested} = ();
19 1         2 $self->{_counter} = 0;
20 1         3 $self->{_actions} = ();
21 1         3 $self->{_state} = 'active';
22              
23 1         5 return bless $self, $class;
24             }
25              
26             sub reset {
27 2     2 1 546 my ($self) = @_;
28              
29             # Check the input
30              
31 2 100       16 die "Rule->reset() takes no arguments" if scalar(@_) != 1;
32              
33 1         2 $self->{_state} = 'active';
34 1         3 $self->{_counter} = 0;
35              
36 1         3 foreach my $name (keys %{$self->{_tested}}) {
  1         5  
37 2         5 $self->{_tested}->{$name} = 0;
38 2         5 $self->{_counter}++;
39             }
40             }
41              
42             sub add_condition {
43 7     7 1 1809 my ($self, $name, $value) = @_;
44              
45 7 100       68 die "Rule->add_condition() takes 2 arguments" if(scalar(@_) != 3);
46 5 100       17 die "Rule->add_condition() argument 1 (NAME) is undefined" if(!defined($name));
47 4 100       15 die "Rule->add_condition() argument 2 (VALUE) is undefined" if(!defined($value));
48              
49 3 100       10 if(defined($self->{_conditions}->{$name})) {
50 1         7 die "Rule->add_condition() has already been set";
51             }
52              
53 2         6 $self->{_conditions}->{$name} = $value;
54 2         4 $self->{_tested}->{$name} = 0;
55 2         6 $self->{_counter}++;
56             }
57              
58             sub add_action {
59 6     6 1 2028 my ($self, $name, $value) = @_;
60              
61 6 100       30 die "Rule->add_action() takes 2 arguments" if(scalar(@_) != 3);
62 4 100       16 die "Rule->add_action() argument 1 (NAME) is undefined" if(!defined($name));
63 3 100       15 die "Rule->add_action() argument 2 (VALUE) is undefined" if(!defined($value));
64              
65 2 100       8 if(defined($self->{_actions}->{$name})) {
66 1         9 die "Rule->add_action() has already been set";
67             }
68              
69 1         5 $self->{_actions}->{$name} = $value;
70             }
71              
72             sub name {
73 2     2 1 854 my ($self) = @_;
74              
75 2 100       14 die "Rule->name() takes no arguments" if(scalar(@_) != 1);
76              
77 1         13 return $self->{_name};
78             }
79              
80             sub state {
81 3     3 1 1221 my ($self) = @_;
82              
83 3 100       22 die "Rule->state() takes no arguments" if(scalar(@_) != 1);
84              
85 2         12 return $self->{_state};
86             }
87              
88             sub given {
89 7     7 1 2336 my ($self, $name, $value) = @_;
90              
91 7 100       34 die "Rule->given() takes 2 arguments" if(scalar(@_) != 3);
92 5 100       22 die "Rule->given() argument 1 (NAME) is undefined" if(!defined($name));
93 4 100       38 die "Rule->given() argument 2 (VALUE) is undefined" if(!defined($value));
94              
95 3 50       11 if(defined($self->{_conditions}->{$name})) {
96 3 50       21 if($self->{_tested}->{$name} == 1) {
    100          
97             # Already done this one
98             } elsif($self->{_conditions}->{$name} eq $value) {
99 2         6 $self->{_tested}->{$name} = 1;
100 2         4 $self->{_counter}--;
101 2 100       12 if($self->{_counter} == 0) {
102 1         2 $self->{_state} = 'completed';
103             }
104             } else {
105 1         3 $self->{_state} = 'invalid';
106             }
107             }
108              
109 3         17 return $self->{_state};
110             }
111              
112             sub actions {
113 2     2 1 619 my ($self) = @_;
114              
115 2 100       14 die "Rule->actions() takes no arguments" if(scalar(@_) != 1);
116              
117 1         3 return %{$self->{_actions}};
  1         6  
118             }
119              
120             sub conditions {
121 2     2 1 1769 my ($self) = @_;
122              
123 2 100       17 die "Rule->conditions() takes no arguments" if(scalar(@_) != 1);
124              
125 1         3 return %{$self->{_conditions}};
  1         8  
126             }
127              
128             sub unresolved {
129 4     4 1 539 my ($self) = @_;
130              
131 4 100       19 die "Rule->unresolved() takes no arguments" if(scalar(@_) != 1);
132              
133 3         6 my @list = ();
134              
135 3         5 foreach my $name (keys(%{$self->{_tested}})) {
  3         12  
136 6 100       19 if($self->{_tested}->{$name} == 0) {
137 3         6 push(@list, $name);
138             }
139             }
140              
141 3         18 return @list;
142             }
143              
144             1;
145              
146             =head1 NAME
147              
148             AI::ExpertSystem::Simple::Rule - A utility class for a simple expert system
149              
150             =head1 VERSION
151              
152             This document refers to verion 1.2 of AI::ExpertSystem::Simple::Rule, released June 10, 2003
153              
154             =head1 SYNOPSIS
155              
156             This is a utility class for AI::ExpertSystem::Simple
157              
158             =head1 DESCRIPTION
159              
160             =head2 Overview
161              
162             This class handles the rules
163              
164             =head2 Constructors and initialisation
165              
166             =over 4
167              
168             =item new( NAME )
169              
170             The constructor takes one argument, the NAME of the rule. The consition and actions are added later.
171              
172             =back
173              
174             =head2 Public methods
175              
176             =over 4
177              
178             =item reset( )
179              
180             Resets the state of the rule back to active and all the condition attributes to untested.
181              
182             =item add_condition( NAME, VALUE )
183              
184             This adds a condition attribute name / value pair.
185              
186             =item add_action( NAME, VALUE )
187              
188             This adds an action attribute name / value pair.
189              
190             =item name( )
191              
192             Returns the name of the rule.
193              
194             =item state( )
195              
196             Returns the current state of the rule.
197              
198             =item given( NAME, VALUE )
199              
200             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
201             is changed in light of the result.
202              
203             =item actions( )
204              
205             Returns a list of the actions set in the rule.
206              
207             =item conditions( )
208              
209             Returns a list of the conditions matched in the rule.
210              
211             =item unresolved( )
212              
213             Returns a list of all the unresolved condition of the rule.
214              
215             =back
216              
217             =head2 Private methods
218              
219             None
220              
221             =head1 ENVIRONMENT
222              
223             None
224              
225             =head1 DIAGNOSTICS
226              
227             =over 4
228              
229             =item Rule->new() takes 1 argument
230              
231             When the constructor is initialised it requires one argument. This message is given if more or less arguments were supplied.
232              
233             =item Rule->new() argument 1 (NAME) is undefined
234              
235             The corrct number of arguments were supplied to the constructor, however the first argument, NAME, was undefined.
236              
237             =item Rule->reset() takes no arguments
238              
239             When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
240              
241             =item Rule->add_condition() takes 2 arguments
242              
243             When the method is called it requires two arguments. This message is given if more or less arguments were supplied.
244              
245             =item Rule->add_condition() argument 1 (NAME) is undefined
246              
247             The corrct number of arguments were supplied with the method call, however the first argument, NAME, was undefined.
248              
249             =item Rule->add_condition() argument 2 (VALUE) is undefined
250              
251             The corrct number of arguments were supplied with the method call, however the second argument, VALUE, was undefined.
252              
253             =item Rule->add_condition() has already been set
254              
255             This method has already been called and the value set. It cannot be called twice.
256              
257             =item Rule->add_action() takes 2 arguments
258              
259             When the method is called it requires two arguments. This message is given if more or less arguments were supplied.
260              
261             =item Rule->add_action() argument 1 (NAME) is undefined
262              
263             The corrct number of arguments were supplied with the method call, however the first argument, NAME, was undefined.
264              
265             =item Rule->add_action() argument 2 (VALUE) is undefined
266              
267             The corrct number of arguments were supplied with the method call, however the second argument, VALUE, was undefined.
268              
269             =item Rule->add_action() has already been set
270              
271             This method has already been called and the value set. It cannot be called twice.
272              
273             =item Rule->name() takes no arguments
274              
275             When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
276              
277             =item Rule->state() takes no arguments
278              
279             When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
280              
281             =item Rule->given() takes 2 arguments
282              
283             When the method is called it requires two arguments. This message is given if more or less arguments were supplied.
284              
285             =item Rule->given() argument 1 (NAME) is undefined
286              
287             The corrct number of arguments were supplied with the method call, however the first argument, NAME, was undefined.
288              
289             =item Rule->given() argument 2 (VALUE) is undefined
290              
291             The corrct number of arguments were supplied with the method call, however the second argument, VALUE, was undefined.
292              
293             =item Rule->actions() takes no arguments
294              
295             When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
296              
297             =item Rule->conditions() takes no arguments
298              
299             When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
300              
301             =item Rule->unresolved() takes no arguments
302              
303             When the method is called it requires no arguments. This message is given if more or less arguments were supplied.
304              
305             =back
306              
307             =head1 BUGS
308              
309             None
310              
311             =head1 FILES
312              
313             See Rules.t in the test directory
314              
315             =head1 SEE ALSO
316              
317             AI::ExpertSystem::Simple - The base class for the expert system
318              
319             AI::ExpertSystem::Simple::Goal - A utility class
320              
321             AI::ExpertSystem::Simple::knowledge - A utility class
322              
323             =head1 AUTHORS
324              
325             Peter Hickman (peterhi@ntlworld.com)
326              
327             =head1 COPYRIGHT
328              
329             Copyright (c) 2003, Peter Hickman. All rights reserved.
330              
331             This module is free software. It may be used, redistributed and/or
332             modified under the same terms as Perl itself.