use strict; use warnings; use AI::Fuzzy; use AI::FuzzyInference; print "##### Project Success Prediction System by Fuzzy Logic #####\n\n"; print "Predict the likelihood of a project to succeed based on\n"; print "1) Leadership, 2) Resources, and 3) Deadline.\n"; print "Press Ctrl-C to quit.\n\n"; print "Leadership quality (1: poor - 10: superb): "; my $predict = predict(); while(){print $predict->($_)} sub predict { my $infer = infer(); my @prompt = ( "Leadership quality (1: poor - 10: superb): ", "Resources (physical & human) available (1: scarce - 10: plenty): ", "Deadline (1: tight - 10: reasonable): " ); my @input; return sub { push @input, shift; return $#input < 2 ? $prompt[$#input+1] : $infer->(map{shift @input}1..3) . "\n\n" . $prompt[$#input+1]; }; } sub infer { my $proj = new AI::FuzzyInference; $proj->inVar('leadership', 1, 10, poor => [ 1,1, 5,0], good => [4,0, 7,1, 9,0], superb => [8,0, 10,1 ] ); $proj->inVar('resources', 1, 10, scarce => [ 1,1, 5,0], adequate => [4,0, 6,1, 8,0], plenty => [7,0, 10,1 ] ); $proj->inVar('deadline', 1, 10, tight => [ 1,1, 6,0], reasonable => [4,0, 10,1 ] ); $proj->outVar('success', 0, 100, unlikely => [ 0,1, 45,0], maybe => [40,0, 60,1, 85,0], likely => [80,0, 100,1 ] ); $proj->addRule( 'leadship=poor & resources=scarce & deadline=tight' => 'success=unlikely', 'leadership=poor & resources=scarce & deadline=reasonable' => 'success=unlikely', 'leadership=poor & resources=adequate & deadline=tight' => 'success=unlikely', 'leadership=poor & resources=adequate & deadline=reasonable' => 'success=maybe', 'leadership=poor & resources=plenty & deadline=tight' => 'success=maybe', 'leadership=poor & resources=plenty & deadline=reasonable' => 'success=maybe', 'leadership=good & resources=scarce & deadline=tight' => 'success=unlikely', 'leadership=good & resources=scarce & deadline=reasonable' => 'success=maybe', 'leadership=good & resources=adequate & deadline=tight' => 'success=maybe', 'leadership=good & resources=adequate & deadline=reasonable' => 'success=likely', 'leadership=good & resources=plenty & deadline=tight' => 'success=maybe', 'leadership=good & resources=plenty & deadline=reasonable' => 'success=likely', 'leadership=superb & resources=scarce & deadline=tight' => 'success=maybe', 'leadership=superb & resources=scarce & deadline=reasonable' => 'success=maybe', 'leadership=superb & resources=adequate & deadline=tight' => 'success=maybe', 'leadership=superb & resources=adequate & deadline=reasonable' => 'success=likely', 'leadership=superb & resources=plenty & deadline=tight' => 'success=maybe', 'leadership=superb & resources=plenty & deadline=reasonable' => 'success=likely' ); my $success = new AI::Fuzzy::Axis; use constant K => 1e-12; $success->addlabel("unlikely", - K, 0, 45 ); $success->addlabel("maybe", 40, 60, 85 ); $success->addlabel("likely", 80, 100, 100+K); return sub { $proj->compute(leadership => $_[0], resources => $_[1], deadline => $_[2]); my @predict = @{[$success->labelvalue($proj->value('success'))]}; my $predict; if ($predict[0] =~ /unlikely/i) { $predict = "\n\n~~~~~ Sorry, you're screwed. (Prediction confidence: " . int(100*$predict[1]) . "%). ~~~~~\n\n"; } elsif ($predict[0] =~ /maybe/i) { $predict = "\n\n----- Take heart, you'll probably make it. (Prediction confidence: " . int(100*$predict[1]) . "%). -----\n\n"; } elsif ($predict[0] =~ /likely/i) { $predict = "\n\n***** Congrat, you're like to succeed. (Prediction confidence: " . int(100*$predict[1]) . "%). *****\n\n"; } return $predict; }; }