📄 respond.php
字号:
<?php
/*
Program E
Copyright 2002, Paul Rydell
This file is part of Program E.
Program E is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Program E is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Program E; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* Respond functions
*
* Second layer functions that are prior to entering the AIML match routine.
* @author Paul Rydell
* @copyright 2002
* @version 0.0.8
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @package Interpreter
*/
/**
* The general preferences and database details.
*/
require_once "botinst/dbprefs.php";
/**
* The matching engine functions of the AIML interpreter.
*/
require_once "graphnew.php";
/**
* A collection of generally useful utility functions
*/
require_once "util.php";
/**
* The file containing the function that process custom, non AIML 1.0.x specified, tags.
*/
require_once "plugins/customtags.php";
/**
* Start function for retrieving bot reply
*
* Checks to see if bot exists, if so calls reply() to get the repons to the user's input.
*
* @uses lookupbotid()
* @uses reply()
*
* @param string $userinput The user's input
* @param integer $uniqueid The user's session ID
* @param string $botname The bot's name, if no name selected the default value is "TestBot".
*
* @return string The bot's reply.
*/
function replybotname($userinput,$uniqueid,$botname = "TestBot"){
$botid = lookupbotid($botname);
if ($botid==-1){
print "I don't know that bot: $botname<BR>\n";
}
else {
return reply($userinput,$uniqueid,$botid);
}
}
/**
* Main container function in creating the bot's reply.
*
* This function is the 'manager' of all the sub-funtions that do the real processing. It creates a class
* called Response that is used throughout the application.
*
* @uses addinputs()
* @uses addthats()
* @uses bget()
* @uses cleanup()
* @uses getthat()
* @uses loadcustomtags()
* @uses logconversation()
* @uses normalsentences()
* @uses respond()
* @uses ss_timing_current()
* @uses ss_timing_start()
* @uses ss_timing_stop()
*
* @global string that The conversation's previous bot output
* @global string topic The contents of the AIML tag 'Topic'
* @global integer uid The session ID of the user (previously $uniqueid)
* @global integer loopcounter Counts the number of time a particular category is used in the same match trace.
* @global array patternmatched The pattern's that matched the
*
* @param string $userinput The user's input.
* @param integer $uniqueid The user's session ID.
* @param integer $bot The bot's ID.
*
* @return object A class link to 'Response'.
*/
function reply($userinput,$uniqueid, $bot = 1){
global $that,$topic,$uid,$loopcounter,$patternmatched,$inputmatched,$selectbot;
cleanup();
ss_timing_start("all");
$patternmatched=array();
$inputmatched=array();
$myresponse = new Response;
$myresponse->errors="";
$uid=$uniqueid;
$selectbot=$bot;
// Load the custom plugin tags
loadcustomtags();
// Get the "that" and the "topic"
$that=getthat(1,1);
$topic=bget("TOPIC");
// Normalize the input
$allinputs=normalsentences($userinput);
// If nothing said then use INACTIVITY special input
if (sizeof($allinputs)==0){
$allinputs[]="INACTIVITY";
}
// Put all the inputs into the <input> stack.
addinputs($allinputs);
$finalanswer="";
// Build our response to all of the inputs.
for ($x=0;$x<sizeof($allinputs);$x++){
$finalanswer.=respond($allinputs[$x]);
}
if (($loopcounter>LOOPINGLIMIT)&&(LOOPINGLIMIT!=-1)){
$finalanswer=LOOPINGERRORMSG;
$myresponse->errors="LOOPINGLIMIT";
}
// Put the final answers into the <that> stack.
addthats(normalsentences($finalanswer));
// Log the conversation
logconversation($userinput,$finalanswer);
$myresponse->response=$finalanswer;
$myresponse->patternsmatched=$patternmatched;
$myresponse->inputs=$inputmatched;
ss_timing_stop("all");
$myresponse->timer=ss_timing_current("all");
return $myresponse;
}
/**
* This is the second level response function.
*
* After reply() this function is the second level function to get the answer to the user's input.
*
* @uses bget()
* @uses debugger()
* @uses gettemplate()
* @uses GetXMLTree()
* @uses recursechildren()
*
* @global string
* @global integer
* @global array
* @global array
*
* @param string $sentence The sentence to be matched.
*
* #return string The response to the user's input.
*/
function respond($sentence){
global $that,$loopcounter,$patternmatched,$inputmatched;
$topic = bget("topic");
$loopcounter++;
if (($loopcounter>LOOPINGLIMIT)&&(LOOPINGLIMIT != -1)){
return "";
}
$inputstarvals=array();
$thatstarvals=array();
$topicstarvals=array();
debugger("respond called with sentence: $sentence",3);
flush();
if ($that==""){
$that="<nothing>";
}
if ($topic==""){
$topic="<nothing>";
}
if ($sentence==""){
return "";
}
else{
//If we found a template
$template=gettemplate($sentence,$that,$topic,$inputstarvals,$thatstarvals,$topicstarvals,$s_patternmatched,$s_inputmatched);
$patternmatched[]=$s_patternmatched;
$inputmatched[]=$s_inputmatched;
if ($template!=""){
$template="<xml><TEMPLATE>" . $template . "</TEMPLATE></xml>";
debugger ("found template: $template",2);
$root=GetXMLTree($template);
if (!isset($root[0]['children'][0]['value'])){
$root=$root[0]['children'][0]['children'];
}
else {
$root=$root[0]['children'][0]['value'];
}
/*
if ($root[0]['children'][0]['value']==""){
$root=$root[0]['children'][0]['children'];
}
else {
$root=$root[0]['children'][0]['value'];
}
*/
$myresponse=recursechildren($root,$inputstarvals,$thatstarvals,$topicstarvals);
debugger("recursechildren ret: $myresponse",3);
return $myresponse;
}
}
}
/**
* Third level response processing
*
* This function is the 'manager' function of the template processing.
*
* @uses handlenode()
*
* @param mixed $xmlnode Getting either a string or an array from respond() func.
* @param array $inputstar If a matched pattern includes *'s then what is covere by the * is found here.
* @param array $thatstar if a used that contains a star, then what is covered by the * is found here.
* @param array $topicstar if a used topic contains a star, then what is covered by the * is found here.
*
* @return string The bot's response.
*/
function recursechildren($xmlnode,$inputstar,$thatstar,$topicstar){
// Getting either a string or an array from respond() func.
$response="";
if (is_array($xmlnode)){
// if ($xmlnode['value']==""){
if (!isset($xmlnode['value'])){
for ($x=0;$x<sizeof($xmlnode);$x++){
$response .= handlenode($xmlnode[$x],$inputstar,$thatstar,$topicstar);
}
}
else {
$response .= handlenode($xmlnode['value'],$inputstar,$thatstar,$topicstar);
}
}
else {
$response .= handlenode($xmlnode,$inputstar,$thatstar,$topicstar);
}
return $response;
}
/**
* Get the real XML child
*
* Get the real XML child which is used for processing AIML tags that may contain other AIML tags, such as SRAI, CONDITION etc.
*
*
* @param array $xmlnode
*
* @return mixed
*/
function realchild($xmlnode){
if (!isset($xmlnode["value"])){
if (isset($xmlnode["children"])){
return($xmlnode["children"]);
}
else {
return "";
}
}
else {
return($xmlnode["value"]);
}
/*
if ($xmlnode["value"]==""){
return($xmlnode["children"]);
}
else {
return($xmlnode["value"]);
}
*/
}
/**
* Handles the actual XML between the <template/> tags.
*
* Recognises the different tags, access the different functions to process each individual tag. Notes by the original developer: <br/>
* Why isn't this a huge switch statement? Because it has to do more comlicated checking than just string comparison to figure out what it should do. <br/>
* How can I organize this better? Good question.
*
* @todo It seems to me that this function could modelled similarly to the custom tag system. Where there is a seperate function for each tag.
*
* @uses getid()
* @uses getfdate()
* @uses getsize()
* @uses upperkeysarray()
* @uses debugger()
* @uses recursechildren()
* @uses respond()
* @uses botget()
* @uses gender()
* @uses getinput()
* @uses bset()
* @uses insertgossip()
* @uses firstthird()
* @uses firstsecond()
* @uses getthat()
* @uses realchild()
*
* @param mixed $xmlnode Getting either a string or an array from recursechildren() func.
* @param array $inputstar If a matched pattern includes *'s then what is covere by the * is found here.
* @param array $thatstar if a used that contains a star, then what is covered by the * is found here.
* @param array $topicstar if a used topic contains a star, then what is covered by the * is found here.
*
* @return string The bot's response.
*/
function handlenode($xmlnode,$inputstar,$thatstar,$topicstar){
if (!is_array($xmlnode)){
return $xmlnode;
}
elseif (strtoupper($xmlnode["tag"])=="ID"){
return getid();
}
elseif (strtoupper($xmlnode["tag"])=="DATE"){
return getfdate();
}
elseif (strtoupper($xmlnode["tag"])=="VERSION"){
return PROGRAMEVERSION;
}
elseif (strtoupper($xmlnode["tag"])=="SIZE"){
return getsize();
}
elseif (strtoupper($xmlnode["tag"])=="STAR"){
$mynode=upperkeysarray($xmlnode["attributes"]);
//$starindex=$xmlnode["attributes"]["INDEX"];
if (!((is_array($mynode))&&(isset($mynode["INDEX"])))){
$mynode["INDEX"]="";
}
$starindex=$mynode["INDEX"];
if ($starindex==""){
$starindex="1";
}
debugger("starindex: $starindex",3);
//print_r($inputstar);
return $inputstar[$starindex-1];
}
elseif (strtoupper($xmlnode["tag"])=="THATSTAR"){
$mynode=upperkeysarray($xmlnode["attributes"]);
//$starindex=$xmlnode["attributes"]["INDEX"];
if (!((is_array($mynode))&&(isset($mynode["INDEX"])))){
$mynode["INDEX"]="";
}
$starindex=$mynode["INDEX"];
if ($starindex==""){
$starindex="1";
}
debugger("starindex: $starindex",3);
//print_r($inputstar);
return $thatstar[$starindex-1];
}
elseif (strtoupper($xmlnode["tag"])=="TOPICSTAR"){
$mynode=upperkeysarray($xmlnode["attributes"]);
//$starindex=$xmlnode["attributes"]["INDEX"];
if (!((is_array($mynode))&&(isset($mynode["INDEX"])))){
$mynode["INDEX"]="";
}
$starindex=$mynode['INDEX'];
if ($starindex==""){
$starindex="1";
}
debugger("starindex: $starindex",3);
//print_r($inputstar);
return $topicstar[$starindex-1];
}
elseif (strtoupper($xmlnode["tag"])=="SRAI"){
// Build up a new response inside of here (using recursechildren function and then call response with it.
$newresponse=recursechildren(realchild($xmlnode),$inputstar,$thatstar,$topicstar);
debugger("newresponts: $newresponse",3);
return respond($newresponse);
}
elseif (strtoupper($xmlnode["tag"])=="SR"){
return respond($inputstar[0]);
}
elseif (strtoupper($xmlnode["tag"])=="RANDOM"){
$liarray=array();
$children = $xmlnode["children"];
for ($randomc=0;$randomc<sizeof($children);$randomc++){
if (strtoupper($children[$randomc]["tag"]) == "LI"){
$liarray[]=$randomc;
}
}
// Pick a random number from 0 to sizeof($liarray)-1
mt_srand ((float) microtime() * 1000000);
$lirandom= mt_rand(0,(sizeof($liarray)-1));
return recursechildren(realchild($children[$liarray[$lirandom]]),$inputstar,$thatstar,$topicstar);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -