|
Proteus Conversational Interface
The Proteus technology is a proprietary
conversational interface engine developed by Artificial Ingenuity. The Proteus conversational interface can be utilized as a front-end to any software application. Coupled with voice recognition and text to speech packages, Proteus facilitates true natural human speech communication with computer applications. The architecture further supports complex knowledge representation for expert-system style functionality.Development of this technology commenced on September 17th of 2002, and has seen seven major revisions as of the date of this document. A basic overview of the applied technologies follows.
Proteus architecture centers around a "fuzzy logic" based pattern matching system for specific responsive behaviors. The processing model (or "Brain") is not a simple "couplet" or "one-liner" non-contextual system as are many "chat-bot" type designs, nor is it an immense case structure as is well known public domain designs.
State and contextual knowledge can be modeled in several ways within the Proteus architecture. The 'Brain" maintains "State" and "Mode" specific structures, as well as facility for use of discrete facts, and "Collections" which represent classes or collections of information. The fuzzy logic system incorporates facility to reference discrete or abstracted class information, as well as the current Brain State and Mode, from within the behavior determinism functions, allowing unprecedented richness of behavioral models from within a single architecture.
The design implements "Modes" of operation, which provide completely separate behavioral structures to implement non integrated, or modal, behaviorisms. Meaning different personality of emotional states may be implemented by separate modes of behavior. This feature can further be used to isolate and simplify subject specific interactions, such as for "help-desk", or expert-system style functionality.
The "State" functionality provides for state specific behaviors within the clauses or predicates of a given behavioral mode. This provides for a simplified topical or behavioral modifier to be made to existing clauses and predicates. This may be utilized to simulate "moods", or topical deviations based upon subject matter.
All data functions of the Proteus architecture are dynamic, meaning that facts and collections may be updated or added to dynamically as a function of the user's interaction with the knowledge base. This facilitates Proteus learning user specific information, as well as contextual facilities for complex heuristic behavior. This can be used in such fashion to allow Proteus to be taught by interaction, as well as by data insertion. Further, as of version 5.0 self-modifying knowledge bases are supported.
The current version also supports procedural behavior, as well as decision tree type of expert system functionality. Complicated diagnostic or procedural functionality can be designed as a decision tree within the Proteus knowledge base to facilitate use in business or technical assistant applications. This complements the conversational aspects of the Proteus technology to provide truly usable expert systems. Also, there is an interface provided to the OpenMind Commonsense Database of 500,000 facts.
Content development if implemented in the "Proteus Language", which is a unique declarative language that is compiled directly to a Proteus "brain" structure. There is facility from within PL to generate new PL declarations. Via this method self extending and self modifying functionality is provided. This means that Proteus can not only accumulate additional data, but can also change it's own programming to accommodate learning behaviors.
The basic Proteus Language definition is as follows:
Fact {Name} = {Value}
Start-Collection {Name}
End-Collection
Mode {Name}
State {Name}
Procedure {Name}
Step {Name},{Query}
For-Mode
For-Step
Threshold From,To
For-State {Name}
Fragment Type,Bonus,Penalty,{Fragment},{TheName},{TheValue}
Response {Response Text},Type,{TheName},{TheValue}
Task {Response Text},Type,{TheName},{TheValue}
Name-Object {ObjectName}
Auto-Name
The PL defined fragment types are as follows:
None, AND, OR, NOT, CUSTOM, Data-Match, External, State-Match,
In Collection, Volition, Out-Match, CUSTOM-Sub, In Collection-Sub, Initialize, Finalize,
Do-Before, Do-After, EXTRACT
The PL defined response and task types are as follows:
None, Just Text, Mode Change, Nested, Assignment, Action, Reset Hits, State Change, Reset State, Task List, Reset KM Hits, Reset Brain Hits, Add To Collection, Remove From Collection, Submit This, Log This, Start Proc, Goto Step, Halt Proc, Ask OpenMind, Call Proc, Proc Return, Self Modify, Load Collection, Save Collection, Clear Collection, Parse Collection, Delete Object, Make Code, Merge Collection, Do Response For, Words To Collection, Create AutoPattern, Add Response, Add Fragment
The Proteus Language was designed as a declarative language to be compiled directly into a Proteus Technology brain construct. The current language definition is intended to be representative of the underlying brain structure, rather than following a traditional procedural structure.
By definition, declarative languages are not intended to define a step-wise procedural process, but instead describe an underlying abstraction. This lends itself well to the application at hand. The Proteus architecture is richly abstracted, but nonetheless in essence a complex state machine. The Proteus language is a top-down description of the brain state, which is compiled directly into the collection of objects and constructs of a Proteus brain.
Please note that there is facility for
procedural type behavior for those cases that may arise. Also
provided are special task types that invoke other clauses, providing
subroutine type behavior and minimizing duplication of
functionality.
A Proteus brain upon creation always contains a few initial constructs. There is initially a state called "Normal", and a mode and knowmode called "Default". The PL (Proteus Language) attributes new declarations of child types to the most recently declared parent type. This therefore means that new clause declarations are assigned to the "Default" knowmode unless a new knowmode has been declared prior to the clause.
PL programs are free-form, meaning that they do not require adherence to sectional based rules, such as declaring all of the facts or collections in a given section of the source code. For the sake of clarity the author would suggest that PL writers should place clause and other definitions within proximity to the parent type declarations, unless clarity of behavioral relationships supercede this.
The syntactical rules for PL are relatively simple. All lines that are not a declaration (and are not part of a collection's contents) will be considered a comment, or ignored white-space. All declarations must exist on one line, wrapping to a second line indicates a new declaration or comment to the compiler. The sole exception to this rule is the collections declaration format. A collection has a start and an end declaration (each on their own line), and all lines (if any) between represent members of the collection.
Declarations can contain two kinds of specifiers: textual and value. Textual data is specified as being contained within an opening and closing curly brace (like {dog} is the text "dog"). The text may contain curly braces without conflict (as that the Tag/Tokens are defined to use them to indicate parameters). Value data is specified by simply typing the value to be represented. Some values may indicate type information (such as fragment type), and is therefore textual, but is NOT enclosed in curly braces. In the case of type information, capitalization does not matter, but spacing and punctuation must match the type definition.
Multiple specifiers are separated by commas. Specifiers may be excluded from a declaration if a default value is acceptable. This is indicated by omitting the specifier completely if at the end of the list, or including the comma delimiter without the value if not (meaning that multiple commas represent empty specifier placeholders).
Fragment types:
1. None
No value calculated for this fragment.
2. AND
If the contents of "Word Fragment" are found in the user's input a bonus of 100 points are awarded to the pattern score, if not found then 100 points are deducted from the pattern score. Uses complete word matching.
3. OR
If the contents of "Word Fragment" are found in the user's input a bonus of 50 points are awarded to the pattern score, if not found then the pattern score is not affected. Uses complete word matching.
4. NOT
If the contents of "Word Fragment" are found in the user's input 100 points are deducted from the pattern score, if not found then 100 points are added from the pattern score. Uses complete word matching.
5. CUSTOM
If the contents of "Word Fragment" are found in the user's input a bonus of "Bonus" points are awarded to the pattern score, if not found then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer. Uses complete word matching.
6. Data-Match
If the "Fact" named in "Name" is equal to the value "Value", then a bonus of "Bonus" points are added to the pattern score, if not then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer.
7. External
Not currently used. Will query external applications with the user's input for a Boolean result, whereupon if true then a bonus of "Bonus" points are added to the pattern score, if not then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer.
8. State-Match
If the current "Brain State" is equal to "Name", then a bonus of "Bonus" points are added to the pattern score, if not then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer.
9. In Collection
If the user's input contains a "Member" of the "Data Collection" named by "Name", then a bonus of "Bonus" points are added to the pattern score, if not then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer. Uses complete word matching.
10. Volition
This fragment type behaves different than the others. There is no value impact to the pattern score when user's input is evaluated. However, if "Volition" is active, then the pattern will be activated according to the fractional value in "Word Fragment". The value can be calculated from one 24 hour day = 1.0, which means the 1 hour = 0.041666, and 1 minute = 0.0006944, and 10 seconds = 0.00011573. This will only occur if the pattern is located within the active "Know-Mode" as indicated by the "Current Mode".
11. Out-Match
If the contents of "Word Fragment" are found in Proteus's last output a bonus of "Bonus" points are awarded to the pattern score, if not found then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer. Uses complete word matching.
12. CUSTOM-Sub
If the contents of "Word Fragment" are found in the user's input a bonus of "Bonus" points are awarded to the pattern score, if not found then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer. Uses sub-pattern matching.
13. In Collection-Sub
If the user's input contains a "Member" of the "Data Collection" named by "Name", then a bonus of "Bonus" points are added to the pattern score, if not then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer. Uses sub-pattern matching.
14. Initialize
This fragment type behaves different than the
membership fragments. There is no value impact to the pattern score when user's input is evaluated. However, when the brain's initialization is invoked the pattern will be activated. This facilitates initial setup actions, such as loading collections from disk, etc.
15. Finalize
This fragment type behaves different than the
membership fragments. There is no value impact to the pattern score when user's input is evaluated. However, when the brain's finalization is invoked the pattern will be activated. This facilitates initial setup actions, such as saving collections to disk, etc.
16. Do-Before
This fragment type behaves different than the
membership fragments. There is no value impact to the pattern score when user's input is evaluated.
Any Patterns with this fragment type attached are always processed
prior to the user's input being evaluated. This facilitates
behavior common to all input cases, such as creating a log file of
user input, etc.
17. Do-After
This fragment type behaves different than the
membership fragments. There is no value impact to the pattern score when user's input is evaluated.
Any Patterns with this fragment type attached are always processed
after the user's input has been evaluated and responded to.
This facilitates behavior common to all input cases, such as
creating a log file of Proteus responses, etc.
18. EXTRACT
The Extract fragment type provides a
more elegant solution for extracting information from a specific
pattern and assigning the extracted data to "Facts".
If the pattern described by "Word Fragment" matches the user's input a bonus of "Bonus" points
is awarded to the pattern score, if not found then "Penalty" points are deducted from the pattern score. Both "Bonus" and "Penalty" may be a positive or negative integer.
This fragment type uses a special Token type (^Extr{}) to
create the pattern and specify the Fact names in which the user data
is to be stored.
Response/Task Types:
1. None
No response or action is taken.
2. Just Text
This response type will output the contents if any of "Out Text" to the user.
3. Mode Change
This response type will output the contents if any of "Out Text" to the user, and will then change the "Current Mode" to the mode indicated by "Name". This will cause all further user input to be evaluated by the "Know-Mode" structure indicated by the new "Current Mode".
4. Nested
This response type will output the contents if any of "Out Text" to the user, and will then pass the user's input on for processing to the "Know-Mode" structure that exists as a subordinate to this "Response" or "Task".
5. Assignment
This response type will output the contents if any of "Out Text" to the user, and will then assign the value "Value" to the "Fact" identified by "Name".
6. Action
This response type will output the contents if any of "Out Text" to the user, and will then execute the external application as specified by the contents of "Name".
7. Reset Hits
This response type will output the contents if any of "Out Text" to the user, and will then reset to zero the "Hit Count" of the "Pattern" to which it is attached.
8. State Change
This response type will output the contents if any of "Out Text" to the user, and will then change the "Current State" to the "State" identified by "Name".
9. Reset State
This response type will output the contents if any of "Out Text" to the user, and will then reset the "Current State" to the default "State".
10. Task List
This response type will output the contents if any of "Out Text" to the user after having executed the attached list of "Tasks". A task is functionally identical to a response, with the exception that it can not have a list of sub-tasks.
11. Reset KM Hits
This response type will output the contents if any of "Out Text" to the user, and will then reset to zero the "Hit Count" of all patterns in the current "Know-Mode".
12. Reset Brain Hits
This response type will output the contents if any of "Out Text" to the user, and will then reset to zero every "Hit Count" residing within the "Brain".
13. Add To Collection
This response type will output the contents if any of "Out Text" to the user, and will then add the data contained in "Value" to the "Data Collection" identified by "Name". If the "Data Collection" does not exist, then it will be created.
14. Remove From Collection
This response type will output the contents if any of "Out Text" to the user, and will then remove the data contained in "Value" from the "Data Collection" identified by "Name".
15. Submit This
This response type will output the contents if any of "Out Text" to the user, and will then submit the contents of "Name" to the "Brain" for a response. This may facilitate chaining several patterns together for complex behavior, and as an associative method of equivalency.
16. Log This
This response type will output the contents if any of "Out Text" to the user, and will then add the contents of "Value" to a text file identified by the file specification contained in "Name". If the text file does not exist it will be created.
17. Start Proc
This response type will initiate a "Procedure" identified by "Name", and will begin processing at the specified "Start Step", or the first "Step" in the procedure if a specific starting step override has not been specified.
18. Goto Step
This response type will jump to the specified "Step" identified by "Name" that exists within the currently executing "Procedure". This response type is meaningless if a procedure is not executing when the response is invoked. When a "Start Proc" response type is invoked, the procedure is automatically started at the default step, therefore invoking "Goto Step" prior to a "Start Proc" is meaningless.
19. Halt Proc
This response type will terminate any currently executing "procedure", and does not require any specification as that only one procedure may be in operation at any given time. This is the normal method for terminating procedures.
20. Ask OpenMind
This response type will invoke the "OpenMind" interface, passing the contents of "Name" as a query to the OpenMind Commonsense Database. Any results generated by the OpenMind interface will then be provided to the user. If the "OpenMind" database is not in the default path you may specify the path for Proteus to find "OpenMind" in the "Value" field.
21. Call Proc
This response type will initiate a "Sub-Procedure" identified by "Name", and will begin processing at the specified "Start Step", or the first "Step" in the procedure if a specific starting step override has not been specified.
22. Proc Return
This response type will return to the "Procedure" from which the "Sub-Procedure" was called, and will continue at the "Step" from which it was invoked. This response type in conjunction with "Call Proc" above provide facility for nested sub-procedures (to any level), allowing for re-use of common procedural behaviors.
23. Self Modify
This response type will modify the contents of any object that has been named "Out Text". The specific member of the object is specified by "Name", and the new value is specified by "Value". There is always at least one named object "MyBrain", which allows modification to the brain object itself. The fields for each of the brain object classes are defined following this section, in table A.
24. Load Collection
This response type will load a Collection from disk, creating it if it did not previously exist. The name is specified in "Name", and the file name and path is specified by "Value".
25. Save Collection
This response type will save a Collection to disk. The name is specified in "Name", and the file name and path is specified by "Value".
26. Clear Collection
This response type will clear the contents of the Collection specified by "Name".
27. Parse Collection
This response type will parse text specified in "OutText" looking for members of the source Collection specified by "Name", and add all such members that are found to the Collection specified by "Value". This is a much more useful function than may be immediately apparent. This facilitates (for example) creating a Collection called "likes pets" by parsing an input string like "I like dogs and cats" using a source Collection called "pets" that contains all known pet types. In the example, a new Collection would be created that contained two members: "Dogs", and "Cats". In addition to the example given, this feature facilitates lexical and semantic analysis.
28. Delete Object
This response type will remove from the brain any previously named brain object, as specified by "OutText". This is useful for self-modification uses.
29. Make Code
This response type will execute the "Proteus Language" code found in the Collection specified by "OutText". This facilitates generation of any brain object or feature using the contents of a Collection. This allows Proteus to extend it's own programming.
30. Merge Collection
This response type adds the contents of the source Collection specified by "Name" to the Collection specified by "Value". It simply appends the source Collection items to the end of the destination Collection, or creates it if it doesn't exist.
31. Do Response For
This response type executes the responses for the clause (Pattern) specified by "Name", facilitating "sub-routine" type functionality for common tasks. For example, if you want Proteus to always track the current topic, but don't want to add the several steps required for this in every clause of every mode, then just create 1 clause with these steps, name it, and add a "Do Response For" from the other clauses.
32. Words To Collection
This response type parses the string contained in "OutText" into individual words and places them in the Data Collection specified by "Name".
33. Create AutoPattern
This response type automatically generates a new Clause (or Pattern) based upon the passed parameters. The contents of "OutText" will be parsed into individual word fragments, given a matching value stored in "Name", and a 'Text Only" Response as stored in "Value". The components of the Clause will be Auto-Named.
34. Add Response
This response type adds a "Text Only" response to the last Clause used or added, with the text to out put of "OutText". The Response will be Auto-Named.
35. Add Fragment
This response type adds a Fragment to the last Clause used or added, with a fragment value of "OutText", and a match bonus indicated in "Name".
36. Set Unsorted
This response type will set the contents of the Collection specified by
"Name" to be unsorted. By default data collection
contents are alphanumerically sorted for lookup performance.
Source code for ProteusDemo.EXE
To show how simply Proteus technology can be implemented in real applications, we are including the full (excluding the actual brain and compiler modules) source code for the ProteusDemo application we distribute.
unit PDemoMain;
(*
Copyright 2003, 2004, Artificial Ingenuity, LLC
All rights reserved.
*)
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
RzPanel, Buttons, RzButton,Grids_ts, TSGrid, ExtCtrls, StdCtrls, a1u2, OleServer,
SpeechLib_TLB, ComCtrls, ActiveX, IniFiles;
type
TForm1 = class(TForm)
RzToolbar1: TRzToolbar;
BtnExit: TRzToolbarButton;
BtnNew: TRzToolbarButton;
BtnOpen: TRzToolbarButton;
BtnSave: TRzToolbarButton;
BtnView: TRzToolbarButton;
BtnUtilities: TRzToolbarButton;
BtnPlaySound: TRzToolbarButton;
RzSpacer: TRzSpacer;
RzSpacer1: TRzSpacer;
RzSpacer2: TRzSpacer;
Memo1: TMemo;
Edit1: TEdit;
RzButton1: TRzButton;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
SpVoice1: TSpVoice;
BtnProperties: TRzToolbarButton;
procedure BtnExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure RzButton1Click(Sender: TObject);
procedure BtnPlaySoundClick(Sender: TObject);
procedure BtnOpenClick(Sender: TObject);
procedure BtnSaveClick(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure BtnViewClick(Sender: TObject);
procedure BtnNewClick(Sender: TObject);
procedure BtnUtilitiesClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BtnPropertiesClick(Sender: TObject);
procedure Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
Brain : BrainClass;
VoiceOn: boolean;
brainNode,
modeNode,
kmodeNode,
ProcNode,
ProcPNode,
factNode,
stateNode,
NobjNode,
DataCollNode,
tmpNode : TTreeNode;
Changed: boolean;
FuncKeyArray: array [1..12] of string;
IniFile: TIniFile;
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
ComObj, Contnrs, ProtLangU, ai1u2x, PDemoEdU, FuncKeys;
procedure MyShowCount(s: string);
begin
Form1.Caption := s;
end;
procedure MyCallback(var output: string);
begin
if Output = '' then exit; //suppress empty lines
Form1.Memo1.Lines.Add('[Proteus]: '+Output);
Form1.Edit1.Text := '';
if Form1.VoiceOn then begin
Form1.spVoice1.Speak(Output, SVSFDefault);
Form1.spVoice1.WaitUntilDone(999);
end;
end;
procedure TForm1.BtnExitClick(Sender: TObject);
begin
if Self.Changed then begin
if MessageDlg('Exit Program Without Saving Changes??', mtConfirmation, mbOKCancel, 0) = mrOK then begin
Self.Brain.DoFinalizes;
Self.Brain.Free;
Close;
end
end
else begin
Self.Brain.DoFinalizes;
Self.Brain.Free;
Close;
end
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
Self.Brain := BrainClass.Create(MyCallBack);
Self.VoiceOn := false;
Self.Changed := false;
Self.IniFile := TIniFile.Create(ChangeFileExt(Application.ExeName, '.INI'));
for i := 1 to 12 do
Self.FuncKeyArray[i] := IniFile.ReadString('FuncKeys', 'Key'+IntToStr(i), '');
end;
procedure TForm1.RzButton1Click(Sender: TObject);
begin
Self.Memo1.Lines.Add('[user]: '+Self.Edit1.Text);
Self.Brain.RequestResponseFor(Self.Edit1.Text);
end;
procedure TForm1.BtnPlaySoundClick(Sender: TObject);
begin
Self.VoiceOn := not Self.VoiceOn;
end;
procedure TForm1.BtnOpenClick(Sender: TObject);
begin
If Changed then begin
if MessageDlg('Discard Changes Made??', mtConfirmation, mbOKCancel, 0) <> mrOK then begin
exit
end
end;
If OpenDialog1.Execute then begin
Self.Brain.DoFinalizes;
Self.Brain.Free;
Self.Brain := BrainClass.Create(MyCallBack);
ShowCountProc := MyShowCount;
Self.RzToolbar1.Enabled := false;
Self.RzButton1.Enabled := false;
LoadLangFile(Self.Brain, OpenDialog1.FileName);
Self.RzToolbar1.Enabled := true;
Self.RzButton1.Enabled := true;
Self.Caption := 'Artificial Ingenuity, LLC Proteus Evaluation Program';
Self.Brain.DoInitializes;
Self.Changed := false;
end;
end;
procedure TForm1.BtnSaveClick(Sender: TObject);
begin
if SaveDialog1.Execute then begin
ShowCountProc := MyShowCount;
Self.RzToolbar1.Enabled := false;
Self.RzButton1.Enabled := false;
SaveLangFile(Self.Brain, Self.SaveDialog1.FileName);
Self.RzToolbar1.Enabled := true;
Self.RzButton1.Enabled := true;
Self.Caption := 'Artificial Ingenuity, LLC Proteus Evaluation Program';
Self.Changed := false;
end;
end;
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = Char(13) then begin
Self.RzButton1.OnClick(Self.RzButton1);
Key := char(0);
end;
end;
function doName(name: string): string;
begin
if name = '' then
result := ''
else
result := ' NAME{'+name+'}'
end;
procedure TForm1.BtnViewClick(Sender: TObject);
//this long procedure is for the tree view of the brain
var
i,j,k,l,m: integer;
tmpNode,
tmpNode2,
tmpNode3,
tmpNode4,
tmpNode5,
tmpNode6,
tmpNode7,
tmpNode8,
tmpNode9,
tmpNode10: TTreeNode;
tKC : KnowledgeClass;
tPC : PatternClass;
tWF : WordFragmentClass;
tRC : ResponseClass;
tTC : TaskClass;
tTH : ThresholdClass;
tSC : StateClass;
tDC : DataCollectionClass;
tProc : ProcClass;
tStep : StepClass;
tStepP : StepPatternClass;
tObj : TObject;
begin
Form2 := TForm2.Create(self);
Form2.Caption := 'Loading, Please WAIT...';
Form2.Show;
Application.ProcessMessages;
Form2.TreeView1.ReadOnly := true;
Form2.TreeView1.AutoExpand := false;
Form2.TreeView1.RightClickSelect := true;
brainNode := Form2.TreeView1.Items.AddFirst(nil, 'Brain'+doName(Brain.MyName));
brainNode.Data := Brain;
tmpNode := Form2.TreeView1.Items.AddChild(brainNode, 'Current Mode = '+IntToStr(Brain.CurrentMode));
tmpNode.Data := Brain;
tmpNode := Form2.TreeView1.Items.AddChild(brainNode, 'Current State = '+IntToStr(Brain.CurrentState));
tmpNode.Data := Brain;
tmpNode := Form2.TreeView1.Items.AddChild(brainNode, 'Current Proc = '+IntToStr(Brain.CurrentProc));
tmpNode.Data := Brain;
NObjNode := Form2.TreeView1.Items.AddChild(brainNode, 'Named Objects');
NObjNode.Data := Brain.NamedObjects;
for i := 0 to Brain.NamedObjects.Count - 1 do begin
tmpNode := Form2.TreeView1.Items.AddChild(NObjNode, Brain.NamedObjects.Strings[i]);
tmpNode.Data := Brain.NamedObjects;
end;
stateNode := Form2.TreeView1.Items.AddChild(brainNode, 'States');
stateNode.Data := Brain.States;
for i := 0 to Brain.States.Count - 1 do begin
tmpNode := Form2.TreeView1.Items.AddChild(stateNode, Brain.States.Strings[i]);
tmpNode.Data := Brain.States;
end;
DataCollNode := Form2.TreeView1.Items.AddChild(brainNode, 'Collections');
DataCollNode.Data := Brain.DataColNames;
for i := 0 to Brain.DataColNames.Count - 1 do begin
tDC := Brain.DataColNames.Objects[i] as DataCollectionClass;
tmpNode := Form2.TreeView1.Items.AddChild(DataCollNode, Brain.DataColNames.Strings[i]);
tmpNode.Data := tDC;
for j := 0 to tDC.TheData.Count -1 do begin
tmpNode2 := Form2.TreeView1.Items.AddChild(tmpNode, tDC.TheData.Strings[j]);
tmpNode2.Data := tDC;
end;
end;
factNode := Form2.TreeView1.Items.AddChild(brainNode, 'Facts');
factNode.Data := Brain.FactNames;
for i := 0 to Brain.FactNames.Count - 1 do begin
tmpNode := Form2.TreeView1.Items.AddChild(factNode, Brain.FactNames.Strings[i]+'='+Brain.Facts.Strings[i]);
tmpNode.Data := Brain.FactNames;
end;
ProcNode := Form2.TreeView1.Items.AddChild(brainNode, 'Procedures');
ProcNode.Data := Brain.Procs;
for i := 0 to Brain.Procs.Count - 1 do begin
tmpNode := Form2.TreeView1.Items.AddChild(ProcNode, Brain.Procs.Strings[i]);
tmpNode.Data := Brain.Procs;
end;
ProcPNode := Form2.TreeView1.Items.AddChild(brainNode, 'Proc-Detail');
ProcPNode.Data := Brain.TheProcs;
for i := 0 to Brain.TheProcs.Count - 1 do begin
tProc := Brain.TheProcs.Items[i] as ProcClass;
tmpNode := Form2.TreeView1.Items.AddChild(ProcPNode, tProc.TheName+doName(tProc.MyName));
tmpNode.Data := tProc;
tmpNode2 := Form2.TreeView1.Items.AddChild(tmpNode, 'Steps');
tmpNode2.Data := tProc;
for j := 0 to tProc.Steps.Count -1 do begin
tStep := tProc.Steps.Items[j] as StepClass;
tmpNode3 := Form2.TreeView1.Items.AddChild(tmpNode2, tStep.TheName+doName(tStep.MyName));
tmpNode3.Data := tStep;
tmpNode4 := Form2.TreeView1.Items.AddChild(tmpNode3, 'Clauses');
tmpNode4.Data := tStep;
for k := 0 to tStep.StepPatterns.Count -1 do begin
tStepP := tStep.StepPatterns.Items[k] as StepPatternClass;
tmpNode5 := Form2.TreeView1.Items.AddChild(tmpNode4, IntToStr(k+1)+doName(tStepP.MyName));
tmpNode5.Data := tStepP;
tmpNode6 := Form2.TreeView1.Items.AddChild(tmpNode5, 'Fragments');
tmpNode6.Data := tStepP;
for l := 0 to tStepP.WordFragments.Count -1 do begin
tWF := tStepP.WordFragments.Items[l] as WordFragmentClass;
tmpNode8 := Form2.TreeView1.Items.AddChild(tmpNode6, FragRelationAs(tWF.Relation)+' - '+tWF.WordFrag+doName(tWF.MyName));
tmpNode8.Data := tWF;
end;
tmpNode7 := Form2.TreeView1.Items.AddChild(tmpNode5, 'Responses');
tmpNode7.Data := tStepP;
for l := 0 to tStepP.Responses.Count -1 do begin
tRC := tStepP.Responses.Items[l] as ResponseClass;
tmpNode8 := Form2.TreeView1.Items.AddChild(tmpNode7, RespTypeAs(tRC.ResponseType)+': '+tRC.OutText+doName(tRC.MyName));
tmpNode8.Data := tRC;
tmpNode9 := Form2.TreeView1.Items.AddChild(tmpNode8, 'Tasks');
tmpNode9.Data := tRC;
for m := 0 to tRC.Tasks.Count -1 do begin
tTC := tRC.Tasks.Items[m] as TaskClass;
tmpNode10 := Form2.TreeView1.Items.AddChild(tmpNode9, RespTypeAs(ttc.ResponseType)+': '+ttc.OutText+doName(tTC.MyName));
tmpNode10.Data := ttc;
end;
end;
end;
end;
end;
modeNode := Form2.TreeView1.Items.AddChild(brainNode, 'Modes');
modeNode.Data := Brain.Modes;
for i := 0 to Brain.Modes.Count - 1 do begin
tmpNode := Form2.TreeView1.Items.AddChild(modeNode, Brain.Modes.Strings[i]);
tmpNode.Data := Brain.Modes;
end;
kmodeNode := Form2.TreeView1.Items.AddChild(brainNode, 'Know-Modes');
kmodeNode.Data := Brain.KnowledgeModes;
for i := 0 to Brain.KnowledgeModes.Count - 1 do begin
tKC := Brain.KnowledgeModes.Items[i] as KnowledgeClass;
tmpNode := Form2.TreeView1.Items.AddChild(kmodeNode, tKC.MyMode+doName(tKC.MyName));
tmpNode.Data := tKC; //Brain.KnowledgeModes;
tmpNode2 := Form2.TreeView1.Items.AddChild(tmpNode, 'Clauses');
tmpNode2.Data := tKC;
for j := 0 to tKC.Patterns.Count -1 do begin
tPC := tKC.Patterns.Items[j] as PatternClass;
tmpNode3 := Form2.TreeView1.Items.AddChild(tmpNode2, IntToStr(j+1)+' - Hits:'+IntToStr(tPC.HitCount)+doName(tPC.MyName));
tmpNode3.Data := tPC;
tmpNode4 := Form2.TreeView1.Items.AddChild(tmpNode3, 'Fragments');
tmpNode4.Data := tPC;
for k := 0 to tPC.WordFragments.Count -1 do begin
tWF := tPC.WordFragments.Items[k] as WordFragmentClass;
tmpNode5 := Form2.TreeView1.Items.AddChild(tmpNode4, FragRelationAs(tWF.Relation)+' - '+tWF.WordFrag+' '+tWF.TheName+doName(tWF.MyName));
tmpNode5.Data := tWF;
end;
tmpNode4 := Form2.TreeView1.Items.AddChild(tmpNode3, 'Responses');
tmpNode4.Data := tPC;
for k := 0 to tPC.Responses.Count -1 do begin
tRC := tPC.Responses.Items[k] as ResponseClass;
tmpNode5 := Form2.TreeView1.Items.AddChild(tmpNode4, RespTypeAs(tRC.ResponseType)+': '+tRC.OutText+doName(tRC.MyName));
tmpNode5.Data := tRC;
tmpNode6 := Form2.TreeView1.Items.AddChild(tmpNode5, 'Tasks');
tmpNode6.Data := tRC;
for l := 0 to tRC.Tasks.Count -1 do begin
tTC := tRC.Tasks.Items[l] as TaskClass;
tmpNode7 := Form2.TreeView1.Items.AddChild(tmpNode6, RespTypeAs(ttc.ResponseType)+': '+ttc.OutText+doName(tTC.MyName));
tmpNode7.Data := ttc;
end;
end;
tmpNode4 := Form2.TreeView1.Items.AddChild(tmpNode3, 'Thresholds');
tmpNode4.Data := tPC;
for k := 0 to tPC.Thresholds.Count -1 do begin
tTH := tPC.Thresholds.Items[k] as ThresholdClass;
tmpNode5 := Form2.TreeView1.Items.AddChild(tmpNode4, IntToStr(tTH.ThreshFrom)+' to '+IntToStr(tTH.ThreshTo)+doName(tTH.MyName));
tmpNode5.Data := tTH;
tmpNode6 := Form2.TreeView1.Items.AddChild(tmpNode5, 'Responses');
tmpNode6.Data := tTH;
for l := 0 to tTH.Responses.Count -1 do begin
tRC := tTH.Responses.Items[l] as ResponseClass;
tmpNode7 := Form2.TreeView1.Items.AddChild(tmpNode6, RespTypeAs(tRC.ResponseType)+': '+tRC.OutText+doName(tRC.MyName));
tmpNode7.Data := tRC;
tmpNode8 := Form2.TreeView1.Items.AddChild(tmpNode7, 'Tasks');
tmpNode8.Data := tRC;
for m := 0 to tRC.Tasks.Count -1 do begin
tTC := tRC.Tasks.Items[m] as TaskClass;
tmpNode9 := Form2.TreeView1.Items.AddChild(tmpNode8, RespTypeAs(ttc.ResponseType)+doName(tTC.MyName));
tmpNode9.Data := ttc;
end;
end;
end;
tmpNode4 := Form2.TreeView1.Items.AddChild(tmpNode3, 'States');
tmpNode4.Data := tPC;
for k := 0 to tPC.States.Count -1 do begin
tSC := tPC.States.Items[k] as StateClass;
tmpNode5 := Form2.TreeView1.Items.AddChild(tmpNode4, tSC.State+doName(tSC.MyName));
tmpNode5.Data := tSC;
tmpNode6 := Form2.TreeView1.Items.AddChild(tmpNode5, 'Responses');
tmpNode6.Data := tSC;
for l := 0 to tSC.Responses.Count -1 do begin
tRC := tSC.Responses.Items[l] as ResponseClass;
tmpNode7 := Form2.TreeView1.Items.AddChild(tmpNode6, RespTypeAs(tRC.ResponseType)+': '+tRC.OutText+doName(tRC.MyName));
tmpNode7.Data := tRC;
tmpNode8 := Form2.TreeView1.Items.AddChild(tmpNode7, 'Tasks');
tmpNode8.Data := tRC;
for m := 0 to tRC.Tasks.Count -1 do begin
tTC := tRC.Tasks.Items[m] as TaskClass;
tmpNode9 := Form2.TreeView1.Items.AddChild(tmpNode8, RespTypeAs(ttc.ResponseType)+doName(tTC.MyName));
tmpNode9.Data := ttc;
end;
end;
end;
end;
end;
brainNode.Expand(false);
Form2.Caption := 'Show Knowledge Tree';
end;
procedure TForm1.BtnNewClick(Sender: TObject);
begin
if Self.Changed then begin
if MessageDlg('Discard Changes Made??', mtConfirmation, mbOKCancel, 0) = mrOK then begin
Self.Brain.DoFinalizes;
Self.Brain.Free;
Self.Brain := BrainClass.Create(MyCallback);
Self.Changed := false;
end;
end
else begin
if MessageDlg('Clear Proteus Brain??', mtConfirmation, mbOKCancel, 0) = mrOK then begin
Self.Brain.DoFinalizes;
Self.Brain.Free;
Self.Brain := BrainClass.Create(MyCallback);
Self.Changed := false;
end;
end
end;
procedure TForm1.BtnUtilitiesClick(Sender: TObject);
var
DaStrings: TStrings;
begin
Self.RzToolbar1.Enabled := false;
Self.RzButton1.Enabled := false;
Form3 := TForm3.Create(self);
DaStrings := Form3.Memo1.Lines;
SaveLangStrings(Self.Brain, DaStrings);
if Form3.ShowModal = mrOk then begin
Self.Brain.DoFinalizes;
Self.Brain.Free;
Self.Brain := BrainClass.Create(MyCallback);
ShowCountProc := MyShowCount;
LoadLangStrings(Self.Brain, DaStrings);
Self.Changed := true;
end;
Self.RzToolbar1.Enabled := true;
Self.RzButton1.Enabled := true;
Self.Caption := 'Artificial Ingenuity, LLC Proteus Evaluation Program';
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i: integer;
begin
for i := 1 to 12 do
Self.IniFile.WriteString('FuncKeys', 'Key'+IntToStr(i), Self.FuncKeyArray[i]);
IniFile.Free;
end;
procedure TForm1.BtnPropertiesClick(Sender: TObject);
begin
Form4 := TForm4.Create(self);
Form4.ShowModal;
end;
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key In [112..123] then begin
Self.Edit1.SelText := Self.FuncKeyArray[Key - 111];
Self.Edit1.Modified := true;
end;
end;
end.
View Online Proteus Documentation
View
"Base.PLF" tutorial
View PLF Examples
View Proteus 5.0 Source
code
Contact info@artificialingenuity.com
Copyright © 2005 Artificial Ingenuity, LLC
Last modified: June 11, 2005
Initial design by Webinizer, LLC