1% ===================================================================
    2% File 'logicmoo_module_aiml_toplevel.pl'
    3% Purpose: An Implementation in SWI-Prolog of AIML
    4% Maintainer: Douglas Miles
    5% Contact: $Author: dmiles $@users.sourceforge.net ;
    6% Version: 'logicmoo_module_aiml.pl' 1.0.0
    7% Revision:  $Revision: 1.7 $
    8% Revised At:   $Date: 2002/07/11 21:57:28 $
    9% ===================================================================
   10
   11%:-module()
   12%:-include('logicmoo_utils_header.pl'). %<?
   13%:- style_check(-singleton).
   14%%:- style_check(-discontiguous).
   15/*
   16:- if( (current_prolog_flag(version,MMmmPP), MMmmPP<70000) ).
   17%:- style_check(-atom).
   18:- style_check(-string).
   19:- endif.
   20*/

   21
   22% :-catch(noguitracer,E,writeq(E)),nl.
   23
   24:-multifile(what/3).
   25:-multifile(response/2).
   26:-dynamic(dict/3).
   27:-multifile(dict/3).
   28
   29:-dynamic(lineInfoElement/4).
   34asserta_if_new_hlper1(C):-catch(C,_,fail),!.
   35asserta_if_new_hlper1(C):-asserta(C),!.
   36
   37:-dynamic(local_directory_search/1).
   38:-multifile(local_directory_search/1).
   39:-module_transparent(local_directory_search/1).
   40
   41addPaths:- source_location(File,_Line),file_directory_name(File, Directory),
   42   %context_module(M),
   43   file_directory_name(Directory,ParentDir),% cd(ParentDir),   
   44   asserta_if_new_hlper1(user:library_directory(ParentDir)),
   45   !,% writeq(M:asserta(user:library_directory(ParentDir))),nl,
   46   file_directory_name(ParentDir,ProgramK),
   47   asserta_if_new_hlper1(user:file_search_path(programk,ProgramK)),
   48   asserta_if_new_hlper1(local_directory_search(ProgramK)),
   49   absolute_file_name('aiml/',[relative_to(ProgramK),file_type(directory)],AIMLDir),
   50   asserta_if_new_hlper1(user:file_search_path(aiml,AIMLDir)),!.
   51
   52
   53:- addPaths.
   54
   55:-ensure_loaded(library('programk/logicmoo_module_aiml_shared.pl')).
   56:-ensure_loaded(library('programk/logicmoo_module_aiml_graphmaster.pl')).
   57:-ensure_loaded(library('programk/logicmoo_module_aiml_memory.pl')).
   58:-ensure_loaded(library('programk/logicmoo_module_aiml_natlang.pl')).
   59:-ensure_loaded(library('programk/logicmoo_module_aiml_cxt_path.pl')).
   60:-ensure_loaded(library('programk/logicmoo_module_aiml_loader.pl')).
   61:-ensure_loaded(library('programk/logicmoo_module_aiml_convertor.pl')).
   62:-ensure_loaded(library('programk/logicmoo_module_aiml_eval.pl')).
   63%%:-ensure_loaded(library('notaiml/tokenize.pl')).
   64
   65local_directory_search('cynd').
   66local_directory_search('cynd/programk').
   67local_directory_search('programk').
   68local_directory_search('../aiml').
   69local_directory_search('aiml').
   70local_directory_search('aiml/test_suite').
   71local_directory_search('special').
   72local_directory_search('..').
   73local_directory_search('../..').
   74
   75local_directory_search_combined2(PL):-local_directory_search(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
   76
   77local_directory_search_combined(X):-local_directory_search(X).
   78local_directory_search_combined(X):-local_directory_search_combined2(X).
   80local_directory_search_combined(PL):-local_directory_search_combined2(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
   81
   82run_chat_tests:-
   83   test_call(alicebot('Hi')),
   84   test_call(alicebot('What is your name')),
   85   test_call(alicebot('My name is Fred.')),
   86   test_call(alicebot('what is my name?')).
   87
   88test_call(G):-writeln(G),ignore(once(error_catch(G,E,writeln(E)))).
   89
   90
   91main_loop1(Atom):- current_input(In),!,
   92            read_line_to_codes(In,Codes),!,            
   93            atom_codes_or_eof(Atom,Codes),!,
   94            ignore(once(alicebot(Atom))),!.
   95
   96atom_codes_or_eof(end_of_file,end_of_file):-!.
   97atom_codes_or_eof(Atom,Codes):- atom_codes(Atom,Codes).
   98
   99
  100ping_default_files:-exists_source(aiml('../temp/aimlCore3.pl')),trace,ensure_loaded(aiml('../temp/aimlCore3.pl')),!.
  101ping_default_files:-exists_source(aiml('../temp/aimlCore.pl')),trace,ensure_loaded(aiml('../temp/aimlCore.pl')),!.
  102ping_default_files.
  103
  104main_loop:- ping_default_files,repeat,main_loop1(EOF),EOF==end_of_file.
  105
  106:-dynamic(default_channel/1).
  107:-dynamic(default_user/1).
  108
  109%default_channel( "#logicmoo").
  110%default_user(    "default_user").
  111
  112% say(Say):-writeq(Say),nl.
  113
  114% ===============================================================================================
  115% ALICE IN PROLOG
  116% ===============================================================================================
  117
  118say(X):-currentContext(say(X),Ctx),say(Ctx,X),!.
  119say(Ctx,X):- aiml_eval(Ctx,X,Y),!,answerOutput(Y,O),showTransition(O,Y,Trans),debugFmt(say(Trans)),!.
  120
  121showTransition(O,Y,O):-O==Y,!.
  122showTransition(O,Y,O=Y).
  123
  124alicebot:-
  125        currentContext(alicebot,Ctx),
  126        alicebotCTX(Ctx).
  127
  128alicebotCTX(Ctx):-
  129        repeat,
  130        current_input(In),
  131	read_line_to_codes(In,Codes),
  132        ( Codes==end_of_file 
  133         -> ! ;
  134        (tokenizeInput(Atom,Codes),
  135        %%atom_codes(Atom,Codes),
  136         ignore(once(alicebotCTX(Ctx,Atom))),
  137         Atom==end_of_file)).
  138
  139% ===============================================================================================
  140% Main Alice Input
  141% ===============================================================================================
  142
  143alicebot(Input):-
  144  currentContext(alicebot(Input),Ctx),
  145  alicebotCTX(Ctx,Input),!.
  146
  147alicebotCTX(Ctx,Input):- prolog_must(nonvar(Input)), alicebotCTX(Ctx,Input,Resp),!,say(Ctx,Resp),!.
  148%%alicebotCTX(Ctx,_):- atrace, say(Ctx,'-no response-'),!.
  149
  150% ===============================================================================================
  151% Main Alice Input-Output
  152% ===============================================================================================
  153alicebot([],_):-debugFmt('no input'),!,fail.
  154alicebot(Input,Resp):- currentContext(alicebot(Input),Ctx),alicebotCTX(Ctx,Input,Resp),!.
  155alicebot(In,Res):- !,ignore(Res='-no response-'(In)).
  156
  157alicebotCTX(_Ctx,[],[]):-!.
  158alicebotCTX(Ctx,Input,Resp):-
  159      context_module(M),
  160      debugOnError(tokenizeInput(Input,Tokens)),
  161      prolog_statistics:time(M:debugOnError(alicebotCTX4(Ctx,Input,Tokens,Resp))),!.
  162
  163
  164% ===============================================================================================
  165% Main Alice Source-Input-Output
  166% ===============================================================================================
  167alicebotCTX4(Ctx,String,Input,Res):- callableInput(Ctx,String,Input,Res),!.
  168alicebotCTX4(_Ctx,String,Input,_Resp):- isNoInput(String,Input), debugFmt('no input'),!,fail.
  169alicebotCTX4(Ctx,String,Input,Resp):-
  170  prolog_mustEach((
  171   ground(String),ground(Input),
  172   Atoms = Input,
  173   retractall(posibleResponse(_,_)),
  174   flag(a_answers,_,0),!,
  175   prolog_mustEach((
  176   getAliceMem(Ctx,'bot','you',User),
  177   getAliceMem(Ctx,'bot','me',_Robot),
  178   getAliceMem(Ctx,'bot',default('minanswers',1),MinAns0),unlistify(MinAns0,MinAns1),MinAnsMinusOne is MinAns1 -1,
  179   getAliceMem(Ctx,'bot',default('maxanswers',1),_MaxAns),
  180   %%setAliceMem(Ctx,User,'input',Atoms),
  181   pushInto1DAnd2DArray(Ctx,'request','input',5,Atoms,User),
  182   setAliceMem(Ctx,User,'rawinput',String))),
  183   thread_local_flag(sraiDepth,_,0),
  184   prolog_must((call_with_depth_limit_traceable(computeInputOutput(Ctx,1,Atoms,Output,N),8000,_DL),
  185	 ignore((nonvar(N),nonvar(Output),savePosibleResponse(N,Output))),flag(a_answers,X,X+1),
  186                X>=MinAnsMinusOne)),!,
  187   findall(NR-OR,posibleResponse(NR,OR),L),!,
  188   (format('~n-> ~w~n',[L])),
  189   sort(L,S),
  190   dumpList(S),
  191   reverse(S,[Resp|_RR]),
  192   degrade(Resp),
  193   rememberSaidIt(Ctx,Resp))),!.
  194
  195isNoInput(String,Input):-trimWhitepaceOffEnds(Input,InputTrimed),Input\==InputTrimed,!,isNoInput(String,InputTrimed).
  196isNoInput(_,[]):-!.
  197isNoInput(_,['']):-!.
  198isNoInput(_,_):-fail.
  199% ===============================================================================================
  200% Call like a SRAI tag
  201% ===============================================================================================
  202computeInput(Ctx, VoteIn,NotList,InputM):-not(is_list(NotList)),!,listify(NotList,Input),maplist_safe(computeInnerEach(Ctx, VoteIn),Input,InputM).
  203computeInput(Ctx, VoteIn,Input,InputM):-maplist_safe(computeInnerEach(Ctx, VoteIn),Input,InputM).
  204
  205computeInputOutput(Ctx,VoteIn,Input,Output,VotesOut):-
  206    prolog_mustEach((computeInput(Ctx, VoteIn,Input,InputM),!,
  207                     computeElement(Ctx,VoteIn,srai,[],InputM,OutputM,VotesOM),
  208                     computeTemplateOutput(Ctx,VotesOM,OutputM,Output,VotesOut))).
  209
  210computeInputOutput(Ctx,VoteIn,Input,Output,VotesOut):-
  211   ((prolog_mustEach((computeAnswer(Ctx,VoteIn,element(srai,[],Input),OutputM,VotesOM),
  212                          computeTemplateOutput(Ctx,VotesOM,OutputM,Output,VotesOut))))),!.
  213
  214
  215
  216% ===============================================================================================
  217% Save Possible Responses (Degrade them as well)
  218% ===============================================================================================
  219:-dynamic(posibleResponse/2).
  220
  221savePosibleResponse(_N,Output):-posibleResponse(_,Output),!.
  222savePosibleResponse(N,Output):-
  223   findall(1,degraded(Output),L),!,
  224   length(L,K),
  225   SN is N - (K * 0.6)  , !,
  226   asserta(posibleResponse(SN,Output)).
  227
  228% ===============================================================================================
  229% Degrade Response
  230% ===============================================================================================
  231
  232:-dynamic(degraded/1).
  233
  234degrade(_-OR):-!,degrade(OR).
  235degrade(OR):-asserta(degraded(OR)).
  236
  237
  238% ===============================================================================================
  239% Expand Answers
  240% ===============================================================================================
  241flatten_if_list(List,Flat):-is_list(List),!,flatten(List,Flat),!.
  242
  243computeTemplate(Ctx,Votes,Input,Output,VotesO):-flatten_if_list(Input,Flat),!,computeTemplate0(Ctx,Votes,Flat,Output,VotesO).
  244computeTemplate(Ctx,Votes,Input,Output,VotesO):-computeTemplate0(Ctx,Votes,Input,Output,VotesO).
  245
  246computeTemplate0(Ctx,Votes,Input,Output,VotesO):-prolog_must(computeTemplate1(Ctx,Votes,Input,Output,VotesO)).
  247
  248computeTemplate1(_Ctx,Votes,In,Out,VotesO):-In==[],!,prolog_must((In=Out,Votes=VotesO)).
  249computeTemplate1(Ctx,Votes,IN,Out,VotesO):-IN=[I|N],!,computeTemplate11(Ctx,Votes,[I|N],Out,VotesO).
  250computeTemplate1(Ctx,VotesM,In,Out,VotesM):-traceAIML,expandVar(Ctx,In,Out).
  251computeTemplate1(_Ctx,Votes,In,Out,VotesO):-prolog_must((In=Out,Votes=VotesO)).
  252
  253computeTemplate11(_Ctx,Votes,In,Out,VotesO):-In==[],!,prolog_must((In=Out,Votes=VotesO)).
  254computeTemplate11(Ctx,Votes,[<,BR,/,>|B],OO,VotesO):-atom(BR),!,
  255   computeTemplate11(Ctx,Votes,[element(BR,[],[])|B],OO,VotesO).
  256computeTemplate11(Ctx,Votes,[A|B],[A|BB],VotesO):-atomic(A),!,computeTemplate11(Ctx,Votes,B,BB,VotesO).
  257computeTemplate11(Ctx,Votes,[A|B],OO,VotesO):-expandVar(Ctx,A,AA),computeTemplate11(Ctx,Votes,B,BB,VotesO),once(flatten([AA,BB],OO)).
  258
  259
  260traceAIML:-!.
  261
  262expandVar(_Ctx,Var,Var):-var(Var),!,traceAIML.
  263expandVar(_Ctx,[Var|_],Var):- !,atrace,traceAIML.
  264expandVar(Ctx,In,Out):-atom(In),atom_concat('$',NameVar,In),!,expandVariable(Ctx,NameVar,Out).
  265expandVar(_Ctx,In,Out):-atomic(In),Out=In,!.
  266expandVar(Ctx,star(A,B,C),Out):-!,starName(A,AStar),!,expandVar(Ctx,element(AStar,B,C),Out).
  267expandVar(Ctx,element(A,B,C),Out):-!,computeElementMust(Ctx,1,A,B,C,Out,_VotesO).
  268expandVar(Ctx,In,Out):-computeAnswerMaybe(Ctx,1,In,Out,_VotesO),!.
  269expandVar(_Ctx,In,Out):-atrace,Out=In,!.
  270
  271expandVariable(Ctx,In,Out):-atom(In),atom_concat('$',NameVar,In),!,expandVariable(Ctx,NameVar,Out),!.
  272expandVariable(Ctx,In,Out):-atom(In),atom_concat(NameVar,'$',In),!,expandVariable(Ctx,NameVar,Out),!.
  273expandVariable(Ctx,name=Name,Result):-!,expandVariable(Ctx,Name,Result),!.
  274
  275expandVariable(_Ctx,nick,A):-!,default_user(B),!,from_atom_codes(A,B),!.
  276expandVariable(_Ctx,person,A):-!,default_user(B),!,from_atom_codes(A,B),!.
  277expandVariable(_Ctx,botnick,'jllykifsh'):-!.
  278expandVariable(_Ctx,mynick,'jllykifsh'):-!.
  279expandVariable(_Ctx,version,[push_nobrkspace,'1','.','0','.','1',pop_nobrkspace]):-!.
  280expandVariable(_Ctx,id,'$botnick$'):-!.
  281expandVariable(_Ctx,size,Size):-aimlCateSig(X),predicate_property(X,number_of_clauses(Size)),!.
  282%TODO extract the machine TimeZone
  283expandVariable(_Ctx,date,[Y,'-',M,'-',D]):-get_time(TimeStamp),stamp_date_time(TimeStamp,DateTime,'UTC'),date_time_value(date,DateTime,date(Y,M,D)),!.
  284expandVariable(_Ctx,mychan,A):-!,default_channel(B),!,from_atom_codes(A,B),!.
  285expandVariable(Ctx,NameVar,Result):-getAliceMem(Ctx,'bot',NameVar,Result),!.
  286expandVariable(Ctx,NameVar,Result):-getAliceMem(Ctx,'global',NameVar,Result),!.
  287
  288
  289globalAliceTagVar(BOT_ATOM):-not(atom(BOT_ATOM)),!,fail.
  290globalAliceTagVar(BOT_ATOM):-member(BOT_ATOM,[version,id,favfood,date,size,news,emotion,time,favoritebook,birthdate]).
  291globalAliceTagVar(BOT_ATOM):-atom_concat('fav',_,BOT_ATOM).
  292globalAliceTagVar(BOT_ATOM):-atom_concat('bot_',_,BOT_ATOM).
  293globalAliceTagVar(BOT_ATOM):-atom_concat('get_',_,BOT_ATOM).
  294globalAliceTagVar(BOT_ATOM):-atom_concat('get',_,BOT_ATOM).
  295
  296
  297from_atom_codes(Atom,Atom):-atom(Atom),!.
  298from_atom_codes(Atom,Codes):-convert_to_string(Codes,Atom),!.
  299from_atom_codes(Atom,Codes):-atom_codes(Atom,Codes).
  300
  301
  302:-dynamic(recursiveTag/1).
  303
  304
  305notRecursiveTag(system).
  306%%notRecursiveTag(template).
  307notRecursiveTag(condition).
  308notRecursiveTag(Loader):-loaderTag(Loader).
  309notRecursiveTag(li).
  310
  311loaderTag(Loader):-member(Loader,[aiml,topic,category,learn,load]).
  312
  313recursiveTag(random).
  314recursiveTag(srai).
  315recursiveTag(NoRec):-notRecursiveTag(NoRec),!,fail.
  316recursiveTag(_).
  317
  318isAimlTag(result):-!,fail.
  319isAimlTag(proof):-!,fail.
  320isAimlTag(get).
  321isAimlTag(_).
  322
  323prolog_mostly_ground(Out):-ground(Out),!.
  324prolog_mostly_ground(Out):-var(Out),!,atrace.
  325prolog_mostly_ground([H|_Out]):-!,prolog_must(prolog_mostly_ground1(H)),!.
  326prolog_mostly_ground(Out):- ((arg(_N,Out,Arg),prolog_must(prolog_mostly_ground1(Arg)),fail));true.
  327prolog_mostly_ground1(Out):-prolog_must(nonvar(Out)).
  328
  329computeInner(_Ctx, _Votes, In, Out) :- atom(In),!,Out=In.
  330computeInner(Ctx,Votes, In, Out) :- not(Out=(_-_)),!,computeAnswer(Ctx,Votes, In, Out, _VoteMid),!.
  331computeInner(Ctx,Votes, In, VoteMid-Out) :-  computeAnswer(Ctx,Votes, In, Out, VoteMid),!,prolog_must(nonvar(Out)),prolog_must(nonvar(VoteMid)).
  332
  333computeInnerEach(_Ctx, _Votes, In, Out) :- atom(In), !, Out=In , prolog_mostly_ground(Out).
  334
  335computeInnerEach(Ctx, _Votes, element(eval,ATTRIBS,INNER_XML),Rendered):-!,
  336   withAttributes(Ctx,ATTRIBS,aiml_eval_each(Ctx,INNER_XML,Rendered)),!.
  337
  338computeInnerEach(  Ctx, Votes, In, Out) :- prolog_must(computeAnswer(Ctx,Votes, In, Out, _VoteMid)),!, prolog_mostly_ground(Out).
  339computeInnerEach(_Ctx, _Votes, In, Out) :- !, Out=In,  prolog_mostly_ground((Out)).
  340
  341isNonCallable(A):-atomic(A),!.
  342isNonCallable([_|_]):-!.
  343isNonCallable(Pred):-predicate_property(Pred,number_of_clauses(_)),!,fail.
  344isNonCallable(_).
  345
  346isCallable(Pred):-not(isNonCallable(Pred)).
  347
  348% ===============================================================================================
  349% Compute Answer Element Probilities
  350% ===============================================================================================
  351computeElementMust(Ctx,Votes,Tag,Attribs,InnerXml,Resp,VotesO):-prolog_must(catch(computeElement(Ctx,Votes,Tag,Attribs,InnerXml,Resp,VotesO),E,throw(E))).
  352
  353computeAnswerMaybe(Ctx,Votes,element(Tag,Attribs,InnerXml),Output,VotesO):-!,computeElement(Ctx,Votes,Tag,Attribs,InnerXml,Output,VotesO).
  354computeAnswerMaybe(Ctx,Votes,InnerXml,Resp,VotesO):-isCallable(InnerXml),!,prolog_ecall(computeAnswerMaybeInnerLast(Ctx,Votes,Resp,VotesO),InnerXml).
  355computeAnswerMaybe(Ctx,Votes,InnerXml,Resp,VotesO):-computeAnswer(Ctx,Votes,InnerXml,Resp,VotesO).
  356computeAnswerMaybe(Ctx,Votes,InnerXml,Resp,VotesO):-debugFmt(computeAnswerMaybe(Ctx,Votes,InnerXml,Resp,VotesO)),fail.
  357
  358computeAnswerMaybeInnerLast(Ctx,Votes,Resp,VotesO,InnerXml):-computeAnswerMaybe(Ctx,Votes,InnerXml,Resp,VotesO).
  359
  360unused_computeElement(Ctx,Votes, Tag, ATTRIBS, [DO|IT], OUT, VotesO) :- recursiveTag(Tag),!,
  361      withAttributes(_Ctx,ATTRIBS,
  362        ((findall(Out,((member(In,[DO|IT]),computeTemplate(Ctx,Votes, In, Out, _VoteMid))),INNERDONE),
  363         NOUT=..[Tag,ATTRIBS,INNERDONE],!,
  364         computeAnswer(Ctx,Votes,NOUT,OUT,VotesO)))).
  365
  366% element inner reductions
  367still_computeElement(Ctx,Votes, Tag, ATTRIBS, [DO|IT], OUT, VotesO) :- recursiveTag(Tag),not(DO=(_-_)),!,
  368     appendAttributes(Ctx,ATTRIBS, [computeAnswer=[side_effects_allow=[transform],intag=Tag]], ATTRIBS_NEW),
  369     withAttributes(_Ctx,ATTRIBS_NEW,
  370       ((findall(OutVoteMid,((member(In,[DO|IT]),computeInner(Ctx,Votes, In, OutVoteMid))),INNERDONE),
  371        NOUT=..[Tag,ATTRIBS,INNERDONE]))),!,
  372         withAttributes(Ctx,ATTRIBS,computeInnerTemplate(Ctx,Votes,NOUT,OUT,VotesO)).
  373
  374:-discontiguous(computeElement/7).%%ah iot would be fine to move the OXY
  375
  376computeElement(_Ctx,Votes,Tag,ATTRIBS,InnerXml,Output,VotesO):- G=a(Votes,Tag,ATTRIBS,InnerXml),
  377   (prolog_must(ground(G)),not(var(Output);var(VotesO))),!,atrace,throw(G).
  378
  379% <justthat ...>
  380computeElement(Ctx,Votes,justthat,ATTRIBS,InnerXml,Output,VotesO):-!, computeElement(Ctx,Votes,input,[index=[2]|ATTRIBS],InnerXml,Output,VotesO).
  381computeElement(Ctx,Votes,justhat,ATTRIBS,InnerXml,Output,VotesO):-!, computeElement(Ctx,Votes,input,[index=[2]|ATTRIBS],InnerXml,Output,VotesO).
  382
  383% <beforethat ...>
  384computeElement(Ctx,Votes,beforethat,ATTRIBS,InnerXml,Output,VotesO):-!, computeElement(Ctx,Votes,input,[index=[3]|ATTRIBS],InnerXml,Output,VotesO).
  385
  386% <justbeforethat ...>
  387computeElement(Ctx,Votes,justbeforethat,ATTRIBS,InnerXml,Output,VotesO):-!, computeElement(Ctx,Votes,that,[index=[2,1]|ATTRIBS],InnerXml,Output,VotesO).
  388
  389% <html:br/>
  390computeElement(Ctx,Votes,Htmlbr,ATTRIBS,Input,Output,VotesO):- atom(Htmlbr),atom_concat_safe('html:',Br,Htmlbr),!,
  391   computeElementMust(Ctx,Votes,html:Br,ATTRIBS,Input,Output,VotesO).
  392computeElement(Ctx,Votes,html:Br,ATTRIBS,Input,Output,VotesO):- atom(Br),
  393   computeElementMust(Ctx,Votes,Br,ATTRIBS,Input,Output,VotesO).
  394
  395% <br/>
  396computeElement(_Ctx,Votes,br,[],[],'\n',Votes):-!.
  397% <p/>
  398computeElement(_Ctx,Votes,p,[],[],'\r\n',Votes):-!.
  399
  400% <sr/>
  401computeElement(Ctx,Votes,sr,ATTRIBS,Input,Output,VotesO):- !,
  402   computeElementMust(Ctx,Votes,srai,ATTRIBS,[element(star,ATTRIBS,Input)],Output,VotesO).
  403
  404computeElement(Ctx,Votes,Tag,ATTRIBS,Input,element(Tag,ATTRIBS,Output),VotesO):- isGenTemplate(Ctx,ATTRIBS),member(Tag,[srai,personf]),!,computeInnerTemplate(Ctx,Votes,Input,Output,VotesO).
  405
  406% <srai/>s
  407computeElement(_Ctx,Votes,srai,ATTRIBS,[],result([],srai=ATTRIBS),VotesO):-atrace,!,VotesO is Votes * 0.6.
  408
  409% <srai>s
  410computeElement(Ctx,Votes,srai,ATTRIBS,Input,Output,VotesO):- !, % for evalSRAI
  411  withAttributes(Ctx,ATTRIBS,((
  412    computeInnerTemplate(Ctx,Votes,Input,Middle,VotesM),!,
  413     prolog_must(computeSRAIElement(Ctx,VotesM,ATTRIBS,Middle,Output,VotesO))))),!.
  414
  415% genTemplate strippers
  416computeElement(Ctx,Votes,Tag,ATTRIBS,Input,Output,VotesO):-member(Tag,[li,template,pre]),isGenTemplate(Ctx,ATTRIBS),!,computeInnerTemplate(Ctx,Votes,Input,Output,VotesO).
  417
  418% <li...>
  419computeElement(Ctx,Votes,li,Preconds,InnerXml,OutProof,VotesO):- !, computeElement_li(Ctx,Votes,Preconds,InnerXml,OutProof,VotesO).
  420
  421% <li> PASSED
  422computeElement_li(Ctx,Votes,Preconds,InnerXml,OutProof,VotesO):-
  423     precondsTrue(Ctx,Preconds),!,computeInnerTemplate(Ctx,Votes,InnerXml,Output,VotesM),VotesO is VotesM * 1.1,!,
  424     prolog_must(OutProof = proof(Output,li(Preconds))).
  425
  426% <li> FAILED ==> []
  427computeElement_li(Ctx,Votes,Preconds,_InnerXml,OutProof,VotesO):-makeBlank(Ctx,Votes,failed(li(Preconds)),OutProof,VotesO),!.
  428
  429  precondsTrue(Ctx,PC):-lastMember(name=Name,PC,WO),lastMember(value=Value,WO,Rest),!,precondsTrue0(Ctx,[Name=Value|Rest]).
  430  precondsTrue(_Ctx,PC):-PC==[];var(PC),!.
  431  precondsTrue(Ctx,PC):-precondsTrue0(Ctx,PC).
  432
  433  precondsTrue0(_Ctx,PC):-PC==[];var(PC),!.
  434  precondsTrue0(Ctx,[NV|MORE]):-!,precondsTrue0(Ctx,MORE),!,precondsTrue0(Ctx,NV).
  435  precondsTrue0(Ctx,N=V):- peekNameValue(Ctx,user,N,Value,'$value'([])),!,(valuesMatch(Ctx,Value,V)->debugFmt(valuesMatch(Value,V));debugFmt(valuesMatch(not,Value,V))),valuesMatch(Ctx,Value,V).
  436  precondsTrue0(_Ctx,_NV):-atrace.
  437
  438%%%%%%%%%%%%%%%%%%%%%
  439% <random...>
  440%%%%%%%%%%%%%%%%%%%%%
  441computeElement(Ctx,Votes,random,Attribs,List,AA,VotesO):-isGenTemplate(Ctx,Attribs),!,member(Pick,List),computeAnswer(Ctx,Votes,Pick,AA,VotesO).
  442computeElement(Ctx,Votes,random,_Attribs,List,AA,VotesO):-!,randomPick(List,Pick),computeAnswer(Ctx,Votes,Pick,AA,VotesO).
  443
  444%%%%%%%%%%%%%%%%%%%%%
  445% <condition...>
  446%%%%%%%%%%%%%%%%%%%%%
  447computeElement(Ctx,Votes,condition,Attribs,List,AA,VotesO):-isGenTemplate(Ctx,Attribs),!,member(Pick,List),computeAnswer(Ctx,Votes,Pick,AA,VotesO).
  448computeElement(Ctx,Votes,condition,CondAttribs,InnerXml,Result,VotesO):-
  449     prolog_must(computeElement_condition(Ctx,Votes,CondAttribs,InnerXml,Result,VotesO)),!.
  450
  451% <condition name="foo" value="bar"> (acts like a <li name="foo" value="bar">)
  452computeElement_condition(Ctx,Votes,CondAttribs,InnerXml,Result,VotesO):-
  453   copy_term(CondAttribs,CondAttribsCopy),
  454     attributesContainOneOf0(CondAttribsCopy,[value=_]),attributesContainOneOf0(CondAttribsCopy,[var=_,name=_]),!,
  455      prolog_must(prolog_may(computeAnswerMaybe(Ctx,Votes,element(li,CondAttribs,InnerXml),Result,VotesO));makeBlank(Ctx,Votes,failed(CondAttribs),Result,VotesO)),!.
  456
  457% <condition name="foo"> <li value="bar"...>
  458computeElement_condition(Ctx,Votes,CondAttribs,InnerXml,Result,VotesO):-
  459   last(InnerXml,Last),
  460   copy_term(CondAttribs,CondAttribsCopy),
  461     not(attributesContainOneOf0(CondAttribsCopy,[value=_])),attributesContainOneOf0(CondAttribsCopy,[var=VarName,name=VarName]),!,
  462   lastKVMember(Ctx,[var,name],VarName,CondAttribs,_NEWCondAttribs),
  463   isValid(VarName),
  464   debugFmt(condition(varname=VarName,InnerXml)),
  465   withAttributes(Ctx, [name=VarName|CondAttribs],
  466      once((member(Pick,InnerXml),once((computeAnswerMaybe(Ctx,Votes,withAttributes(CondAttribs,Pick),Result,VotesO),isNonBlank(Result)))))
  467         ; (Result = Last,VotesO is Votes * 0.9)),!.
  468
  469% <condition><li..>
  470computeElement_condition(Ctx,Votes,CondAttribs,InnerXml,Result,VotesO):-
  471  last(InnerXml,Last),
  472   withAttributes(Ctx, CondAttribs,
  473     once(
  474      once((member(Pick,InnerXml),once((computeAnswerMaybe(Ctx,Votes,withAttributes(CondAttribs,Pick),Result,VotesO),isNonBlank(Result)))))
  475         ; (Result = Last, VotesO is Votes * 0.9))),!.
  476
  477makeBlank(_Ctx,Votes,Message,result([],Message),VotesO):- VotesO is Votes * 0.3 . %%%failed(CondAttribs)
  478
  479attributesContainOneOf(CondAttribs,AllOf):-copy_term(CondAttribs,CondAttribsCopy),attributesContainOneOf0(CondAttribsCopy,AllOf),!.
  480attributesContainOneOf0(CondAttribsCopy,AllOf):-member(Find,AllOf),member(Find,CondAttribsCopy),!.
  481isNonBlank(Result):-answerOutput(Result,Stuff),!,nonvar(Stuff),Stuff\==[].
  482
  483% <input/response/that index="1"...>
  484computeElement(Ctx,Votes,InputResponse,Attribs,InnerXml,Resp,VotesO):-member(InputResponse,[input,response,that]),!,
  485  lastMemberOrDefault(index=Index,Attribs,AttribsNew,['1']),
  486  prolog_must(computeMetaStar(Ctx,Votes,InputResponse,Index,AttribsNew,InnerXml,Resp,VotesO)).
  487
  488% <gossip...>
  489computeElement(Ctx,Votes,gossip,_Attribs,Input,Output,VotesO):-!,computeAnswer(Ctx,Votes,Input,Output,VotesO).
  490
  491% <think...>
  492computeElement(Ctx,Votes,think,Attribs,_Input,[],Votes):-isGenTemplate(Ctx,Attribs),!.
  493computeElement(Ctx,Votes,formatter,[type=[think]],_Input,[],Votes):-isGenTemplate(Ctx,[]),!.
  494computeElement(Ctx,Votes,think,_Attribs,Input,proof([],think=Hidden),VotesO):-!,computeInnerTemplate(Ctx,Votes,Input,Hidden,VotesO).
  495
  496% <formatter type="prologcall">
  497computeElement(Ctx,Votes,formatter,Attribs,Input,Result,VotesO):-
  498      computeInnerTemplate(Ctx,Votes,Input,Mid,VotesO),
  499      lastMember(type=ProcI,Attribs,_NEW),listify(ProcI,[Proc|More]),atom(Proc),atomic_list_concat_aiml(['format_',Proc|More],Pred),
  500      functor(Callable,Pred,3),predicate_property(Callable,_),!,
  501      computeCall(Ctx,Pred,Mid,Result,'$error'),Result\=='$error'.
  502
  503% <formatter type="sometag">
  504computeElement(Ctx,Votes,formatter,Attribs,Input,Result,VotesO):- !,
  505      computeInnerTemplate(Ctx,Votes,Input,Hidden,VotesO),
  506      lastMember(type=ProcI,Attribs,NEW),unlistify(ProcI,Proc),!,
  507      withAttributes(Ctx,NEW,computeElement(Ctx,Votes,Proc,NEW,Hidden,Result,VotesO)),!.
  508
  509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  510% <get,set,bot...>
  511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  512
  513computeElement(Ctx,Votes,GetSetBot,Attribs,InnerXml,Resp,VotesO):-member(GetSetBot,[get,set,bot]),!,computeGetSet(Ctx,Votes,GetSetBot,Attribs,InnerXml,Resp,VotesM),VotesO is VotesM * 1.1,!.
  514
  515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  516% for sure botvar-ish
  517% <version/id/date/size>
  518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  519computeElement(Ctx,Votes,BOT_ATOM,Attribs,InnerXml,element(BOT_ATOM,Attribs,InnerXml),Votes):- isGenTemplate(Ctx,Attribs), globalAliceTagVar(BOT_ATOM),!.
  520% HANDLE this in computeAnswer now convert_ele(Ctx,element(BOT_ATOM, ALIST, V),element(bot,[name=BOT_ATOM|ALIST],VV)):- globalAliceTagVar(BOT_ATOM),convert_template(Ctx,V,VV),!.
  521computeElement(Ctx,Votes,BOT_ATOM,[],[],proof(Resp,globalAliceTagVar(BOT_ATOM)),VotesO):- globalAliceTagVar(BOT_ATOM),!,expandVariable(Ctx,BOT_ATOM,Resp),VotesO is Votes  * 1.1.
  522
  523% <topicstar,star,thatstar...>
  524computeElement(Ctx,Votes,StarTag,Attribs,InnerXml,Resp,VotesO):- hotrace(starType(StarTag,StarName)),!, %%atrace,
  525      computeStar(Ctx,Votes,StarName,Attribs,InnerXml,Resp,VotesM),VotesO is VotesM * 1.1,!.
  526
  527
  528computeElement(Ctx,Votes,Tag,Attribs,Input,element(Tag,Attribs,Input),Votes):-  isGenTemplate(Ctx,Attribs),verbatumGenTemplate(Tag),!.
  529
  530verbatumGenTemplate(Tag):-member(Tag,[cycsystem,cyceval,cycquery,cycrandom,embed,img,script]).
  531verbatumGenTemplate(Tag):-member(Tag,[system,eval,load,learn]).
  532
  533
  534% <cycrandom...>
  535computeElement(Ctx,Votes,cycrandom,_Attribs,RAND,Output,VotesO):-!, computeAnswer(Ctx,Votes,cyceval(RAND),RO,VotesO),randomPick(RO,Output).
  536
  537% <system...>
  538computeElement(Ctx,Votes,Tag,Attribs,Input,result(RESULT,Tag=EVAL),VotesO):-
  539   member(Tag,[system]),
  540   checkNameValue(peekNameValue,Ctx,Attribs,[lang],Lang, '$value'('bot')),
  541   computeInnerTemplate(Ctx,Votes,Input,EVAL,VotesO),
  542   systemCall(Ctx,Lang,EVAL,RESULT).
  543
  544% <cyc..>
  545computeElement(Ctx,Votes,Tag,Attribs,Input,result(RESULT,Tag=EVAL),VotesO):-
  546   member(Tag,[cycsystem,cyceval,cycquery]),
  547   checkNameValue(peekNameValue,Ctx,Attribs,[lang],Lang,'$value'(Tag)),
  548   computeInnerTemplate(Ctx,Votes,Input,EVAL,VotesO),
  549   systemCall(Ctx,Lang,EVAL,RESULT).
  550
  551% <template, pre ...>
  552computeElement(Ctx,Votes,Tag,Attribs, DOIT, result(OUT,Tag=Attribs), VotesO) :- member(Tag,[template,pre]), isGenTemplate(Ctx,Attribs), !,
  553  computeTemplate(Ctx,Votes,DOIT,OUT,VotesO).
  554computeElement(Ctx,Votes,Tag,Attribs, DOIT, result(OUT,Tag=Attribs), VotesO) :- member(Tag,[template,pre]), !,
  555  computeTemplate(Ctx,Votes,DOIT,OUT,VotesO).
  556
  557% <uppercase, lowercase ...>
  558computeElement(Ctx,Votes,Tag,Attribs, Input, Output, VotesO) :- formatterProc(Tag),
  559   formatterTypeMethod(Tag,Type,Method),!,
  560   computeInnerTemplate(Ctx,Votes,Input,Mid,VotesO),
  561   computeCall(Ctx,Method,Mid,Output,prologCall(Method, result(Mid,element(Tag,[type=Type|Attribs])))),!.
  562
  563% .... computeCall to formatter ....
  564computeCall(Ctx,Method,Mid,Output,ElseResult):-
  565   error_catch(prolog_must(call(Method,Ctx,Mid,Output)),
  566     E, (debugFmt(error(E,call(Method,Mid,Output))), atrace, Output = ElseResult)).
  567computeCall(_Ctx,_Pred,_Mid,Result,ElseResult):-prolog_must(Result=ElseResult).
  568
  569% .... formatters ....
  570format_formal(_Ctx,In,Out):-toPropercase(In,Out),!.
  571format_sentence(_Ctx,[In1|In],[Out1|Out]):-In=Out,toPropercase(In1,Out1),!.
  572format_sentence(_Ctx,In,Out):-In=Out.
  573format_think(_Ctx,_In,Out):-[]=Out.
  574format_gossip(_Ctx,In,Out):-In=Out.
  575format_uppercase(_Ctx,In,Out):-toUppercase(In,Out),!.
  576format_lowercase(_Ctx,In,Out):-toLowercase(In,Out),!.
  577
  578
  579% <gender..>
  580computeElement(Ctx,Votes,Gender,Attribs,Input,Result,VotesO):- substitutionDictsName(Gender,DictName),!,
  581   computeElement_subst(Ctx,Votes,Gender,DictName,Attribs,Input,Result,VotesO).
  582
  583% <gender|person2/>
  584computeElement_subst(Ctx,Votes,_Gender,DictName,Attribs,[],Result,VotesO):-
  585    computeElementMust(Ctx,Votes,star,Attribs,[],Hidden,VotesO),
  586    substituteFromDict(Ctx,DictName,Hidden,Result),!.
  587
  588computeElement_subst(Ctx,Votes,_Gender,DictName,Attribs,Input,Result,VotesO):-
  589      withAttributes(Ctx,Attribs,((computeInnerTemplate(Ctx,Votes,Input,Hidden,VotesO),
  590      substituteFromDict(Ctx,DictName,Hidden,Result)))),!.
  591
  592% <load...>
  593computeElement(Ctx,Votes,Tag,ATTRIBS,Input,result(RESULT,Tag=EVAL),VotesO):-
  594   member(Tag,[load]),!,
  595   computeInnerTemplate(Ctx,Votes,Input,EVAL,VotesO),
  596   tag_eval(Ctx,element(Tag,ATTRIBS,EVAL),RESULT).
  597
  598% <learn...>
  599computeElement(Ctx,Votes,Tag,ATTRIBS, NEWXML, result([learned,Diff,new,patterns]),Votes) :-
  600  member(Tag,[learn]),!,
  601       NEW = element(aiml,ATTRIBS,NEWXML),
  602       aimlCateSig(CateSig),
  603       predicate_property(CateSig,number_of_clauses(Before)),
  604        withAttributes(Ctx,ATTRIBS, load_aiml_structure(Ctx,NEW)),!,
  605           predicate_property(CateSig,number_of_clauses(After)),
  606           Diff is After - Before.
  607
  608% <aiml/topic/category...>
  609computeElement(Ctx,Votes,Tag,ATTRIBS, NEWXML, result([learned,Tag,Diff,new,patterns]),Votes) :- member(Tag,[aiml,topic,category]),!,
  610       NEW = element(Tag,ATTRIBS,NEWXML),
  611       aimlCateSig(CateSig),
  612       predicate_property(CateSig,number_of_clauses(Before)),
  613        withAttributes(Ctx,ATTRIBS, load_aiml_structure(Ctx,NEW)),!,
  614           predicate_property(CateSig,number_of_clauses(After)),
  615           Diff is After - Before.
  616
  617% <eval...>
  618computeElement(Ctx,Votes,Tag,ATTRIBS, DOIT, RESULT, Votes) :- member(Tag,[eval]),!,
  619      withAttributes(Ctx,ATTRIBS,aiml_eval(Ctx,DOIT,RESULT)),!.
  620
  621% other evals
  622computeElement(Ctx,Votes,Tag,ATTRIBS,Input,RESULT,VotesO):- evaluatorTag(Tag),
  623   computeInnerTemplate(Ctx,Votes,Input,EVAL,VotesO),!,
  624   tag_eval(Ctx,element(Tag,ATTRIBS,EVAL),RESULT),!.
  625
  626% maybe not for sure botvar-ish
  627% <favfood/master>
  628% HANDLE this in computeAnswer now convert_ele(Ctx,element(BOT_ATOM, ALIST, V),element(bot,[name=BOT_ATOM|ALIST],VV)):- globalAliceTagVar(BOT_ATOM),convert_template(Ctx,V,VV),!.
  629computeElement(Ctx,Votes,BOT_ATOM,[],[],proof(Resp,globalAliceTagVar(BOT_ATOM)),VotesO):- expandVariable(Ctx,BOT_ATOM,Resp),!, VotesO is Votes  * 1.1.
  630
  631% rewrites
  632computeElement(_Ctx,Votes,Tag,[],[],result([reply,from,tag,Tag],element(Tag,[],[])),Votes):-!.
  633computeElement(_Ctx,Votes,Tag,Attribs,[],result([reply,from,Tag|Attribs],Tag,Attribs),Votes):-!,atrace.
  634computeElement(Ctx,Votes,Tag,Attribs,InnerXml,Resp,VotesO):-
  635  GETATTRIBS = element(Tag,Attribs,InnerXml),
  636  convert_element(Ctx,GETATTRIBS,GETATTRIBS0),
  637  GETATTRIBS \== GETATTRIBS0,!,
  638  %%atrace,
  639  convert_element(Ctx,GETATTRIBS,_GETATTRIBS1),
  640  computeAnswer(Ctx,Votes,GETATTRIBS0, Resp,VotesO).
  641
  642
  643% ===============================================================================================
  644% Compute Star
  645% ===============================================================================================
  646
  647starName(get_star,star):-!.
  648starName(StarStar,StarStar):- atom_concat(_,'star',StarStar),!.
  649starName(Star,StarStar):- atom_concat(Star,'star',StarStar),!.
  650
  651starElementName(starstar,star).
  652starElementName(pattern,star).
  653starElementName(get_star,star).
  654starElementName(star,star).
  655starElementName(patternstar,star).
  656starElementName(StarStar,StarStar):- atom_concat(_Star,'star',StarStar),!.
  657starElementName(Star,StarStar):- atom_concat(Star,'star',StarStar),!.
  658
  659:-dynamic(inGenOutput/0).
  660isGenerateUnknown(_Ctx,_ATTRIBS):-!,inGenOutput,!.
  661isGenerateUnknown(Ctx,ATTRIBS):- peekNameValue(Ctx,ATTRIBS,generateUnknownVars,GenerateUnknown,'false'),!,GenerateUnknown=true.
  662isGenTemplate(_Ctx,_ATTRIBS):-!,inGenOutput,!.
  663isGenTemplate(Ctx,Attribs):-peekNameValue(Ctx,Attribs,generateTemplate,GenTempl,'$failure'),GenTempl=true.
  664
  665computeStar(Ctx,Votes,Star,Attribs,InnerXml,Resp,VotesO):-
  666   isGenTemplate(Ctx,Attribs),!,VotesO=Votes,
  667   starElementName(Star,EName),Resp=element(EName,Attribs,InnerXml),!.
  668
  669computeStar(Ctx,Votes,Star,Attribs,InnerXml,Resp,VotesO):-
  670   starName(Star,StarStar),Star \== StarStar,!,
  671   computeStar(Ctx,Votes,StarStar,Attribs,InnerXml,Resp,VotesO),!.
  672
  673computeStar(Ctx,Votes,Star,Attribs,InnerXml,Resp,VotesO):-
  674    lastMember(index=Index,Attribs,AttribsNew),!,
  675    computeStar1(Ctx,Votes,Star,Index,AttribsNew,InnerXml,Resp,VotesO),!.
  676
  677computeStar(Ctx,Votes,Star,Attribs,InnerXml,Resp,VotesO):-
  678    computeStar1(Ctx,Votes,Star,[1],Attribs,InnerXml,Resp,VotesO),!.
  679
  680computeStar1(Ctx,Votes,Star,Major,ATTRIBS,InnerXml,Proof,VotesO):-atomic(Major),!,
  681    computeStar1(Ctx,Votes,Star,[Major],ATTRIBS,InnerXml,Proof,VotesO),!.
  682
  683computeStar1(Ctx,Votes,Star,Index,ATTRIBS,_InnerXml,proof(ValueO,StarVar=ValueI),VotesO):- is_list(Index),
  684      CALL=atomic_list_concat_aiml([Star|Index],StarVar),
  685      prolog_must(error_catch(CALL,E,(debugFmt(CALL->E),fail))),
  686   getDictFromAttributes(Ctx,'evalsrai',ATTRIBS,Dict),
  687   computeStar2(Ctx,Votes,Dict,ATTRIBS,StarVar,ValueI,ValueO,VotesM),!,
  688   VotesO is VotesM * 1.1.
  689
  690computeStar1(_Ctx,Votes,Star,Index,ATTRIBS,InnerXml,Resp,VotesO):-
  691      traceIf(Resp = result(InnerXml,Star,Index,ATTRIBS)),!,VotesO is Votes * 1.1.
  692
  693computeStar2(Ctx,Votes,Dict,ATTRIBS,StarVar,ValueI,ValueO,VotesM):-
  694   getStoredStarValue(Ctx,Dict,StarVar,ValueI),
  695   %%ValueO=ValueI,VotesM=Votes,
  696   computeTemplate(Ctx,Votes,element(template,ATTRIBS,ValueI),ValueO,VotesM),
  697   !.
  698
  699getStoredStarValue(Ctx,_Dict,StarVar,ValueI):-current_value(Ctx,StarVar,ValueI),!.
  700getStoredStarValue(Ctx,Dict,StarVar,ValueI):-getStoredValue(Ctx,Dict,StarVar,ValueI),!.
  701getStoredStarValue(_Ctx,Dict,StarVar,[starvar,StarVar,Dict]):-!,unify_listing(dict(Dict,_,_)),atrace.
  702
  703
  704computeMetaStar(Ctx,Votes,Star,Index,ATTRIBS,InnerXml,Resp,VotesO):-computeMetaStar0(Ctx,Votes,Star,Index,ATTRIBS,InnerXml,Resp,VotesO),!.
  705
  706computeMetaStar0(Ctx,Votes,Star,MajorMinor,ATTRIBS,InnerXml,Resp,VotesO):-isGenTemplate(Ctx,ATTRIBS),!,VotesO=Votes,Resp=element(Star,[index=MajorMinor|ATTRIBS],InnerXml).
  707
  708computeMetaStar0(Ctx,Votes,Star,MajorMinor,ATTRIBS,_InnerXml,proof(ValueO,Star=ValueI),VotesO):-
  709      getDictFromAttributes(Ctx,'evalsrai',ATTRIBS,Dict),
  710      getIndexedValue(Ctx,Dict,Star,MajorMinor,ValueI),!,
  711      computeInnerTemplate(Ctx,Votes,element(template,ATTRIBS,[ValueI]),ValueO,VotesM),VotesO is VotesM * 1.1.
  712
  713computeMetaStar0(_Ctx,Votes,Star,Index,ATTRIBS,InnerXml,Resp,VotesO):- atrace,
  714      traceIf(Resp = result(InnerXml,Star,Index,ATTRIBS)),!,VotesO is Votes * 0.9.
  715
  716%%%%%%  peekNameValue(Ctx,Scope,Name,Value,else). %%
  717getDictFromAttributes(Ctx,VarHolder,_ATTRIBS,SYM):-current_value(Ctx,VarHolder,SYM).
  718getDictFromAttributes(_Ctx,_VarHolder,_ATTRIBS,'user'):-!. %%atrace.
  719
  720% ===============================================================================================
  721% Compute Get/Set Probilities
  722% ===============================================================================================
  723/*
  724
  725computeGetSet(Ctx,Votes,GetSetBot,ATTRIBS,[],Resp,VotesO):- !,computeGetSet(Ctx,Votes,GetSetBot,user,ATTRIBS,Resp,VotesO).
  726computeGetSet(Ctx,Votes,GetSetBot,name=NAME,MORE,Resp,VotesO):- !, computeGetSet(Ctx,Votes,GetSetBot,user,[name=NAME|MORE],Resp,VotesO).
  727computeGetSet(Ctx,Votes,GetSetBot,WHO,[X],Resp,VotesO):- !,computeGetSet(Ctx,Votes,GetSetBot,WHO,X,Resp,VotesO).
  728computeGetSet(Ctx,Votes,GetSetBot,ATTRIBS,Value,Resp,VotesO):- delete(ATTRIBS,type=bot,NEW),!,computeGetSet(Ctx,Votes,bot=GetSetBot,NEW,Value,Resp,VotesO).
  729computeGetSet(Ctx,Votes,GetSetBot,TYPE,[],Resp,VotesO):- !,computeGetSet(Ctx,Votes,GetSetBot,user,TYPE,Resp,VotesO).
  730
  731*/

  732
  733computeGetSet(Ctx,Votes,bot,ATTRIBS,InnerXml,Resp,VotesO):- !, computeGetSetVar(Ctx,Votes,bot,get,_VarName,ATTRIBS,InnerXml,Resp,VotesO),!.
  734
  735computeGetSet(Ctx,Votes,GetSet,ATTRIBS,InnerXml,Resp,VotesO):- computeGetSetVar(Ctx,Votes,user,GetSet,_VarName,ATTRIBS,InnerXml,Resp,VotesO),!.
  736
  737dictVarName(N):-member(N,[dictionary,dict,userdict,type,user,botname,username,you,me]).
  738% tests the dictionary contains at least one value
  739dictFromAttribs(Ctx,ATTRIBS,Dict,NEW):-dictVarName(N),lastMember(N=DictV,ATTRIBS,NEW),convert_dictname(Ctx,DictV,Dict),getContextStoredValue(Ctx,Dict,_Name,Value),valuePresent(Value),!.
  740dictFromAttribs(Ctx,ATTRIBS,Dict,NEW):-dictVarName(N),lastMember(N=DictV,ATTRIBS,NEW),atrace,convert_dictname(Ctx,DictV,Dict),!,atrace.
  741
  742lastKVMember(_Ctx,Keys,Value,ATTRIBS,NEW):-member(N,Keys),lastMember(N=Value,ATTRIBS,NEW),prolog_must(isValid(Value)),!.
  743lastKVMember(Ctx,Keys,Value,ATTRIBS,ATTRIBS):-member(N,Keys),current_value(Ctx,N,Value),prolog_must(isValid(Value)),!.
  744lastKVMember(Ctx,Keys,Value,ATTRIBS,ATTRIBS):-member(N,Keys),peekNameValue(Ctx,ATTRIBS,N,Value,'$failure'),prolog_must(isValid(Value)),!.
  745
  746%%computeGetSetVar(Ctx,Votes,_Dict,bot,VarName,ATTRIBS,InnerXml,Resp,VotesO):- !,computeGetSetVar(Ctx,Votes,user,get,VarName,ATTRIBS,InnerXml,Resp,VotesO).
  747%% computeGetSetVar(Ctx,Votes,Dict,GetSetBot,VarName,ATTRIBS,InnerXml,Resp,VotesO).
  748
  749
  750computeGetSetVar(Ctx,Votes,Dict,GetSet,OVarName,ATTRIBS,InnerXml,Resp,VotesO):- atom(ATTRIBS),ATTRIBS \= [],!, VarName = ATTRIBS,
  751   nop(debugFmt(computeGetSetVarName(GetSet,Dict:OVarName->VarName))),
  752     computeGetSetVar(Ctx,Votes,Dict,GetSet,VarName,[],InnerXml,Resp,VotesO),!.
  753
  754computeGetSetVar(Ctx,Votes,Dict,GetSet,OVarName,ATTRIBS,InnerXml,Resp,VotesO):-
  755      member(N,[var,name]),lastMember(N=VarName,ATTRIBS,NEW),!,
  756   nop(debugFmt(computeGetSetVarDict(GetSet,Dict:OVarName->VarName))),
  757      computeGetSetVar(Ctx,Votes,Dict,GetSet,VarName,NEW,InnerXml,Resp,VotesO).
  758
  759computeGetSetVar(Ctx,Votes,OldDict,GetSet,VarName,ATTRIBS,InnerXml,Resp,VotesO):-
  760     dictFromAttribs(Ctx,ATTRIBS,Dict,NEW),
  761   nop(debugFmt(computeGetSetVarDict2(GetSet,OldDict->Dict,VarName))),
  763      computeGetSetVar(Ctx,Votes,Dict,GetSet,VarName,NEW,InnerXml,Resp,VotesO)
  763.
  764
  765computeGetSetVar(Ctx,Votes,_Dict,'set',OVarName,Attribs,_InnerXml,OVarName,Votes):-isGenTemplate(Ctx,Attribs),getStoredValue(Ctx,setReturn(_Default),OVarName,NameOrValue),NameOrValue=name,!.
  766computeGetSetVar(Ctx,Votes,_Dict,'set',_OVarName,Attribs,InnerXml,Resp,VotesO):-isGenTemplate(Ctx,Attribs),!,computeTemplate(Ctx,Votes,InnerXml,Resp,VotesO).
  767computeGetSetVar(Ctx,Votes,Dict,GetSetBot,OVarName,Attribs,InnerXml,Resp,VotesO):-isGenTemplate(Ctx,Attribs),!,VotesO=Votes,Resp=element(GetSetBot,[dict=Dict,ovar=OVarName|Attribs],InnerXml).
  768
  769computeGetSetVar(Ctx,Votes,Dict,get,VarName,ATTRIBS,_InnerXml,proof(ValueO,VarName=ValueI),VotesO):-
  770      getAliceMemComplete(Ctx,Dict,VarName,ValueI),!,
  771      computeAnswer(Ctx,Votes,element(template,ATTRIBS,ValueI),ValueO,VotesM),VotesO is VotesM * 1.1.
  772
  773% GET no value found
  774computeGetSetVar(Ctx,Votes,Dict,get,VarName,ATTRIBS,_InnerXml,proof(ReturnValueO,Dict:VarName='OM',ATTRIBS),VotesO):-!,VotesO is Votes * 0.7,
  775     once(isGenerateUnknown(Ctx,ATTRIBS) -> DefaultEmpty=[unKnowN,VarName,of,Dict];DefaultEmpty=[]),
  776     lastMemberOrDefault('default'=DefaultValue,ATTRIBS,_AttribsNew,DefaultEmpty),
  777     returnNameOrValue(Ctx,Dict,VarName,DefaultValue,ReturnValueO),!.
  778
  779computeGetSetVar(Ctx,Votes,Dict,set,VarName,ATTRIBS,InnerXml,proof(ReturnValue,VarName=InnerXml),VotesO):-!,
  780      computeAnswer(Ctx,Votes,element(template,ATTRIBS,InnerXml),ValueM,VotesM),
  781      computeInnerTemplate(Ctx,VotesM,ValueM,ValueO,VotesMO),
  782      ensureValue(ValueO,ValueOO),
  783      setAliceMem(Ctx,Dict,VarName,ValueOO),!,
  784      returnNameOrValue(Ctx,Dict,VarName,ValueO,ReturnValue),
  785      VotesO is VotesMO * 1.1.
  786
  787%%computeGetSetVar(_Ctx,_Votes,_Get,_,_,_,_):-!,fail.
  788
  789returnNameOrValue(Ctx,IDict,VarNameI,Value,ReturnValue):-dictNameDictNameC(Ctx,IDict,VarNameI,Scope,Name),!,returnNameOrValue(Ctx,Scope,Name,Value,ReturnValue).
  790returnNameOrValue(Ctx,_Dict,VarName,ValueO,ReturnValueO):-
  791      once(getStoredValue(Ctx,setReturn(_Default),VarName,NameOrValue);NameOrValue=value),
  792      returnNameOrValue0(NameOrValue,VarName,ValueO,ReturnValue),!,listify(ReturnValue,ReturnValueO).
  793
  794returnNameOrValue0([NameOrValue],VarName,ValueO,ReturnValue):-!,returnNameOrValue0(NameOrValue,VarName,ValueO,ReturnValue),!.
  795returnNameOrValue0(name,VarName,_ValueO,VarName).
  796returnNameOrValue0(_Value,_VarName,ValueO,ValueO).
  797
  798
  799% ===============================================================================================
  800% Compute Answer Probilities
  801% ===============================================================================================
  802computeAnswer(Ctx,Votes,IN,Result,VotesOut):-computeAnswerND(Ctx,Votes,IN,Result,VotesOut),!.
  803
  804:-discontiguous(computeAnswerND/5).
  805
  806computeAnswerND(Ctx,Votes,IN,Result,VotesOut):- not(tracing),computeAnswer0(Ctx,Votes,IN,Result,VotesOut),fail.
  807
  808computeAnswer0(Ctx,Votes,IN,Result,VotesOut):- prolog_must((number(Votes),nonvar(IN),var(Result),var(VotesOut))),
  809      nop(debugFmt(computeAnswer(Ctx,Votes,IN,Result,VotesOut))),fail.
  810
  811computeAnswer0(Ctx,Votes,MidVote - In,Out,VotesO):- prolog_must(nonvar(MidVote)),
  812                           atrace, !, computeAnswer(Ctx,Votes,In,Out,VotesA), VotesO is VotesA * MidVote.
  813
  814computeAnswer0(_Ctx,Votes,_I,_,_):-(Votes>20;Votes<0.3),!,fail.
  815
  816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  817% elements
  818%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  819
  820% element inner reductions
  821computeAnswer_1_disabled(Ctx,Votes, element(Tag, ATTRIBS, [DO|IT]), OUT, VotesO) :- recursiveTag(Tag),not(DO=(_-_)),!,
  822     appendAttributes(Ctx,ATTRIBS, [computeAnswer=[side_effects_allow=[transform],intag=Tag]], ATTRIBS_NEW),
  823       withAttributes(_Ctx,ATTRIBS_NEW, findall(Each,((member(In,[DO|IT]),computeInner(Ctx,Votes, In, Each))),INNERDONE)),
  824       computeElementMust(Ctx,Votes,Tag, ATTRIBS, INNERDONE, OUT, VotesO).
  825
  826computeAnswerND(Ctx,Votes, element(Tag, ATTRIBS, [DO|IT]), OUT, VotesO) :- recursiveTag(Tag),not(DO=(_-_)),!,
  827     appendAttributes(Ctx,ATTRIBS, [computeAnswer=[side_effects_allow=[transform],intag=Tag]], ATTRIBS_NEW),
  828         withAttributes(Ctx,ATTRIBS_NEW, computeInput(Ctx, Votes,[DO|IT],INNERDONE)),
  829       prolog_mostly_ground((INNERDONE)),
  830       computeElementMust(Ctx,Votes,Tag, ATTRIBS, INNERDONE, OUT, VotesO).
  831
  832computeAnswerND(Ctx,Votes,element(Tag,Attribs,List),Out,VotesO):-!,computeElement(Ctx,Votes,Tag,Attribs,List,Out,VotesO).
  833
  834% never gets here due to element/3 cutted above
  835computeAnswerND(Ctx,Votes,element(Tag,Attribs,List),Output,VotesO):- computeElement(Ctx,Votes,Tag,Attribs,List,Output,VotesO),!.
  836computeAnswerND(Ctx,Votes,element(Tag,Attribs,List),Output,VotesO):-atrace,computeElement(Ctx,Votes,Tag,Attribs,List,Output,VotesO),!.
  837
  838
  839%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  840% strings (must happen before list-check)
  841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  842computeAnswerND(Ctx,Votes,String,Out,VotesO):-string(String),string_to_atom(String,Atom),!,computeAnswer(Ctx,Votes,Atom,Out,VotesO).
  843computeAnswerND(_Ctx,Votes,String,Atom,Votes):-is_string(String),toCodes(String,Codes),!,from_atom_codes(Atom,Codes),!.
  844computeAnswerND(_Ctx,Votes,'$stringCodes'(List),AA,Votes):-!,from_atom_codes(AA,List),!.
  845
  846%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  847% list-check
  848%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  849% (should be no stars)
  850computeAnswerND(_Ctx,_Votes,Pattern,_,_):- traceIf(isStarValue(Pattern)),fail.
  851
  852computeAnswerND(_Ctx,Votes,[],[],Votes):-!.
  853computeAnswerND(Ctx,Votes,[A|B],OO,VotesO):-
  854    atomic(A) ->
  855      (!,computeTemplate(Ctx,Votes,B,BB,VotesO),OO=[A|BB]) ;
  856      computeTemplate(Ctx,Votes,[A|B],OO,VotesO).
  857
  858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  859% atomic
  860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  861computeAnswerND(Ctx,Votes,randomsentence,Output,VotesO):-!, choose_randomsentence(X),!,computeAnswer(Ctx,Votes,X,Output,VotesO).
  862
  863computeAnswerND(Ctx,Votes,In,Out,Votes):-atomic(In),expandVar(Ctx,In,Out).
  864computeAnswerND(_Ctx,Votes,Resp,Resp,Votes):-atomic(Resp),!.
  865
  866%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  867% prologCall
  868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  869computeAnswerND(Ctx,Votes,prologCall(Method,Stuff),Resp,VotesO):-
  870  computeAnswer(Ctx,Votes,Stuff,Mid,VotesO),
  871  call(Method,Ctx,Mid,Resp),!.
  872
  873computeAnswerND(_Ctx,Votes,prologCall(Method),Resp,VotesO):- atrace,
  874   once(call(Method)->(Resp=pass(Method),VotesO=Votes);(Resp=failed(Method),VotesO is Votes*0.5)),!.
  875
  876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  877% Star Compounds
  878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  879computeAnswerND(Ctx,Votes,star(Star,Attribs,InnerXml),Output,VotesO):- computeStar(Ctx,Votes,Star,Attribs,InnerXml,Output,VotesO),!.
  880
  881%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  882% withAttributes Compounds
  883%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  884
  885computeAnswerND(Ctx,Votes,Input,Output,VotesO):- functor(Input,withAttributes,_),
  886  Input = withAttributes(OuterAttribs,element(Tag,Attribs,InnerXml)),
  887  append(Attribs,OuterAttribs,AllAttribs),
  888  withAttributes(Ctx,OuterAttribs,once(computeAnswer(Ctx,Votes,element(Tag,AllAttribs,InnerXml),Output,VotesO);Failed=failed)),!,Failed \== failed.
  889
  890computeAnswerND(Ctx,Votes,withAttributes(OuterAttribs,InnerXml),Output,VotesO):-
  891  withAttributes(Ctx,OuterAttribs,once(computeAnswer(Ctx,Votes,InnerXml,Output,VotesO);Failed=failed)),!,Failed \== failed.
  892
  893computeAnswerND(Ctx,Votes,compute(InnerXml),Output,VotesO):-!, computeAnswer(Ctx,Votes,InnerXml,Output,VotesO).
  894
  895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  896% Result or Proof already
  897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  898
  899computeAnswerND(_Ctx,Votes,Res, Res,Votes):-resultOrProof(Res,_Mid),!.
  900
  901%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  902% Other Compounds
  903%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  904
  905computeAnswerND(Ctx,Votes,GETATTRIBS, Resp,VotesO):-
  906  convert_element(Ctx,GETATTRIBS,GETATTRIBS0),
  907  GETATTRIBS \== GETATTRIBS0,!,
  908  atrace,
  909  convert_element(Ctx,GETATTRIBS,_GETATTRIBS1),
  910  computeAnswer(Ctx,Votes,GETATTRIBS0, Resp,VotesO).
  911
  912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  913% errors
  914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
  915
  916computeAnswerND(Ctx,Votes,GETATTRIBS, Resp,VotesO):- GETATTRIBS=..[GET], isAimlTag(GET), !, computeElementMust(Ctx,Votes,GET,[],[],Resp,VotesO).
  917computeAnswerND(Ctx,Votes,GETATTRIBS, Resp,VotesO):- GETATTRIBS=..[GET,ATTRIBS], isAimlTag(GET), !, computeElementMust(Ctx,Votes,GET,ATTRIBS,[],Resp,VotesO).
  918computeAnswerND(Ctx,Votes,GETATTRIBS, Resp,VotesO):- GETATTRIBS=..[GET,ATTRIBS,INNER], isAimlTag(GET), !, computeElementMust(Ctx,Votes,GET,ATTRIBS,INNER,Resp,VotesO).
  919
  920computeAnswerND(_Ctx,Votes,Resp,Resp,Votes):-atrace,aiml_error(computeAnswer(Resp)).
  921
  922% ===============================================================================================
  923% Run answer procs
  924% ===============================================================================================
  925
  926choose_randomsentence(X):-
  927	repeat,
  928		retract(random_sent(Y)),
  929		assertz(random_sent(Y)),
  930		4 is random(10),!,
  931		Y=X.
  932
  933% ===============================================================================================
  934% Get and rember Last Said
  935% ===============================================================================================
  936%% using dict now :-dynamic(getLastSaid/1).
  937%%:-setAliceMem(_,_,that,(['where',am,'I'])).
  938
  939rememberSaidIt(_Ctx,[]):-!.
  940rememberSaidIt(Ctx,_-R1):-!,rememberSaidIt(Ctx,R1).
  941rememberSaidIt(Ctx,R1):-append(New,'.',R1),!,rememberSaidIt(Ctx,New).
  942rememberSaidIt(Ctx,R1):-answerOutput(R1,SR1),R1\==SR1,!,rememberSaidIt(Ctx,SR1).
  943rememberSaidIt(Ctx,R1):- !,
  944   getAliceMem(Ctx,'bot','you',User),
  945   getAliceMem(Ctx,'bot','me',Robot),
  946   rememberSaidIt_SH(Ctx,R1,Robot,User).
  947
  948rememberSaidIt_SH(_Ctx,[],_Robot,_User):-!.
  949rememberSaidIt_SH(Ctx,_-R1,Robot,User):-!,rememberSaidIt_SH(Ctx,R1,Robot,User).
  950rememberSaidIt_SH(Ctx,R1,Robot,User):-append(New,[Punct],R1),sentenceEnderOrPunct_NoQuestion(Punct),!,rememberSaidIt_SH(Ctx,New,Robot,User).
  951rememberSaidIt_SH(Ctx,R1,Robot,User):-answerOutput(R1,SR1),!,
  952   setAliceMem(Ctx,Robot,'lastSaid',SR1),
  953   pushInto1DAnd2DArray(Ctx,'response','that',5,SR1,User).
  954
  955getRobot(Robot):-atrace,getAliceMem(_Ctx,'bot','me',Robot),!.
  956
  957getLastSaid(LastSaid):-getRobot(Robot),getAliceMem(_Ctx,Robot,'lastSaid',LastSaid).
  958
  959getLastSaidAsInput(LastSaidMatchable):-getLastSaid(That),convertToMatchable(That,LastSaidMatchable),!.
  960
  961% set some sane defaults to be overiden in config.xmls
  962:-prolog_must(setAliceMem('bot','me','bot')).
  963:-setAliceMem('bot','you','user').
  964:-setAliceMem('bot','name',['The','Robot']).
  965:-setAliceMem('bot',version,'1.0.1').
  966:-setAliceMem('user','name',['Unknown','Partner']).
  967:-setAliceMem('user','me','user').
  968:-setAliceMem('user','is_type','agent').
  969:-setAliceMem('bot','is_type','agent').
  970:-setAliceMem('default','is_type','role').
  971:-setAliceMem('bot','infinite-loop-input',['INFINITE','LOOP']).
  972%%:-setAliceMem(substitutions(_DictName),'is_type','substitutions').
  973
  974
  975% ===============================================================================================
  976% Template Output to text
  977% ===============================================================================================
  980computeTemplateOutput(Ctx,Votes,Input,Output,VotesO):-prolog_must(computeTemplate(Ctx,Votes,Input,Output,VotesO)).
  983computeInnerTemplate(Ctx,Votes,Input,Output,VotesO):-
  984    prolog_mustEach((computeTemplateOutput(Ctx,Votes,Input,Mid,VotesO),answerOutput(Mid,Output))).
  985
  986answerOutput(Output,NonVar):-nonvar(NonVar),answerOutput(Output,Var),!,valuesMatch(_Ctx,Var,NonVar).
  987answerOutput(Output,[Output]):-var(Output),!.
  988answerOutput([],Output):- !, Output=[].
  989%answerOutput(Output,Split):-atom(Output),atomWSplit(Output,Split),Split==[Output],!.
  990%answerOutput(Output,Split):-atom(Output),atrace,atomWSplit(Output,Split),!.
  991answerOutput('<br/>',['\n']):-!.
  992answerOutput('<p/>',['\r\n']):-!.
  993answerOutput(element('br',[],[]),['\n']):-!.
  994answerOutput(Output,[Output]):-atomic(Output),!.
  995answerOutput([<,BR,/,>|B],OO):-atom(BR),!,
  996  answerOutput([element(BR,[],[])|B],OO),!.
  997answerOutput([A|AA],Output):-!,
  998   answerOutput(A,B),
  999   answerOutput(AA,BB),
 1000   flatten([B,BB],Output).
 1001
 1002answerOutput(element(template,[],InnerXML),Output):- answerOutput(InnerXML,Output),!.
 1003
 1004answerOutput(element(Tag,Attribs,InnerXML),[element(Tag,Attribs,Output)]):- answerOutput(InnerXML,Output),!.
 1005answerOutput(star(Tag,Attribs,InnerXML),[star(Tag,Attribs,Output)]):- answerOutput(InnerXML,Output),!.
 1006answerOutput(Term,Output):-resultOrProof(Term,Mid),!,answerOutput(Mid,Output).
 1007answerOutput(Term,Output):-compound(Term),Term=..[_,Mid|_],debugFmt(answerOutput(Term->Mid)),!,answerOutput(Mid,Output).
 1008answerOutput(Output,[Output]):-!.
 1009
 1010lastMemberOrDefault(E,L,N,_D):-lastMember(E,L,N),!.
 1011lastMemberOrDefault(_Named=E,L,N,D):-L=N,E=D,!.
 1012lastMemberOrDefault(E,L,N,D):-L=N,E=D.
 1013
 1014
 1015% ===================================================================
 1016% Substitution based on Pred like sameWordsDict(String,Pattern).
 1017% ===================================================================
 1018
 1019convert_substs(A,D):-simplify_atom0(A,M),A\==M,!,convert_substs(M,D).
 1020convert_substs(A,D):-A=D.
 1021
 1022simplify_atom0(A,A):-A==[],!.
 1023simplify_atom0(A0,DD):- is_list(A0),joinAtoms(A0,' ',A),!,simplify_atom0(A,D),!,atomWSplit(D,DD),!.
 1024simplify_atom0(A,D):- atom(A),!,literal_atom(A,B),atomic_list_concat_aiml(L0,'\\b',B),delete(L0,'',L),joinAtoms(L,' ',C),!,atomWSplit(C,D),!.
 1025
 1026
 1027sameWordsDict([String|A],[Pattern|B]):-!,sameWordsDict0(String,Pattern),!,sameWordsDict_l(A,B),!.
 1028sameWordsDict(String,Pattern):-sameWordsDict0(String,Pattern),!.
 1029
 1030sameWordsDict_l([String|A],[Pattern|B]):-sameWordsDict0(String,Pattern),sameWordsDict_l(A,B),!.
 1031sameWordsDict_l([],[]):-!.
 1032
 1033sameWordsDict0(verbatum(_String),_):-!,fail.
 1034sameWordsDict0(_,verbatum(_Pattern)):-!,fail.
 1035sameWordsDict0(String,Pattern):-compound(String),
 1036   prolog_must((answerOutput_atom(String,String1),debugFmt(interactStep(String,String1,Pattern)),String \== String1)),!,
 1037   sameWordsDict0(String1,Pattern).
 1038
 1039sameWordsDict0(String,Pattern):-compound(Pattern),
 1040   prolog_must((answerOutput_atom(Pattern,Pattern1),debugFmt(interactStep(Pattern,Pattern1,String)), Pattern \== Pattern1)),!,
 1041   sameWordsDict0(String,Pattern1).
 1042
 1043sameWordsDict0(String,Pattern):-String==Pattern,!,debugFmt(sameWordsDict(String,Pattern)).
 1044%sameWordsDict0(String,Pattern):-debugFmt(sameWordsDict0(String,Pattern)),wildcard_match(Pattern,String),!.
 1045%sameWordsDict0(String,Pattern):-dwim_match(Pattern,String),!.
 1046
 1047answerOutput_atom(Pattern,Pattern1):-unresultify(Pattern,Pattern0),unlistify(Pattern0,Pattern1),!,prolog_must(atomic(Pattern1)).
 1048
 1049dictReplace(DictName,Before,After):-dict(substitutions(DictName),Before,After).%%convert_substs(Before,B),convert_template(Ctx,After,A).
 1050
 1051substituteFromDict(Ctx,DictName,Hidden,Output):-answerOutput(Hidden,Mid),Hidden\==Mid,!,substituteFromDict(Ctx,DictName,Mid,Output),!.
 1052
 1053substituteFromDict(Ctx,DictName,Hidden,Output):- dictReplace(DictName,_,_),prolog_must(substituteFromDict_l(Ctx,DictName,Hidden,Output)),!.
 1054
 1055substituteFromDict(_Ctx,DictName,Hidden,Output):- dictReplace(DictName,_,_),!,
 1056      recorda(DictName,Hidden),
 1057      forall(dictReplace(DictName,Before,After),
 1058          (recorded(DictName,Start,Ref),
 1059          erase(Ref),
 1060          pred_subst(sameWordsDict,Start,Before,verbatum(After),End),
 1061          recorda(DictName,End))),
 1062      recorded(DictName,Output,Ref),
 1063      debugFmt(substituteFromDict(Hidden,Output)),
 1064      erase(Ref),!.
 1065
 1066substituteFromDict(Ctx,DictName,Hidden,Result):- isGenTemplate(Ctx,[]),!,Result=[substs,DictName,on,Hidden].
 1067substituteFromDict(_Ctx,DictName,Hidden,result([substs,DictName,on,Hidden],Result)):-Result=..[DictName,Hidden].
 1068
 1069substituteFromDict_l(_Ctx,_DictName,Hidden,Output):-atomic(Hidden),!,Hidden=Output.
 1070substituteFromDict_l(Ctx,DictName,[V|Hidden],[V|Output]):-verbatum(_)==V,!,substituteFromDict_l(Ctx,DictName,Hidden,Output).
 1071substituteFromDict_l(Ctx,DictName,Hidden,[verbatum(After)|Output]):-dictReplace(DictName,Before,After),
 1072   debugOnError((length(Before,Left),length(NewBefore,Left))),
 1073   append(NewBefore,Rest,Hidden),sameBinding(NewBefore,Before),!,substituteFromDict_l(Ctx,DictName,Rest,Output).
 1074substituteFromDict_l(Ctx,DictName,[V|Hidden],[V|Output]):-substituteFromDict_l(Ctx,DictName,Hidden,Output).
 1075
 1076:- addScopeParent(toplevel,cateFallback).
 1077:- addScopeParent(filelevel,toplevel).
 1078:- addScopeParent(category,filelevel).
 1079:- prolog_mustEach((cateFallback(ATTRIBS), pushAttributes(_Ctx,cateFallback,ATTRIBS))).
 1080%%:- prolog_mustEach((cateFallback(ATTRIBS), popAttributes(_Ctx,cateFallback,ATTRIBS), !)).
 1081%%:- cateFallback(ATTRIBS), pushAttributes(_Ctx,cateFallback,ATTRIBS).
 1082
 1083% run main loop if this was the toplevel file
 1084do_main_if_load:- current_prolog_flag(associated_file,File),file_base_name(File, 'logicmoo_module_aiml.pl')->main_loop;true