File Coverage

blib/lib/Chorus/Expert.pm
Criterion Covered Total %
statement 11 44 25.0
branch 0 26 0.0
condition 0 6 0.0
subroutine 5 9 55.5
pod 2 4 50.0
total 18 89 20.2


line stmt bran cond sub pod time code
1             package Chorus::Expert;
2              
3 1     1   34437 use 5.006;
  1         4  
4 1     1   5 use strict;
  1         2  
  1         21  
5 1     1   5 use warnings;
  1         12  
  1         54  
6              
7             our $VERSION = '1.03';
8              
9             =head1 NAME
10              
11             Chorus::Expert - A simple skeleton of application using one or more Chorus::Engine objects (inference engines)
12             working together on a common task.
13              
14             =head1 VERSION
15              
16             Version 1.04
17              
18             =cut
19              
20             =head1 SYNOPSIS
21              
22             Chorus::Expert does 3 simple things :
23              
24             1 - Registers one or more Chorus::Engine objects
25             2 - Provides to each of them a shared working area ($SELF->BOARD)
26             3 - Enter an infinite loop on each inference engine until one of them declares the system as SOLVED.
27              
28             package A;
29            
30             use Chorus::Engine;
31             our $agent = Chorus::Engine->new();
32             $agent->addrule(...);
33              
34             # --
35            
36             package B;
37             use Chorus::Engine;
38             our $agent = Chorus::Engine->new();
39             $agent->addrule(...);
40            
41             # --
42            
43             use Chorus::Expert;
44             use A;
45             use B;
46            
47             my $xprt = Chorus::Expert->new();
48             $xprt->register($A::agent);
49             $xprt->register($B::agent);
50            
51             $xprt->process();
52              
53             =cut
54              
55 1     1   574 use Chorus::Frame;
  1         3  
  1         721  
56              
57             my @agents = ();
58             my $board = Chorus::Frame->new(); # shared with $self->BOARS between agents
59              
60             sub new {
61 0     0 0   my $class = shift;
62 0           return bless {}, $class;
63             }
64              
65             =head1 SUBROUTINES/METHODS
66              
67             =head2 register
68              
69             use Chorus::Expert;
70             use Chorus::Engine;
71            
72             my $xprt = Chorus::Expert->new();
73              
74             my $e1 = Chorus::Engine->new(); # inference engine 1
75             my $e2 = Chorus::Engine->new(); # inference engine 2
76              
77             $xprt->register($e1,$e2); # $e1 and $2 added to the list of agents
78             # providing to all of them a shared attribute named BOARD
79            
80             =cut
81              
82             sub register {
83 0     0 1   my $this = shift; # -> @_ ~equiv. @agents
84 0           $_->set('BOARD', $board) for @_;
85 0           $_->set('EXPERT', $this) for @_;
86 0           push @agents, @_;
87 0           return $this;
88             }
89              
90             # --
91              
92             =head2 process
93              
94             Tells the Chorus::Expert object to enter in an infinite loop until one of the engines
95             set the attribute $SELF->BOARD->{SOLVED} to something true.
96             The Chorus::Expert object will ask its agents, one after one, to test all its rules with all
97             possible combinations of its _SCOPE attributes. An agent never ends while at least one of its rules
98             returns a true value in the same loop (see Chorus::Engine documentation).
99            
100             $xprt->process(); # without argument
101             $xprt->process($something); # this argument will become $SELF->BOARD->INPUT for all agents
102            
103             =cut
104              
105             my $DEBUG = 0;
106              
107             sub debug {
108 0     0 0   my ($this, $level) = @_;
109 0           $DEBUG = $level;
110             }
111              
112             sub process {
113 0     0 1   my ($this, $input) = @_;
114 0           $board->set('INPUT', $input); # $self->BOARD->INPUT is the default INPUT shared betwwen agents
115             do {
116 0           my @processed = ();
117 0           for (@agents) {
118            
119 0 0         if ($_->_LOCK_UNTIL_STABLE ) {
120 0 0         print STDERR "Chorus::Expert - Agent $_->{_IDENT} is tagged with LOCK_UNTIL_STABLE\n" if $DEBUG;
121 0 0         last if grep { $_->_SUCCES } @processed;
  0            
122 0 0         print STDERR "Chorus::Expert - None of agents [" . join (',', map { $_->{_IDENT} || 'NO_NAME' } @processed) . "] have succeeded\n" if $DEBUG;
  0 0          
123             }
124            
125 0           do {
126            
127 0 0         if ($_->_REPLAY) {
128 0 0         print STDERR "Chorus::Expert - REPLAYING AGENT $_->{_IDENT} NOW.\n" if $DEBUG;
129 0           $_->delete('_REPLAY');
130             }
131            
132 0 0         print STDERR "Chorus::Expert - LOOPING ON AGENT $_->{_IDENT} NOW.\n" if $DEBUG;
133 0 0 0       $_->loop() unless $board->SOLVED or $board->FAILED;
134            
135             } while($_->_REPLAY);
136              
137 0           push @processed, $_;
138            
139 0 0         if ($_->_REPLAY_ALL) {
140 0 0         print STDERR "Chorus::Expert - WILL REPLAY ALL AGENTS NOW.\n" if $DEBUG;
141 0           $_->delete('_REPLAY_ALL');
142 0           last;
143             }
144             }
145 0   0       } until ($board->{SOLVED} or $board->{FAILED});
146            
147 0 0         ($board->delete('SOLVED'), return 1) if $board->{SOLVED};
148 0 0         ($board->delete('FAILED'), return undef) if $board->{FAILED};
149            
150             }
151              
152             =head1 AUTHOR
153              
154             Christophe Ivorra, C<< >>
155              
156             =head1 BUGS
157              
158             Please report any bugs or feature requests to C, or through
159             the web interface at L. I will be notified, and then you'll
160             automatically be notified of progress on your bug as I make changes.
161              
162             =head1 SUPPORT
163              
164             You can find documentation for this module with the perldoc command.
165              
166             perldoc Chorus::Expert
167              
168              
169             You can also look for information at:
170              
171             =over 4
172              
173             =item * RT: CPAN's request tracker (report bugs here)
174              
175             L
176              
177             =item * AnnoCPAN: Annotated CPAN documentation
178              
179             L
180              
181             =item * CPAN Ratings
182              
183             L
184              
185             =item * Search CPAN
186              
187             L
188              
189             =back
190              
191              
192             =head1 ACKNOWLEDGEMENTS
193              
194              
195             =head1 LICENSE AND COPYRIGHT
196              
197             Copyright 2013 Christophe Ivorra.
198              
199             This program is free software; you can redistribute it and/or modify it
200             under the terms of either: the GNU General Public License as published
201             by the Free Software Foundation; or the Artistic License.
202              
203             See http://dev.perl.org/licenses/ for more information.
204              
205              
206             =cut
207              
208       1     END { }
209              
210             1; # End of Chorus::Expert