jarvis/modules/aiml/AIML.pl
2015-09-01 22:09:40 +02:00

85 lines
1.8 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
die("Usage: $0 aiml.xml\n") unless($ARGV[0]);
open(XML,"<$ARGV[0]") or die("open($ARGV[0]): $!\n");
my $aiml = '';
while(<XML>) {
$aiml .= $_;
}
close(XML);
my $parser = XML::Simple->new();
my $xml = $parser->XMLin($aiml);
print "xml: " . Dumper($xml) . "\n";
my $knowledge = {};
my $star;
foreach my $c (@{$xml->{category}}) {
print "pattern: $c->{pattern}\n";
&addKnowledge($knowledge,$c->{pattern},$c->{template});
}
print "Knowledge: " . Dumper($knowledge) . "\n";
print "> ";
while(my $input = <STDIN>) {
chomp($input);
print &findAnswer($knowledge,$input) . "\n";
print "> ";
}
sub findAnswer {
my ($struct,$input) = @_;
my ($key,$rest) = split(/\s+/,$input,2);
unless($struct->{uc($key)}) {
$star = $key;
$key = '*';
}
if($rest) {
if($struct->{uc($key)}) {
&findAnswer($struct->{uc($key)},$rest);
} elsif($struct->{template}) {
return(&parseAnswer($struct));
}
} else {
return(&parseAnswer($struct->{uc($key)}));
}
}
sub parseAnswer {
my ($struct) = @_;
if(ref($struct->{template}) eq '') {
return($struct->{template});
} elsif(ref($struct->{template}) eq 'HASH') {
if($struct->{template}->{random}) {
my @r = @{$struct->{template}->{random}->{li}};
srand($$^time^$struct);
return($r[rand(int($#r) + 1)]);
}
}
return('I do not know what that means.');
}
sub addKnowledge {
my ($ref,$pattern,$template) = @_;
my ($key,$rest) = split(/\s+/,$pattern,2);
if($rest) {
print "addKnowledge(): $key:$rest ref=" . ref($ref) . "\n";
$ref->{uc($key)} = {} unless(exists $ref->{uc($key)});
&addKnowledge($ref->{uc($key)},$rest,$template);
} else {
print "addKnowledge(): $key:$template\n";
$ref->{uc($key)}->{template} = $template;
}
return(1);
}