#!/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() { $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 = ) { 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); }