import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
import javax.swing.border.TitledBorder;
import javax.swing.border.*;
import java.text.*;
import javax.swing.undo.UndoManager;
import java.nio.charset.Charset;
import java.text.NumberFormat;
import java.awt.datatransfer.StringSelection;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;
import java.text.SimpleDateFormat;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.Timer;
import java.util.TimeZone;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.nio.file.Path;
import javax.swing.filechooser.*;
class main {
// AI begins here
static String substring(String s, int x) {
return substring(s, x, strL(s));
}
static String substring(String s, int x, int y) {
if (s == null)
return null;
if (x < 0)
x = 0;
int n = s.length();
if (y < x)
y = x;
if (y > n)
y = n;
if (x >= y)
return "";
return s.substring(x, y);
}
// convenience method for quickly dropping a prefix
static String substring(String s, CharSequence l) {
return substring(s, lCharSequence(l));
}
public static String join(String glue, Iterable strings) {
if (strings == null)
return "";
if (strings instanceof Collection) {
if (((Collection) strings).size() == 1)
return str(first(((Collection) strings)));
}
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext()) buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String... strings) {
return join(glue, Arrays.asList(strings));
}
static String join(Iterable strings) {
return join("", strings);
}
static String join(Iterable strings, String glue) {
return join(glue, strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static String join(String glue, Pair p) {
return p == null ? "" : str(p.a) + glue + str(p.b);
}
static int lastIndexOf(String a, String b) {
return a == null || b == null ? -1 : a.lastIndexOf(b);
}
static int lastIndexOf(String a, char b) {
return a == null ? -1 : a.lastIndexOf(b);
}
// starts searching from i-1
static int lastIndexOf(List l, int i, A a) {
if (l == null)
return -1;
for (i = min(l(l), i) - 1; i >= 0; i--) if (eq(l.get(i), a))
return i;
return -1;
}
static int lastIndexOf(List l, A a) {
if (l == null)
return -1;
for (int i = l(l) - 1; i >= 0; i--) if (eq(l.get(i), a))
return i;
return -1;
}
static String padLeft(String s, char c, int n) {
return rep(c, n - l(s)) + s;
}
// default to space
static String padLeft(String s, int n) {
return padLeft(s, ' ', n);
}
static String trim(String s) {
return s == null ? null : s.trim();
}
static String trim(StringBuilder buf) {
return buf.toString().trim();
}
static String trim(StringBuffer buf) {
return buf.toString().trim();
}
static class Smarty extends Concept {
static final String _fieldOrder = "IntensityRange Sense Processing50 MaxBodies World bodies VB_Name JND Smarty LeftArrow RightArrow UpArrow DownArrow FourWay Smarty0 BodySetting BodyConfig BodyValue BodyPointing North East South West NumSenses MaxSenses IsSense Senses SensorStimuli PropertyBinonType SymbolicOrMagnitude LowerRangeLimit UpperRangeLimit LinearOrCircular IntegersOrLogs NumberOfSensors SensorsDependentOrIndependent Symbolic Magnitude Linear Circular IntegerValues LogValues Dependent Independent SensorValues Valu XQCnt NoName Motion NoMove WheelMovement ABlock Wall EmptySquare Fired Current NumDevices MaxDevices Device IsDevice Devices DeviceResponses DeviceValues NoResp WheelsTurn MoveForward MoveToLeft MoveToRight MoveBackward TurnRght TurnLft TurnArnd NoMoveOrTurn NumActs RotateActs NumBinons MaxBinons OverLimit Binons BType O1 TQ O2 GQ IDL IntVl OLv SP TriggerList TriggerCount GoalList GoalCount AE NullObject NOVEL INTERESTING FAMILIAR NoInterest InterestLevels Sequential Parallel Action Attention MaxBinonTypes NumBinonTypes BinonTypeName BinName BinAbbreviation BinonTypes ActBin NumProperties NullType SensOrDevNum SensedBinons NumPercepts MaxPercepts Percepts BinId PerceptSources FirstSource SecondSource PerceptLevel NumTargets MaxTargets Targets NLnk TargetBinon NullTarget NumDHabits TopLevel HighestPerceptLvl MaxLevels STM TQCnt MoveAmount PerceivedBinon LTMEMORY LtmPerceptTyp LtmPerceptBin LtmESType LtmESActBin LtmARType LtmARActBin LtmActionTyp LtmActionBin StoreAt MaxMemory INPUTS OUTPUTS SizeBase IntensityBase ASpace SequentialSign ParallelSign CreateAll Normal Happy Unhappy PartMatch DoingReaction DoingRepeat LastAct LIN COUNTIN RecentWorld RecentBody OperatingMode Running Started vbDblQuote Black White LightBlue DarkBlue";
int IntensityRange;
String[] Sense = new String[10 + 1];
boolean Processing50 = false;
int MaxBodies;
transient TheWorld World;
Bodies bodies = new Bodies();
static class TheWorld {
public String LookUnder() {
return "";
}
public void MoveWest() {
}
public void MoveSouth() {
}
public void MoveEast() {
}
public void MoveNorth() {
}
public void PointUnder() {
}
public void PointNorth() {
}
public void PointSouth() {
}
public void PointWest() {
}
public void PointEast() {
}
public void DisplayStimuliAndResponse(int[][][] sensorValues, char resp) {
}
public int RangeSouth() {
return 0;
}
public int RangeNorth() {
return 0;
}
public int RangeEast() {
return 0;
}
public int RangeWest() {
return 0;
}
public String LookSouth() {
return "";
}
public String LookNorth() {
return "";
}
public String LookEast() {
return "";
}
public String LookWest() {
return "";
}
public void Update_View() {
}
public void setBinonDisplayObjList(String text) {
}
public void setBinonDisplayChngResults(String text) {
}
public void appendBinonDisplayChngResults(String text) {
}
public void showSensorValues(String text) {
}
public void showDeviceValues(String text) {
}
}
// end of TheWorld
String VB_Name = "Adaptron";
// Originally was a TEST VERSION WHICH PRODUCES RANDOM INPUT AND
// CHECKS MEMORY TO SEE IF IT CONTAINS THE SAME STUFF
// Obviously must have spun it off of Think 5
// Adaptron/Cognitron Algorithm - Program - Feb. 2003 test
// (C) Copyright 2007, Adaptron Inc.
//
// THINK3 IS NOT HANDLING CONSCIOUS HABITS PROPERLY
// THINK4 IS EXPERIMENT IN EXPECTATIONS BEING SAVED
// THINK5 DOES A PROPER JOB OF HANDLING R-HABITS
// 11 July 2002 - attempting to get the 2 bugs out of pattern matching
// 13th July 2002 - put back the stimulus matching mem location use for
// habit continuation checking in the right order - resulting stimulus
// first then is it an expected trigger.
// pattern4 - July 28, format display better
// pattern5 - July 29 week - trace display improvements -got out bug in
// habit collapsing
// pattern6 - Aug 3 - test some more
// pattern7 - Aug 9 - more tests with manual input, THEN AUTOMATED AGAIN
// pattern8 - Aug 13 - I did top and bottom expected stimuli in habit in
// previous version - now I need to introduce expected stimuli
// in the habit stack fixed up Context saving too - but I think
// some context could be put in LTM for pattern matching on
// context so it doesn't get too long or do pattern matching on
// context while in STM.
// Pattern9 - incorporate thinking changes from Think8 and turn on responses
// Went back to the THINK versions and incorporated results from Pattern9
// THINK7 DOES A PROPER JOB OF HANDLING R-HABITS
// THINK8 Well documented version
// Fixed up some stuff and comments and made it into ACTIONS8.BAS Aug 16th 2002
// ACTIONS8 - Work on comments and then responses -Then went back to Pattern
// versions and worked on Pattern0 -Active Habits that fail attract attention
// and then incorporated these results into Actions8.
// Actions9 - Started to investigate response habits - fixed up
// NOADDSHABITS and removed NOADDHABITS.
// ACTION10 - Make no distinction between doing nothing and doing something
// until the last minute when go to do it.
// - Refine priority of what attracts attention especially for
// familiar input.
// EXPLORE1 - Test it out
// EXPLORE2 - Improve context saving. Use 16 bit memory locations.
// - HAVING PROBLEM WITH HABIT MATCHING - CREATE NEW VERSION
// EXPLORE3 - Change habit stack so current one is on top and any ADDSHABITS
// are below it. Stopped it using context in habits being done.
// EXPLORE4 - Removed code for context saving.
// Explore5 - Visual Basic 6 Version with different windows for LTM, STM etc.
// Boredom turned on for current stimulus and result
// habitualized and this habit has a familiar or novel result
// based on InterestLevel. Old Boredom code commented out.
// Explore6 13th July 2003 Try to make feelings of novel, familiar etc.
// into a new stimulus type which result in information about
// success or failure.
// 12th Aug 2003 Decided not to do this. Instead am
// going to add R-Habits. Decided R-Habits already taken care
// of. Added continuous stimuli from both senses. Investigate
// looping behaviour and subconscious habit execution. Haven't
// done looping but it seems pretty stable.
// Explore7 11th Sept 2003 Now work on subconscious habit execution.
// Add loop execution in subconscious habits
// 24th Sept Allow multiple stimuli on S-List - 1 external &
// 1 internal stimulus. Then fix bugs / features
// Explore8 1st Oct 2003 Now work on R-habits and their execution.
// Explore9 6th Nov 2003 Major change required in how memory stored and
// used - less emphasis on efficiency and episodic accuracy.
// Added multiple S-habit recognition and context of S-habit
// Added conscious looping of permanent S-habits
// Happy1 25th Nov 2003 Add in pain and pleasure. 11th Dec Added
// expectation of Novel as Interesting - exploration is better.
// Happy2 17th Dec 2003 First attempt at adding thinking
// 7th Jan 2004 small changes
// Happy3 10th Jan 2004 turn off separate Trigger and Result stimuli,
// add control flags for it and DoingReflex.
// Happy4 13th Jan,Seperate permanence property from feeling for stimuli
// Add Response Habits containing Response-Stimulus-Response
// Get looping (repeating same stimulus) working properly
// Happy5 20th Jan, getting permanent working, remove stimulus roles
// Happy6 21st Jan, handle dynamic environments
// Happy7 23rd Jan, Try handling S-Habits as R-Habits-no go.
// Happy8 27th Jan, Try to get R-habits as R-S-R working. Feb 12th. Add
// subconscious processes.
// Happy9 23rd Feb, Novel stimulus becomes interesting, then familiar
// Enhance thinking, strategies for handling Interesting
// Works1 6th Mar, 2004, Attend to stimuli
// Works2 30th March, Expectation processing
// Works3 31st March, Stimulus context in LTM for S-Habits too.
// Works4 8th Apr, Recognize loops in R-Habits, Good/Bad testing
// Works5 15th Apr, turn on Kinesthetics, do subconscious habits
// Works6 work on repetition / loops
// Works7 18th July 2004, new learning strategy, Test Cases
// Works8 29th July, Good and Bad processing
// Works9 7th Sept, Generalization & Discrimination - 2 or more senses
// and subconscious habit processing
// Learn1 18th Sept, Conscious versus subconscious behaviour, added
// levels and context at end of LTM
// Learn2 3rd Nov, Kinesthetic stimuli, loops, action habits
// Learn3 23rd Nov, Rename things, subconscious A-Habits, A-sequences
// Learn4 6th Dec, Chained A-Habits, Concentration, A-Sequences
// Learn5 6th Jan, 2005, A&B sequence, thinking refined, kinesthtics,
// order of For's, Separate world
// Learn6 World front-end, ABC repeating pattern & permanent S-Habits
// Learn7 Body info, still working on S-Habits, R-Habits, separate body
// Learn8 11 May 05, separate body & Test Cases, R-Habits, P-Stimuli,
// Difference in R-Habits
// Learn9 21 June 05, 31st Dec 05, removed linked habits, novelty/familarity
// stored as feeling, work on 2nd sense and R-Habits
// Habit1 3rd March 06, New attention algorithm, only collapse permanent
// triggers of S-Habits, practice non-permanent S-Habits
// Habit2 March - Interestlevel based on A & S-Habit feelings
// Habit3 March - Good & Bad, Reward & Punishment, Feelings
// Habit4 Jan 2007 reworking interest levels
// Habit5 29th Jan 07, S-habits collapse when both stimuli are permanent
// A-habits interest propagate back to trigger, S-Habits interest
// propagates up the heirarchy.
// Habit6 16th Feb 07, Rearrange attention algorithm
// Habit7 14th March 07, Add graduated stimuli
// Habit8 25th March 07, New attention algorithm
// Habit9 3rd April 07, Sort out permanent stimuli, attention algorithm
// Cogni1 18th April 07, Work on thinking part, replace feature with sensor
// Recog1, Recog2 Recognition of objects from graduated senses.
// Add discrete Sensor Array, discrete and graduated sensors
// Cogni2 New interest derivation for experiences, new expected interest
// Cogni3 27th July 07, Each Habit has its own expected interest
// In here I worked on lines
// Cogni5 Sept 07, Reworking multiple sensors with graduated values
// Cogni6 Oct 12, 07, New S-Habit matching and find difference, multi-sensors
// Cogni7 Oct 28, 07, Multi-sensors
// Cogni8 Nov 16, 07, Use recency to solve which S-Habit to attend to. Change
// action selection strategy, use FindInstead, not FindDifference
// Cogni9 Nov 25, 07, Bucket stimuli readings, Change as a stimulus
// Grad1 Dec 14, 07, Graduated sensors, S-Habits use LTM pointers
// Grad2 Feb 4, 2008, sequences of graduated stimuli - C-Habits, generalization
// Grad3 Feb 14, 2008, Change as stimulus, new S-Habit structure
// Grad4 Feb 26, 2008, new S-Habit structure
// Grad5 Mar 9, 2008, new S-Habit structure
// Grad6 April 2008, Remove Change as a stimulus - objects represent the changes experienced
// In here I worked on lines and developed course 447
// Grad7 Jan 2009, Subconscious action habits, Interest levels
// Grad8 Feb 2009, new S-Habit structure changes
// Grad9 Mar 20, 2009, Overlapping parts of S-habits, add line recognition from Sense1
// Ideas1 April 18, 2009, Add change objects, get thinking working and upto testcase #25
// Ideas2 May 19, 2009, Use tree of sense stimuli and P-habits - not on S-List
// Ideas3 June 17, 2009, Finish conversion of S-List, Conscious Habit rework, attention alg.
// Ideas4 July 8, P-Habits
// Ideas5 July 10, Remove context processing, ignore repeating S-Habits,
// Ideas6 Aug 2, Incorporate new line recognition, Where and Order processing
// Ideas7 Sept 1st, Partial trigger matching - generalization
// Ideas8 Sept 15th, Graduated readings, 8th Dec new recognition routines, Change Reading Object
// Ideas9 Dec 15th, Separation object
// Change1 Dec 31st, Save Change objects in LTM, Add STM for sequences
// Change2 Jan 10th, 2010 create SepRdgObj, remove LTM Separs(), move STM process
// Change3 Feb 2nd, STM processing, new line recognition, sequence recognition
// Change4 May 2nd, New LTM episodic memory representation, new STM
// Change5 May 26th, Sequence and Action LTM separated
// Change6 Jun 13th, new Where obj, STM per Sense & Sensor if independent
// Change7 Jun 23rd, Interest on sequences in STM, T-List
// Change8 Jul 4th, P-Habits in STM, Body and World changes
// Change9 Jul 20th, A_Sequences implemented, Fix STM S-habit recognition / distraction
// Active1 Jul 31st, Boredom and sub-conscious A-Habits
// Active2 Aug 12th, Conscious STM and/or A-Habits
// Active3 Sept 21st, New Sequence recognition, Conscious STM
// Active4 Oct 7th, Action Habits(practicing & doing), remove partial sequential match,
// Convert interest into a property of all binons
// Active5 Nov 4th, New binon structure, thinking
// Active6 Dec 7th, Another new binon structure, fix partial match, remove reset interest
// Active7 Dec 17th, Separate Change and Interest, reduce interest upon repetition, no concentration
// Active8 Jan 22nd, 2011 remove permanent, remove current habit, separate S-habit and A-Habits
// Active9 Feb 12th, New binon structure, P-habits before Sequences, better attention
// Expect1 Mar 6th, Expect Interesting, new A-Habit structure, remove dependence concept
// Expect2 Mar 23rd, Changed DoIt structure, Experiences in STM, Conscious Seq's in STM
// Expect3 Apr 9th, New Acton structure, sequential trigger and goal recognition, removed
// Novel and Fresh concepts
// Expect4 May 3rd, Add device stimuli, Unexpected, New Acton structure
// Expect5 Aug 2nd, Action habits, STM changes
// Expect6 Sept 4th, STM just recognizes (no expectations), remove orient actons, directed
// attention on expected goal
// Expect7 Sept 20th,Added UnInteresting
// Expect8 Oct 4th, New acton structure
// Expect9 Oct 16th, P-Habits, kinesthetic sense fixed, formation of combo by A-Habit?
// Practic1 Nov 7th, Sequences and Action Habits
// Practic2 Nov 15th, STM processing and Permanent
// Practic3 Dec 12th, Before and after conscious STMs, S-Level 1 stimuli familiar
// Practic4 Jan 10th, STMs do not create A-Habits, Practice mode - redo-interest
// Practic5 Jan 31st, Practice and Goal Actons, STM processing conscious sequences
// Practic6 Feb 15th, P-Habit processing, Directed Attention, sequences of permanent stimuli
// Practic7 Mar 14th, brought in new pattern recognition
// Practic8 Apr 7th, new novel/familiar combinations and STM processing, P-Habits working
// Practic9 Apr 24th, generalization for 2 senses
// General1 May 23rd, Incorporate new Object Recognition (twice)
// General2 July 1st, Practice and Thinking, Redo versus goal interest, Random next responses
// General3 July 11th, A-habits at lowest level first, Unexpected sequential interest
// General4 July 23rd, Expectation inhibits familiar from attention, should binons come with
// habituation of a repeat sequence built in?
// General5 12th Jan 2017 - started to document it - going to insert PerceptionAction from Act2
// 15th Jan 2017 'Inserted PerceptionAction() and got Inpu_KeyPress(0 and TestCases working with no babbling output.
// 22nd Jan 'adding motor babbling when known action habits are familiar
// 23rd Jan 'thinking and bodies starting to work
// 24th Jan 'adding body #6 with two senses - vision and motion
// 28th Jan 'Got Thinking Approach #1 working
// 29th Jan 'Make Binon type one of the Binon properties
// 30th Jan 'Create P-Habit combinations for any number of senses = properties
// 2018 Aug 29th 'Clean up code before sending to Jianyong
// 31st Aug 'Renamed it Smarty. Continue to clean up the code
// 25th August 2019
// 'renaming percpts, actions etc. to conform with the perception-action hierarchy paper
// DefInt A - Z; //16 bits / 2 bytes
// set to 20%
int JND;
// J = wingdings happy face
final static String Smarty = "J";
// "<"
final static String LeftArrow = chr(239);
// ">"
final static String RightArrow = chr(240);
// "^"
final static String UpArrow = chr(241);
// "v"
final static String DownArrow = chr(242);
// "+" - unused
String FourWay;
// "Smarty0" The initial / default Body name
String Smarty0;
// Contains the current body being used
String[] BodySetting = new String[22];
// Bodysetting$(0) contains the number of settings in use
// The values in the configure forms when go to Design or Select
String BodyConfig;
// For determining if a change has been made.
// Contain the values read and written to the .BDY file
String[] BodyValue;
// The values on the body configuration forms
// direction body is pointing, 0=East, 1=South, 2=West, 3=North
int BodyPointing;
// direction body is pointing, 0=East, 1=South, 2=West, 3=North
transient final int North = 3;
transient final int East = 0;
transient final int South = 1;
// direction body is pointing, 0=East, 1=South, 2=West, 3=North
transient final int West = 2;
// -------------------------- Senses and Sensors --------------------------
// The number of physical senses, Max of 10, dynamically set in SetUpSense()
int NumSenses;
// Currently equals the NumProperties since each sense currently = 1 property type
// Maximum number of senses = max 10 physical senses
int MaxSenses;
// 1, Flag for Senses versus Devices
int IsSense;
// unused String StringSense; //Names of senses, up to 10 physical senses - assigned in SetupSense()
// Properties of the different senses
int[][] Senses = new int[10 + 1][8 + 1];
// 1st index = Sense number
// 2nd index = Sense property
// A string of the possible symbolic stimuli for the sensor
String[] SensorStimuli = new String[10 + 1];
// ---- Senses() - 2nd index values - Sense Properties - same used for Devices below
// 1, Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin
int PropertyBinonType;
// 2, Symbolic or Magnitude indicator
int SymbolicOrMagnitude;
// 3, Lower limit of range of values, zero is minimum (65 = "A")
int LowerRangeLimit;
// 4, Upper limit of range of values, 255 is maximum (90 ="Z")
int UpperRangeLimit;
// 5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360)
int LinearOrCircular;
// 6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
int IntegersOrLogs;
// 7 Number of sensors in sensor array
int NumberOfSensors;
// 8 are sensors adjacent (dependent) or independent
int SensorsDependentOrIndependent;
// 1, Indicates that the values from this sense are symbolic, range A -> Z
int Symbolic;
// 2, Indicates that the values from this sense are numeric, integers, range 0 -> Limit
int Magnitude;
// 1, Indicates that the values go from the lower limit to upper limit
int Linear;
// 2, Indicates that the values rap around from the upper limit to 0
int Circular;
// 1, Indicates that the values are integer readings
int IntegerValues;
// 2, Indicates that the values are already logs - orders of magnitude
int LogValues;
// 1, Sensors in array are beside each other (adjacent)
int Dependent;
// 2, Sensors are not associated with each other
int Independent;
// -------------------- Values of stimuli from senses / sensors ------------------------------
// Stimulus values from senses/sensors
int[][][] SensorValues = new int[10 + 1][2 + 1][1 + 1];
// 1st index is sense number, currently = property /sense binon type
// 2nd index is what type of information is in the SensorValues(), XQCnt or Valu
// 3rd index is Fired for the most recent stimulus value and Current for the previous
// ---- SensorValues 2nd index values - type of information in SensorValues()
// =1, the value for the stimulus, if symbolic then value = Asc(Symbol$)
int Valu;
// =2, the count of times the value has repeated, also used below
int XQCnt;
// "_", The character used when no letter provided for the IDL value of a TextBin binon
String NoName;
// World.MoveDown() etc set this to indicate the direction the robot moved
String Motion;
// "-" to indicate there was no motion in the Motion$ stimulus value
String NoMove;
// "-flrb..." 'will contains the possible wheel motions
String WheelMovement;
// WheelMovement$ = "-flrb" & TurnRght$ & TurnLft$ & TurnArnd$ ' rotate right, left and around 180 degrees
String ABlock;
// a block, Chr$(219) is a black square in Terminal font
static final String Wall = chr(219);
// Chr$(177) is a fuzzy square in Terminal font
static final String EmptySquare = chr(177);
// ---- SensorValues 3rd index values - which past stimulus it is - also used below
// =0 'stimulus put in this level upon firing before being processed
int Fired;
// =1 'The Fired one becomes the Current one after processing
int Current;
// -------------------- Devices ------------------------------------------------
// Number of output devices - max 4 - dynamically set in SetupDevice()
int NumDevices;
// Maximum number of devices = max 4 devices
int MaxDevices;
// Names of device, up to 4 devices - assigned in SetupDevice()
String[] Device = new String[4 + 1];
// 2, Flag for Devices versus Senses
int IsDevice;
// Properties of the output / response devices
int[][] Devices = new int[4 + 1][6 + 1];
// 1st index = Device number
// 2nd index = Device property
// A string of the possible symbolic responses for the device
String[] DeviceResponses = new String[4 + 1];
// ---- Devices() - 2nd index values - Device Properties - DEFINED ABOVE
// Public PropertyBinonType '1, Response property binon type e.g. 1 = LetrBin
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator
// Public LowerRangeLimit '3, Lower limit of range of response values, zero is minimum (97 = "a")
// Public UpperRangeLimit '4, Upper limit of range of response values, 255 is maximum (122 = "z")
// Public LinearOrCircular '5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Motor rotations are Circular (0 to 360)
// Public IntegersOrLogs '6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
// Public Symbolic '1, Indicates that the values for this device are symbolic, Range a -> z
// Public Magnitude '2, Indicates that the values for this device are numeric, integers, range 0 -> limit
// Public Linear '1, Indicates that the values go from the lower limit to upper limit
// Public Circular '2, Indicates that the values rap around from the upper limit to 0
// Public IntegerValues '1, Indicates that the values are integer readings
// Public LogValues '2, Indicates that the values are already logs - orders of magnitude
// -------------------- Values of responses to devices ------------------------------
// Response values for devices
int[][] DeviceValues = new int[4 + 1][2 + 1];
// 1st index is device number, currently = response property binon type
// 2nd index is what type of information is in the DeviceValues(), XQCnt or Valu
// ---- DeviceValues 2nd index values - type of information in DeviceValues() - DEFINED ABOVE
// Public Valu '=1, the value for the response, if symbolic then Symbol$ = Chr$(value)
// Public XQCnt '=2, the count of times the value needs repeating, also used below
// "-", The character representing no response for a LetrBin binon
transient final char NoResp = '-';
// c Public Relax$ '"-", used for a Relaxing response - currently the same as NoResp$
// and it is used as the stimulus input of the Motion sense
// If it is false then Smarty displays as an O else it displays as ^>1 means it has more than one goal
int TriggerCount;
// Used for prediction reliability, may be set >1 if needs to be combined with previous
// 12, points to the linked list of target binons [Targets()]
int GoalList;
// for which this binon is the right source binon (not the left source binon)
// 13, Count of its sequential left targets, >1 means can not predict its trigger
int GoalCount;
// Used for reliability of determining the cause, may be set >1 if needs to be combined with next
// 14, Action (Percept - Act) or Attention (Act - Percept) level 1 Sequential binon
int AE;
// -1, Indicates the O1 or O2 pointer is not pointing to another binon
int NullObject;
// ---- Interest values for Binons(x, IntVl) - must be numeric for comparison purposes
// New - 1st time experienced - attention paid to it
// ---- Interest values for Binons(x, IntVl) - must be numeric for comparison purposes
// 3 New - 1st time experienced - attention paid to it
final int NOVEL = 3;
// To indicate it has been experienced for the second time
// 2 To indicate it has been experienced for the second time
final int INTERESTING = 2;
// Neutral, experienced 2 or 3 or more times
// 1 Neutral, experienced 2 or 3 or more times
final int FAMILIAR = 1;
// -1 Interest not known yet
int NoInterest;
// 2 or 3 - number of interest levels, 2= Novel and Familiar, 3= Novel, Interesting, and Familiar
int InterestLevels;
// ---- Sequential or Parallel property values for Binons(x, SP)
// -1
int Sequential;
// +1
int Parallel;
// ---- Action or Attention property values for Binons(x, AE) - value = 0 for Parallel Percepts
// 1
int Action;
// 2
int Attention;
// ---- BinonType property values for Binons(x, BType)
// with 2 senses and 1 device this is =6, 4 senses & 4 devices = 33
int MaxBinonTypes;
// = 2^N+1, number of property binons, Percept combination binon types, Action type and
int NumBinonTypes;
// the D-Habit response types - set dynamically based on SetupSense() and SetupDevice()
// The names and abbreviations for the various binon types
String[][] BinonTypeName = new String[68 + 1][2 + 1];
// ---- BinonTypeName$() 2nd index values
// 1
int BinName;
// 2
int BinAbbreviation;
// The source types of property binons are 1=TextBin, 2=ContBin. There are N of these
// and all other Percept combinations such as Name&Cont.
// There are 2^N-1 Property plus Percept types
// There is just the one Action type - a sequential combination of the
// Property binons, Percept binons, response D-Habit binons and/or Action binons.
// The binon types for stimuli (Percepts 15), ActBin (1) and responses (D-Habits 15)
int[][] BinonTypes = new int[68 + 1][1 + 2];
// 1st index = the type of binon (dimension = NumBinonTypes)
// 2nd index = binon type property
// ---- BinonTypes() - 1st Index values - stimulus and response binon types
// Binon type for Actions, Expectations, percepts, and action binons = NumPercepts + 1. Dynamically set
int ActBin;
// N=4, The number of stimulus property binon types - currently one property per sense
int NumProperties;
// 0, Indicates the type not set, binon will be NullObject
final int NullType = 0;
// ---- BinonTypes() 2nd index values
// 1, Pointer points back to sense or device
int SensOrDevNum;
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator - defined above
// -------------------- Percept Stimuli Perceived ---------------------------------------
// the source binons for the Percepts() tree (only uses = Numsenses=NumProperties)
int[] SensedBinons = new int[1 + 10];
// N=63, The number of property binons and Percept combinations of them 2^NumProperties-1
int NumPercepts;
// =63 currently = (2^6)-1 would need to be (2^10) if 10 sensors
int MaxPercepts;
// Current and Fired Property binon and Percept IDs and XQ count
int[][][] Percepts = new int[1 + 63][1 + 2][2];
// 1st index is the property / Percept binon type (dimension = NumPercepts)
// 2nd index is what type of information is in the Percepts()
// 3rd index is Fired=0 or Current=1
// ---- Percepts 2nd index values - type of information in Percepts()
// =1, the 2nd index value for the binon ID - defined / used below
int BinId;
// Public XQCnt '=2, the count of times the fired binon has been recognized / fired - DEFINED ABOVE
// pointers to the lower level Percepts that are used in forming this Percept
int[][] PerceptSources = new int[1 + 63][1 + 3];
// ---- PerceptSources() 2nd index values
// =1, the first / left source Percept binon
int FirstSource;
// =2, the second / right source Percept binon
int SecondSource;
// =3, The level in the Percept tree
int PerceptLevel;
// -------------------- Left and Right Targets ---------------------------------------
// --- Linked List of Target Binons - for all binons -------------
// The number of Target binon entries created so far
int NumTargets;
// 10000 = the max number of Target binon entries possible
int MaxTargets;
// pointed to by Binons(ID, TriggerList) or by Binons(ID, GoalList)
int[][] Targets = new int[1 + 10000][1 + 2];
// ---- Targets' 2nd index property values
// 1 = The pointer to the next Targets() entry in this linked list,
int NLnk;
// may be a NullTarget at end of linked list
// 2 = a left or right Target binon
int TargetBinon;
// =0, an NLnk pointer at end of linked list
int NullTarget;
// -------------------- D-Habit Response Produced ---------------------------------------
// unused int[] RespondedBinons = new int[1 + 2]; //the response binons for the DHabits() tree (only uses = NumDevices=NumResponses)
// N=15, The number of response binons and D-Habit combinations of them 2^NumDevices-1
int NumDHabits;
// unused int MaxDHabits; //=15 currently = (2^4)-1
// unused int[][][] DHabits = new int[1 + 15][1 + 2][1 + 1]; //Current and Fired Property binon and Percept IDs and XQ count
// 1st index is the property / Percept binon type (dimension = NumPercepts)
// 2nd index is what type of information is in the Percepts()
// 3rd index is Fired=0 or Current=1
// ---- Percepts 2nd index values - type of information in Percepts()
// Public BinId '=1, the 2nd index value for the binon ID - defined above
// Public XQCnt '=2, the count of times the fired binon has been recognized / fired - DEFINED ABOVE
// -------------------- Action Stimuli Perceived ---------------------------------------
// The highest level with any binons in it in STM
int TopLevel;
// The highest STM() entry produced / fired per cycle
int HighestPerceptLvl;
// =25, The highest level of complexity to which the tree can grow
int MaxLevels;
// STM current history of Patterns - a tree with parts at level 1
int[][][] STM = new int[25 + 1][3 + 1][25 + 1];
// 1st index is the stimulus object level
// 2nd index =1 for binon type, =2 for binon ID, =3 for XQCnt, =4 for TQCnt
// 3rd index = Fired = 0 for the just fired stimulus
// = Current = 1 for the Current perceived stimuli
// They can all be expecting a repeat or a changed / different value
// = Last one whose position is the last STM entry that has something in it
// ---- STM 2nd index values - type of information in STM()
// Public BinId '=1, the binon ID - DEFINED ABOVE
// Public XQCnt '=2, the count of times the fired binon has been recognized / fired / repeated - Defined above
// =3, the count of times its trigger fired for repeat size comparison
int TQCnt;
// ---- STM 3rd index values - which past stimulus is it - DEFINED ABOVE
// Public Fired '=0 'stimulus put in this level upon firing before being processed
// Public Current '=1 'The fired one becomes the current one after processing
// Move right amount to eliminate previous pattern - set in ProcessSTMLevel()
int MoveAmount;
// --------------------- Conscious Binons -----------------------------------------
// predicting/expecting the next binon as the goal. May have 0, 1 or more associating binons.
int PerceivedBinon;
// -------------------- Long Term Memory (LTM) - Monitoring Info. -------------------------
// For Display purposes only by Adapt.DUMPLTM in Adapt.LTMem
// Long term memory contains a list of the stimuli that have been paid attention to.
// It stores Perceptual sequences as a pair of sequential memory locations.
int[][] LTMEMORY = new int[2000 + 1][8 + 1];
// 1st index is StoreAt cycle number
// 2nd index is what type of information is in the LTM
// ---- LTMEMORY() 2nd index values - type of information in LTMEMORY()
// 1 Percept binon type
int LtmPerceptTyp;
// 2 Percept binon
int LtmPerceptBin;
// 3 Type of ES Binon - may be an S
int LtmESType;
// 4 ES Actbin
int LtmESActBin;
// 5 Type of AR Binon - may be an R
int LtmARType;
// 6 AR ActBin
int LtmARActBin;
// 7 Action binon type
int LtmActionTyp;
// 8 Action binon
int LtmActionBin;
// LTM POSITION OF LAST STIMULUS - location in LTMEMORY() - incremented by PerceptionAction()
int StoreAt;
// 2000
int MaxMemory;
// ----------------------Input/Output History ----------------------------------------
// For display by Adapt.HISTORYDISPLAY in Adapt.IO
// INPUT history - List of sense stimuli for each sense (1 to 10)
String[][] INPUTS = new String[2000][10 + 1];
// OUTPUT history - List of Responses for each device (1 to 4)
String[][] OUTPUTS = new String[2000][4 + 1];
// -------------------- Other Variables ------------------------------------------
// 1.2 for a 20% just noticeable difference
double SizeBase;
// If it is 2.0 then that is a 100% just noticeable difference
double IntensityBase;
// -------------------- Operational Values - Adaptron --------------------
String ASpace;
// char SequentialSign = first(unicode_rightPointingTriangle()); //Chr$(16) ">"
transient char SequentialSign = '>';
// "+" was Chr$(186) two vertical lines was "/"
String ParallelSign;
// True if create all combinations
boolean CreateAll = false;
// False if use only familiar parts
// ********* Counters, Temporary values, Flags and Pointers ******
// ---------------------- Operational Values -------------------------------
int Normal;
int Happy;
int Unhappy;
// Used as ActTypes for body display
int PartMatch;
// unused boolean PracticeMode; //Practicing the PracticeActon. Still performing it.
// When finished in PracticeMode then we switch to GoalMode.
// unused Public PracticeActon; //The acton that is being practiced
// static Public ActiveActon; //The highest level active acton being done subconsciously
// If set then this is being done subconsciously (not being practiced)
// static Public DoingAct1; //The Act is being done even though it is not being practiced
// This does not include the do Relax act
// unused Public GoalExpected; //Goal expected by Action started - to measure success or failure
// = 0 if no expectation because doing reflexive response
// unused Public GoalSoFar; //Keeps track of the part of the expected goal obtained so far
// unused boolean GoalMode; //Concentrating on the goal of the action being practiced.
// We have finished the acton execution.
// If set it will cause directed attention to the GoalExpected
// unused Public ExpectedGoal; //Goal expected for thinking about
// unused Public TraceGoal; //Used for Trace - The goal we are either trying to achieve or avoid
// unused Public MATCHUSE; //Trigger match Action in Actons() that is interesting to do
// unused Public ActionDesire; //Interest in the MATCHUSE entry for AttendTo
// unused Public PartialMATCHUSE; //same as MATCHUSE but for partial matches
// unused Public PartialActionDesire;
// unused Public PartialTrigger; //set to the partial trigger object if partial trigger true
// unused boolean ThoughtUsed;
// set true if last response was reactive / reflex
boolean DoingReaction = false;
// set true if repeating a known response as a reflexive reaction
boolean DoingRepeat = false;
// Last reflexive response used from Acts list
int LastAct;
// unused Public NextAct; //The next output act for reflexive response from Acts()
// unused Public ResponseOutput; //The one output in this cycle for storing in LTM trace
// unused Public Recency;
// unused boolean PracticeIt; //Global because used in Trace()
// unused boolean DoIt; //Global because used in Trace()
// unused boolean React; //Global because used in Trace()
// Count of how many stimuli have been input/output in INPUTS$() and OUTPUTS$()
int LIN;
// unused boolean FreezeSList; //When true don't do the DUMPSTIMS any more
// Count of inputs for display of history
int COUNTIN;
// The list of recent .WLD files created - kept in RecentWldList.TXT
String[] RecentWorld = new String[4];
// The list of recent .BDY files created - kept in RecentBdyList.TXT
String[] RecentBody = new String[4];
// Either, Running World or just Started
int OperatingMode;
int Running;
int Started;
// ********* Counters, Temporary values, Flags and Pointers ******
// unused Public I, J, T, M, H, N, K, P, F, S, Hab;
// unused Public ThoughtDesire;
char vbDblQuote;
// --------------- Colours --------------
int Black;
int White;
int LightBlue;
int DarkBlue;
// End of (Declarations)
public void Initialize_Adaptron() {
// Called only once from World form when it loads, World.Form_Load()
// Initialize all values that don't change
FourWay = chr(170);
// The initial / default Body name
Smarty0 = "Smarty0";
// sets the inital values in BodySetting$()
InitBodySettingsToSmarty0();
// -------------------------- Senses and Sensors --------------------------
// max no. of physical senses possible in Values$ arrays
MaxSenses = 10;
// Flag for Senses versus Devices
IsSense = 1;
// ---- Senses() and Devices() - 2nd index values - Sense and device Properties
// Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin
PropertyBinonType = 1;
// Symbolic or Magnitude indicator
SymbolicOrMagnitude = 2;
// Lower limit of range of values, zero is minimum (65 = "A")
LowerRangeLimit = 3;
// Upper limit of range of values, 255 is maximum (90 ="Z")
UpperRangeLimit = 4;
// Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360)
LinearOrCircular = 5;
// Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
IntegersOrLogs = 6;
// Number of sensors in sensor array
NumberOfSensors = 7;
// Are sensors adjacent (dependent) or independent
SensorsDependentOrIndependent = 8;
// Indicates that the values from this sense are symbolic, range A -> Z
Symbolic = 1;
// Indicates that the values from this sense are numeric, integers, range 0 -> Limit
Magnitude = 2;
// Indicates that the values go from the lower limit to upper limit
Linear = 1;
// Indicates that the values rap around from the upper limit to 0
Circular = 2;
// Indicates that the values are integer readings
IntegerValues = 1;
// Indicates that the values are already logs - orders of magnitude
LogValues = 2;
// Sensors in array are beside each other (adjacent)
Dependent = 1;
// Sensors are not associated with each other
Independent = 2;
// -------------------- Values of stimuli from senses / sensors ------------------------------
// ---- SensorValues 2nd index values - type of information in SensorValues()
// the value for the stimulus, if symbolic then value = Asc(Symbol$)
Valu = 1;
// the count of times the value has repeated, also used below
XQCnt = 2;
// The character used when no letter provided for the IDL value of a TextBin binon
NoName = "_";
// a # for internal use to indicate a block at the location
ABlock = "#";
// ---- SensorValues 3rd index values - which past stimulus it is - also used below
// stimulus put in this level upon firing before being processed
Fired = 0;
// The Fired one becomes the Current one after processing
Current = 1;
// -------------------- Devices ------------------------------------------------
// Maximum number of devices = max 4 devices
MaxDevices = 4;
// Flag for Devices versus Senses
IsDevice = 2;
// "z" indicates Smarty does not have this move ability
NoMoveOrTurn = "z";
// rotate right, left and around 180 degrees
WheelMovement = "-flrb" + TurnRght + TurnLft + TurnArnd;
// "-" to indicate there was no motion in the Motion$ stimulus value
NoMove = WheelMovement.substring(0, 1);
// -------------------- The Stimulus Objects (Binons) -------------------------
// Max number of binons per type
MaxBinons = 5000;
// with 2 senses and 1 device this is =5
MaxBinonTypes = 68;
// ---- BinonTypeName$() 2nd index values
BinName = 1;
BinAbbreviation = 2;
// ---- BinonTypes() 2nd index values
// Pointer points back to sense or device
SensOrDevNum = 1;
// SymbolicOrMagnitude = 2 ' Symbolic or Magnitude indicator - initialized above
// -------------------- Percept Stimuli Perceived ---------------------------------------
// currently based on maxsenses=5 senses=number of property types
MaxPercepts = 63;
// ---- Percepts() 2nd index values - type of information in Percepts()
// the 2nd index value for the binon ID - defined / used below
BinId = 1;
// XQCnt = 2 ' the count of times the fired binon has been recognized / fired - DEFINED ABOVE
// ---- PerceptSources() 2nd index values
// the first / left source Percept binon
FirstSource = 1;
// the second / right source Percept binon
SecondSource = 2;
// The level in the Percept tree
PerceptLevel = 3;
// ---- Binons() Properties - 2nd index values
// The type of binon
BType = 1;
// Left source binon pointer
O1 = 2;
// the count of times the trigger has fired
TQ = 3;
// Right source binon pointer
O2 = 4;
// the number of times the goal has fired
GQ = 5;
// The ratio value of the binon
IDL = 6;
// Interest Value (NOVEL, INTERESTING, or Familiar)
IntVl = 7;
// Level of object = number of lowest level parts involved
OLv = 8;
// Sequential or Parallel property
SP = 9;
// points to the linked list of right target binons [Targets()]
TriggerList = 10;
// Count of its sequential right targets, >1 means it has more than one goal
TriggerCount = 11;
// points to the linked list of left target binons [Targets()]
GoalList = 12;
// Count of its sequential left targets, >1 means can not predict its trigger
GoalCount = 13;
// Action (Stimulus - Response) or Attention (Response - Stimulus) level 1 Sequential binon
AE = 14;
// Indicates the O1 or O2 pointer is not pointing to another binon
NullObject = -1;
// Interest not known yet
NoInterest = -1;
// 2 or 3 - number of interest levels, 2= Novel and Familiar, 3= Novel, Interesting, and Familiar
InterestLevels = 2;
// ---- Sequential or Parallel property values for Binons(x, SP)
Sequential = -1;
Parallel = 1;
// ---- Action or Attention property values for Binons(x, AE)
Action = 1;
Attention = 2;
// --- Linked List of Target Binons - for Percepts and Actions -------------
// = the max number of Target binon entries possible
MaxTargets = 10000;
// ---- Targets' 2nd index property values
// = The pointer to the next Targets() entry in this linked list,
NLnk = 1;
// = a left or right Target binon
TargetBinon = 2;
// an NLnk pointer at end of linked list
NullTarget = 0;
// -------------------- Stimuli Perceived STM() ---------------------------------------
// The highest level of complexity to which the tree can grow
MaxLevels = 25;
// ---- STM 2nd index values - type of information in STM()
// BinId = 1 ' the binon ID - initialized above
// XQCnt = 2 ' the count of times the fired binon has been recognized / fired / repeated - initialized above
// the count of times its trigger fired for repeat size comparison
TQCnt = 3;
// -------------------- Long Term Memory (LTM) - Monitoring Info. -------------------------
LtmPerceptTyp = 1;
LtmPerceptBin = 2;
LtmESType = 3;
LtmESActBin = 4;
LtmARType = 5;
LtmARActBin = 6;
LtmActionTyp = 7;
LtmActionBin = 8;
MaxMemory = 2000;
// ---------------------- Operational Values -------------------------------
ASpace = " ";
// Was Chr$(186), 'was "/"
ParallelSign = "+";
// Used as ActTypes for body display
Normal = 0;
Happy = 1;
PartMatch = 2;
Unhappy = 3;
// = "
vbDblQuote = (char) 34;
Running = 2;
Started = 1;
// Just started so WorldHelp is displayed
OperatingMode = Started;
Black = 0x0;
White = 0xFFFFFF;
LightBlue = 0xFF8080;
DarkBlue = 0xC00000;
// persist changes
change();
}
private static String chr(int c) {
return String.valueOf((char) c);
}
public final void GetTypeInfo(int BinTyp, ISetter BinonTyp, ISetter Rdgs) {
// Returns the names of the BinonTyp$ and Rdg$ for the given BinTyp
// Public BinonTypeName$(1 To 5, 1 To 2) 'The names and abbreviations for the various binon types
// '---- BinonTypeName$() 2nd index values
// Public BinName '1
// Public BinAbbreviation '2
Rdgs.set("");
BinonTyp.set("");
if (BinTyp == NullType) {
BinonTyp.set("Null");
Rdgs.set("~ = ");
} else {
BinonTyp.set(BinonTypeName[BinTyp][BinName]);
Rdgs.set(BinonTypeName[BinTyp][BinAbbreviation] + "= ");
}
}
// End of GetTypeInfo()
public final int BinonTypeOf(int TheBinon) {
int tempBinonTypeOf;
if (TheBinon == NullObject) {
tempBinonTypeOf = NullType;
} else {
tempBinonTypeOf = Binons[TheBinon][BType];
}
return tempBinonTypeOf;
}
// End of BinonTypeOf()
public final void GetValue(int OOO, Var v) {
// Returns the value for the object based on its Type
int Readng;
int TheBinon;
int LeftBinon;
// Recursive routine to add values to V$ for any binon/object
if (OOO == NullObject) {
return;
}
// VB TO JAVA CONVERTER NOTE: The following VB 'Select Case' included either a non-ordinal switch expression or non-ordinal, range-type, or non-constant 'Case' expressions and was converted to Java 'if-else' logic:
// Select Case BinonTypeOf(OOO)
var tempVar = BinonTypeOf(OOO);
// ORIGINAL LINE: Case ActBin //Public ActBin = sequential - action = NumPercepts+1
if (// Public ActBin = sequential - action = NumPercepts+1
tempVar == ActBin) {
TheBinon = OOO;
while (// While we have an Action
BinonTypeOf(TheBinon) == ActBin) {
ping();
LeftBinon = TheBinon;
// Go down the left side to the bottom Property or Percept binon
while (// While we have an Action
BinonTypeOf(LeftBinon) == ActBin) {
ping();
// Get the left source part
LeftBinon = Binons[LeftBinon][O1];
}
// get the property and/or Percept binon
GetValue(LeftBinon, v);
v.set(v.get() + SequentialSign);
// Go to the right side and repeat going down its left side
TheBinon = Binons[TheBinon][O2];
}
// get the last Property or Percept binon on the right side
GetValue(TheBinon, v);
} else // ORIGINAL LINE: Case 1 To NumProperties //Senses / property binon
if (// Senses / property binon
tempVar >= 1 && tempVar <= NumProperties) {
// The binons value
Readng = Binons[OOO][IDL];
if (BinonTypes[BinonTypeOf(OOO)][SymbolicOrMagnitude] == Symbolic) {
if (Readng < 32) {
v.set(v.get() + "~");
} else {
// text
v.set(v.get() + chr(Readng));
}
} else // Else the property is Magnitude
{
// a number
v.set(v.get() + vbToStr(Readng));
}
} else // ORIGINAL LINE: Case NumProperties + 1 To NumPercepts //Percept binons
if (// Percept binons
tempVar >= NumProperties + 1 && tempVar <= NumPercepts) {
TheBinon = OOO;
while (// While we have a Percept
BinonTypeOf(TheBinon) > NumProperties) {
ping();
LeftBinon = TheBinon;
// Go down the left side to the bottom property binon
while (// While we have a Percept
BinonTypeOf(LeftBinon) > NumProperties) {
ping();
// Get the left source part
LeftBinon = Binons[LeftBinon][O1];
}
// get the property binon
GetValue(LeftBinon, v);
v.set(v.get() + ParallelSign);
// Go to the right side and repeat going down its left side
TheBinon = Binons[TheBinon][O2];
}
// get the last Property binon on the right side
GetValue(TheBinon, v);
} else // ORIGINAL LINE: Case ActBin + 1 To NumBinonTypes //A response / device binon
if (// A response / device binon
tempVar >= ActBin + 1 && tempVar <= NumBinonTypes) {
Readng = Binons[OOO][IDL];
if (Readng < 32) {
v.set(v.get() + "~");
} else {
// symbolic
v.set(v.get() + chr(Readng));
}
}
}
// End of GetValue()
public final void RememberResponse(int RespBin, int StoreAtPlace) {
// Save the last response for LTM display
// Public LTMEMORY&(1 To 2000, 1 To 6) -- comment stefan: not really - it's going to 8
// '1st index is StoreAt cycle number
// '2nd index is what type of information is in the LTM
//
// '---- LTMEMORY() 2nd index values - type of information in LTMEMORY()
// Public LtmPerceptTyp '1 Percept binon type
// Public LtmPerceptBin '2 Percept binon
// Public LtmESType '3 Type of ES Binon - may be an S
// Public LtmESActBin '4 ES Actbin
// Public LtmARType '5 Type of AR Binon - may be an R
// Public LtmARActBin '6 AR ActBin
// Public LtmActionTyp '7 Action binon type
// Public LtmActionBin '8 Action binon
LTMEMORY[StoreAtPlace][LtmActionTyp] = BinonTypeOf(RespBin);
LTMEMORY[StoreAtPlace][LtmActionBin] = RespBin;
}
// End of RememberResponse()
public final void RememberStimulus(int TrigObj, int StoreAtPlace) {
// Save the given relationship / association in LTM for display
// Public LTMEMORY&(1 To 2000, 1 To 6)
// '1st index is StoreAt cycle number
// '2nd index is what type of information is in the LTM
//
// '---- LTMEMORY() 2nd index values - type of information in LTMEMORY()
// Public LtmPerceptTyp '1 Percept binon type
// Public LtmPerceptBin '2 Percept binon
// Public LtmESType '3 Type of ES Binon - may be an S
// Public LtmESActBin '4 ES Actbin
// Public LtmARType '5 Type of AR Binon - may be an R
// Public LtmARActBin '6 AR ActBin
// Public LtmActionTyp '7 Action binon type
// Public LtmActionBin '8 Action binon
LTMEMORY[StoreAtPlace][LtmPerceptTyp] = BinonTypeOf(TrigObj);
LTMEMORY[StoreAtPlace][LtmPerceptBin] = TrigObj;
}
// End of RememberStimulus()
public final void SetupSense(int SenseNum, String Sense_Name, String BinonName, String BinonAbbrev, int MagnOrSymb, int LowerLimit, int UpperLimit, String Stimuli, int LinOrCirc, int IntOrLog, int NumSensrs, int SensorDependency) {
printVars_str("SetupSense", "SenseNum", SenseNum, "Sense_Name", Sense_Name, "NumSensrs", NumSensrs);
// If the SenseNum passed in is zero this routine returns the Sense number (SenseNum)
// for the given Sense, else it modifies the given SenseNum
// The range or number of sensors is NumSensrs - max 256
// IntensityRange: is the range or number of intensity values for the sensors
// Stimuli$: is a string of possible stimuli for this sensor - saved in SensorStimuli$()
// Sense_Name$: is the name of the sense
// MagnOrSymb: = Magnitude if each sensor measures a Magnitude range of intensity
// = Symbolic if each sensor provides readings that are symbolic.
// LinOrCirc: = Linear
// = Circular
// unused String Ssr = null;
int UseSense;
// unused String SG = null;
int Sns;
var BinTypNum = new Var<>(0);
String DisplayStimuli;
// Public NumSenses 'The number of physical senses, Max of 8
// 'Currently equals the NumProperties since each sense currently = 1 property type
// Public MaxSenses 'Maximum number of senses = max 8 physical senses
// Public Sense$(1 To 8) 'Names of senses, up to 8 physical senses
//
// Public Senses[1 To 8][1 To 6] 'Properties of the different senses
// '1st index = Sense number
// '2nd index = Sense property
// Public SensorStimuli$(1 To 10) 'A string of the possible symbolic stimuli for the sensor
//
// '---- Senses() - 2nd index values - Sense Properties
// Public PropertyBinonType '1, Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator
// Public LowerRangeLimit '3, Lower limit of range of values, zero is minimum (65 = "A")
// Public UpperRangeLimit '4, Upper limit of range of values, 255 is maximum (90 ="Z")
// Public LinearOrCircular '5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360)
// Public IntegersOrLogs '6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
// Public NumberOfSensors '7 Number of sensors in sensor array
// Public SensorsDependentOrIndependent '8 are sensors adjacent (dependent) or independent
//
// Public Symbolic '1, Indicates that the values from this sense are symbolic, range A -> Z
// Public Magnitude '2, Indicates that the values from this sense are numeric, integers, range 0 -> Limit
//
// Public Linear '1, Indicates that the values go from the lower limit to upper limit
// Public Circular '2, Indicates that the values rap around from the upper limit to 0
//
// Public IntegerValues '1, Indicates that the values are integer readings
// Public LogValues '2, Indicates that the values are already logs - orders of magnitude
//
if (// Can't assign another new sense number
NumSenses == MaxSenses) {
Stop();
}
// There are only so many senses in SensorValues array
// currently set to 8 in Adaptron.Initialize_Adaptron()
if (// don't have a sense number yet so assign and return it
SenseNum == 0) {
// The new sense number for this sense
NumSenses = NumSenses + 1;
// The returned sense number
SenseNum = NumSenses;
} else if (// else it is more than allowed
SenseNum > MaxSenses) {
Stop();
} else if (// else is it higher than the next one available
SenseNum > NumSenses + 1) {
Stop();
} else if (// else use the one passed in - overriding an existing sense
SenseNum <= NumSenses) {
} else if (// else is it equal to the next one available
SenseNum == NumSenses + 1) {
// which equals NumSenses + 1
NumSenses = SenseNum;
}
UseSense = SenseNum;
if (// only 8 sensors allowed per sense for now - maybe only
NumSensrs > 8) {
Stop();
}
// need this limit if independent sensors
if (// only 256 values allowed for intensity
IntensityRange > 256) {
Stop();
}
Sense[UseSense] = Sense_Name;
Senses[UseSense][SymbolicOrMagnitude] = MagnOrSymb;
Senses[UseSense][LowerRangeLimit] = LowerLimit;
Senses[UseSense][UpperRangeLimit] = UpperLimit;
// If not "" these take preference over the upper and lower limit
SensorStimuli[UseSense] = Stimuli;
if (// Magnitude READINGS
Senses[UseSense][SymbolicOrMagnitude] == Magnitude) {
// can be circular or linear
Senses[UseSense][LinearOrCircular] = LinOrCirc;
// can not have symbolic list
SensorStimuli[UseSense] = "";
} else // Symbolic readings can not be circular
{
// non circular
Senses[UseSense][LinearOrCircular] = Linear;
}
Senses[UseSense][IntegersOrLogs] = IntOrLog;
Senses[UseSense][NumberOfSensors] = NumSensrs;
Senses[UseSense][SensorsDependentOrIndependent] = SensorDependency;
// SetupBinonTypes(SenseOrDeviceNum, BinNam$, BinAbb$, IsASense, BinonTypReturned)
SetupBinonTypes(UseSense, BinonName, BinonAbbrev, IsSense, BinTypNum);
// Currently BinonType = Sense = property binon
Senses[UseSense][PropertyBinonType] = BinTypNum.get();
// and fill in sense info on world page
StringBuilder sensorInfo = new StringBuilder();
for (Sns = 1; Sns <= NumSenses; Sns++) {
ping();
if (Senses[Sns][SymbolicOrMagnitude] == Magnitude) {
DisplayStimuli = StringHelper.trim(String.valueOf(Senses[Sns][LowerRangeLimit]), ' ') + " to" + Senses[Sns][UpperRangeLimit];
} else // symbolic values
{
if (// If no symbolic list then use upper and lower limit
SensorStimuli[Sns].equals("")) {
DisplayStimuli = chr(Senses[Sns][LowerRangeLimit]) + " to " + chr(Senses[Sns][UpperRangeLimit]);
} else {
DisplayStimuli = SensorStimuli[Sns];
DisplayStimuli = replace(DisplayStimuli, NoMoveOrTurn, ASpace);
}
}
sensorInfo.append(takeFirst(8, Sense[Sns] + ": ") + " " + DisplayStimuli + " " + SymbOrMagn(IsSense, Sns) + "\r\n");
}
World.showSensorValues(str(sensorInfo));
}
// End of SetupSense()
private static void Stop() {
Stop("STOP");
}
private static void Stop(String msg) {
throw new RuntimeException(msg);
}
public final // Called from DesignBody.UseThisBody_Click()
void SetupVision() {
int VisionSense;
int MS = 0;
// renamed because of clash with JavaX's LL
int ll = 0;
int UL = 0;
// BodySetting$(7) = VisionConfig.VisionDown
// BodySetting$(8) = VisionConfig.VisionLeft
// BodySetting$(9) = VisionConfig.VisionRight
// BodySetting$(10) = VisionConfig.VisionInFront
// BodySetting$(11) = VisionConfig.VisionBehind
// BodySetting$(12) = VisionConfig.VisionSymbolicOrMagnitude(0)
// BodySetting$(13) = VisionConfig.VisionSymbolicOrMagnitude(1)
// BodySetting$(21) = VisionConfig.VisionSymbolicOrMagnitude(2)
// so a new sense number assigned automatically by SetupSense()
VisionSense = 0;
// Body 1 'Sense #1 looks down at square, Device #1 moves Left, Right, Up, Down
// 'set up Sense #1, 1 sensor
// 'SetupSense(SenseNum, Sense_Name$, BinonName$, BinonAbbrev$, MagnOrSymb, LowerLimit, UpperLimit, _
// LinOrCirc, IntOrLog, NumSensrs, SensorDependency)
// Call SetupSense(InputSense, "Input", "Text", "Tx", Symbolic, 65, 122, Linear, IntegerValues, 1, Independent)
//
// 'SetupDevice(DeviceNum, DName$, BinonName$, BinonAbbrev$, MagnOrSymb, LowerLimit, UpperLimit, _
// Responses$, LinOrCirc, IntOrLog)
// Call SetupDevice(DevNum, "Output", "Letter", "Lt", Symbolic, 97, 100, "", Linear, IntegerValues)
//
// Body 2 'Looks forward at next cell, Turns left, right & moves forward
// 'set up Sense #1, 1 Sensor
// Call SetupSense(InputSense, "Input", "Text", "Tx", Symbolic, 65, 113, Linear, IntegerValues, 1, Independent)
// Call SetupDevice(DevNum, "Output", "Letter", "Lt", Symbolic, 97, 99, "", Linear, IntegerValues)
if (// radio button VisionSymbolicOrMagnitude(0) selected
isTrue(BodySetting[12])) {
MS = Symbolic;
// "A" 1st cell location
ll = 65;
// "z" last possible cell location - actually if 8 x 8 then it is Chr$(129)
UL = 122;
}
if (// radio button VisionSymbolicOrMagnitude(1) selected
isTrue(BodySetting[13])) {
MS = Magnitude;
ll = 1;
// max 8 cells in any direction
UL = 8;
}
if (// radio button VisionSymbolicOrMagnitude(2) selected
isTrue(BodySetting[21])) {
MS = Symbolic;
// Wall$ = Chr$(20) Terminal font
ll = asc(Wall);
// empty square beside it
UL = asc(EmptySquare);
}
if (// Looking down box is checked
eq(BodySetting[7], "1")) {
// SetupSense(SenseNum, Sense_Name$, BinonName$, BinonAbbrev$, MagnOrSymb, LowerLimit, UpperLimit, _
// Stimuli, LinOrCirc, IntOrLog, NumSensrs, SensorDependency);
SetupSense(VisionSense, "VisionD", "VisionD", "VD", MS, ll, UL, "", Linear, IntegerValues, 1, Independent);
}
VisionSense = 0;
if (// Looking left box is checked
eq(BodySetting[8], "1")) {
SetupSense(VisionSense, "VisionL", "VisionL", "Vl", MS, ll, UL, "", Linear, IntegerValues, 1, Independent);
}
VisionSense = 0;
if (// Looking right box is checked
eq(BodySetting[9], "1")) {
SetupSense(VisionSense, "VisionR", "VisionR", "Vr", MS, ll, UL, "", Linear, IntegerValues, 1, Independent);
}
VisionSense = 0;
if (// Looking InFront box is checked
eq(BodySetting[10], "1")) {
SetupSense(VisionSense, "VisionF", "VisionF", "Vf", MS, ll, UL, "", Linear, IntegerValues, 1, Independent);
}
VisionSense = 0;
if (// Looking Behind box is checked
eq(BodySetting[11], "1")) {
SetupSense(VisionSense, "VisionB", "VisionB", "Vb", MS, ll, UL, "", Linear, IntegerValues, 1, Independent);
}
}
// End of SetupVision()
private int asc(String s) {
return empty(s) ? 0 : s.charAt(0);
}
private boolean isTrue(String s) {
return "True".equals(s);
}
public final void SetupTouch() {
}
// End of SetupTouch()
public final void SetupWheels() {
int WheelsDevice;
int MS;
// unused String LL = null;
// unused String UL = null;
StringBuilder WheelResponses;
int MotionSense;
// BodySetting$(14) = WheelsConfig.MoveForward
// BodySetting$(15) = WheelsConfig.MoveLeft
// BodySetting$(16) = WheelsConfig.MoveRight
// BodySetting$(17) = WheelsConfig.MoveBackward
// BodySetting$(18) = WheelsConfig.TurnRight
// BodySetting$(19) = WheelsConfig.TurnLeft
// BodySetting$(20) = WheelsConfig.TurnAround
// BodySetting$(4) = WheelsConfig.AddAWheelSensor
// Body 1 'Sense #1 looks down at square, Device #1 moves Left, Right, Up, Down
// 'set up Sense #1, 1 sensor
// 'SetupSense(SenseNum, Sense_Name$, BinonName$, BinonAbbrev$, MagnOrSymb, LowerLimit, UpperLimit, _
// LinOrCirc, IntOrLog, NumSensrs, SensorDependency)
// Call SetupSense(InputSense, "Input", "Text", "Tx", Symbolic, 65, 113, Linear, IntegerValues, 1, Independent)
//
// Call SetupDevice(DevNum, "Output", "Letter", "Lt", Symbolic, 97, 100, "", Linear, IntegerValues)
//
// Body 2 'Looks forward at next cell, Turns left, right & moves forward
// 'set up Sense #1, 1 Sensor
// Call SetupSense(InputSense, "Input", "Text", "Tx", Symbolic, 65, 113, Linear, IntegerValues, 1, Independent)
// Call SetupDevice(DevNum, "Output", "Letter", "Lt", Symbolic, 97, 99, "", Linear, IntegerValues)
// The device number assigned to the device by SetupDevice()
WheelsDevice = 0;
MS = Symbolic;
// will be filled in with move symbols "-flrb" and turn symbols,
WheelResponses = new StringBuilder("-");
// a "z" for an invalid movement, the "-" for do nothing
// Assume no turning capability, display Smarty as Happy face
WheelsTurn = false;
if (MS == Symbolic) {
for (var I = 14; I <= 20; I++) {
ping();
if (// if it is checked then
eq(BodySetting[I], "1")) {
switch(I) {
case // Forward
14:
WheelResponses.append(MoveForward);
break;
case // Left
15:
WheelResponses.append(MoveToLeft);
break;
case // Right
16:
WheelResponses.append(MoveToRight);
break;
case // Backward
17:
WheelResponses.append(MoveBackward);
break;
case // Turn right 90 degrees
18:
// right angle symbol
WheelResponses.append(TurnRght);
WheelsTurn = true;
break;
case // Turn left 90 degrees
19:
// left angle symbol
WheelResponses.append(TurnLft);
WheelsTurn = true;
break;
case // Turn around 180 degrees
20:
// double arrow symbol
WheelResponses.append(TurnArnd);
WheelsTurn = true;
break;
}
} else {
WheelResponses.append(NoMoveOrTurn);
}
}
}
// the same movements should be recognizable
WheelMovement = WheelResponses.toString();
// Setup a motion sense if WheelsConfig.AddAWheelSensor = 1 is checked
if (eq(BodySetting[4], "1")) {
MotionSense = 0;
// SetupSense(SenseNum, Sense_Name$, BinonName$, BinonAbbrev$, MagnOrSymb, LowerLimit, UpperLimit, _
// Stimuli, LinOrCirc, IntOrLog, NumSensrs, SensorDependency);
SetupSense(MotionSense, "Motion", "Motion", "Mo", Symbolic, 1, 1, WheelMovement, Linear, IntegerValues, 1, Independent);
}
// SetupDevice(DeviceNum, DName$, BinonName$, BinonAbbrev$, MagnOrSymb, LowerLimit, UpperLimit, _
// Responses, LinOrCirc, IntOrLog);
SetupDevice(WheelsDevice, "Wheels", "Wheels", "Wh", MS, 1, 1, WheelResponses.toString(), Linear, IntegerValues);
}
// End of SetupWheels()
public final void SetupArms() {
}
// End of SetupArms()
public // Initialize the BodySetting$() or BodyValue$() to Smarty0 values
void InitBodyToSmarty0(// Initialize the BodySetting$() or BodyValue$() to Smarty0 values
String[] Body) {
// Count of Body$() values
Body[0] = "21";
Body[1] = Smarty0;
// Vision.Value = 1 - checked
Body[2] = "1";
// Touch.Value
Body[3] = "0";
// WheelsConfig.AddAWheelSensor
Body[4] = "0";
// Wheels.Value
Body[5] = "1";
// Arms.Value
Body[6] = "0";
// VisionConfig.VisionDown
Body[7] = "1";
// VisionConfig.VisionLeft
Body[8] = "0";
// VisionConfig.VisionRight
Body[9] = "0";
// VisionConfig.VisionInFront
Body[10] = "0";
// VisionConfig.VisionBehind
Body[11] = "0";
// VisionConfig.VisionSymbolicOrMagnitude(0)
Body[12] = "True";
// VisionConfig.VisionSymbolicOrMagnitude(1)
Body[13] = "False";
// WheelsConfig.MoveForward
Body[14] = "1";
// WheelsConfig.MoveLeft
Body[15] = "1";
// WheelsConfig.MoveRight
Body[16] = "1";
// WheelsConfig.MoveBackward
Body[17] = "1";
// WheelsConfig.TurnRight
Body[18] = "0";
// WheelsConfig.TurnLeft
Body[19] = "0";
// WheelsConfig.TurnAround
Body[20] = "0";
// VisionConfig.VisionSymbolicOrMagnitude(2)
Body[21] = "False";
}
// End of InitBodyToSmarty0()
public void InitBodySettingsToSmarty0() {
InitBodyToSmarty0(BodySetting);
}
public final void InitBodyValuesToSmarty0() {
InitBodyToSmarty0(BodyValue);
}
public final String SymbOrMagn(int SensOrDevc, int SensOrDevcNumber) {
String tempSymbOrMagn;
// called from SetupSense() & SetupDevice()
int SorG;
if (SensOrDevc == IsSense) {
SorG = Senses[SensOrDevcNumber][SymbolicOrMagnitude];
} else // Else SensOrDevc = IsDevice
{
SorG = Devices[SensOrDevcNumber][SymbolicOrMagnitude];
}
if (SorG == Symbolic) {
tempSymbOrMagn = "Symbolic";
} else {
tempSymbOrMagn = "Magnitude";
}
return tempSymbOrMagn;
}
// End of SymbOrMagn$()
public final void SetupBinonTypes(int SenseOrDeviceNum, String BinNam, String BinAbb, int IsASense, Var BinonTypReturned) {
// Called by SetUpSense() and SetupDevice()
// After setting up a sense or device the binontypes() information must be updated correctly
// SenseOrDeviceNum could be one that already exists and is being reset
int BinTypNum = 0;
int PerceptBinTyp;
int DHabitBinTyp;
int FirstPtr;
int SecondPtr;
int ThisPercept;
int StartPercept;
int EndPercept;
int ThisLevel;
// '---- Binons[x][BType] - stimulus and response binon types
// TextBin = 1 ' = A letter (symbolic)
// ContBin = 2 ' = Contrast pattern - intensity (Magnitude)
// 'Parallel combinations should be put in the binons above the property type ones.
// NCBin = 3 ' = TextBin & ContBin combination
// ActBin = 4 ' = 2^N = NumPercepts+1, holds sequential binons.
// LetrBin = 5 ' = Response binon = letters
// ------------------ Property and Percept combinations --------------------------
// The number of combinations at each level of complexity when combining independent senses.
// # of Sensors
// or Senses
// Stimuli @ P-Level 1 2 3 4 5 6 7 8 Total
// 1 1 1
// 2 2 1 3
// 3 3 3 1 7
// 4 4 6 4 1 15
// 5 5 10 10 5 1 31
// 6 6 15 20 15 6 1 63
// 7 7 21 35 35 21 7 1 127
// 8 8 28 56 70 56 28 8 1 255
// N 2^N - 1
// Public NumProperties 'N=2, The number of stimulus property binon types
// Public NumPercepts 'N=3, The number of property binons and Percept combinations of them
// Public NumBinonTypes '= 2^N+1, number of property binons, Percept combination binon types, Action type and
// ' the response type
// Public MaxBinonTypes 'with 2 senses and 1 device this is =5
// Public BinonTypeName$(1 To 31, 1 To 2) 'The names and abbreviations for the various binon types
// '---- BinonTypeName$() 2nd index values
// Public BinName '1
// Public BinAbbreviation '2
// 'The source types of property binons are 1=TextBin, 2=ContBin. There are N of these
// 'and all other Percept combinations such as Name&Cont.
// 'There are 2^N-1 Property plus Percept types
// 'There is just the one Action type - a sequential combination of the
// 'Property binons, Percept binons, response binon and/or Action binons.
// 'Added responses as LetrBin binons so NumBinonTypes = 2^N + 1
// Public BinonTypes[1 To 31][1 To 4] 'The binon types for stimuli, ActBin and responses
// '1st index = the type of binon (dimension = NumBinonTypes)
// '2nd index = binon type property
//
// ---- BinonTypes() 2nd index values
// Public SensOrDevNum '1, Pointer points back to sense or device
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator
if (// If setting up a sense then
IsASense == IsSense) {
if (// if it is an existing sense then resetting it
SenseOrDeviceNum <= NumProperties) {
BinTypNum = SenseOrDeviceNum;
} else if (// else if it is the next new sense then
SenseOrDeviceNum == NumProperties + 1) {
// N=2, The number of stimulus property binon types
NumProperties = SenseOrDeviceNum;
BinTypNum = NumProperties;
// N=3, The number of property binons and Percept combinations of them
NumPercepts = (2 << (NumProperties - 1)) - 1;
for (PerceptBinTyp = NumProperties + 1; PerceptBinTyp <= NumPercepts; PerceptBinTyp++) {
ping();
BinonTypeName[PerceptBinTyp][BinName] = "Percept";
BinonTypeName[PerceptBinTyp][BinAbbreviation] = "Pc";
}
// Setup the PerceptSources() to point at the correct source entries at the level below
// Filling in level 2 Percept information
ThisLevel = 2;
// Position of 1st Percept combination of sense/property binons
ThisPercept = NumProperties + 1;
// Start of range of pairs - level-2 Percepts, level-1 Percepts=property binons
StartPercept = ThisPercept;
for (// Create all the 2nd level pair pointers
FirstPtr = 1; // Create all the 2nd level pair pointers
FirstPtr < NumProperties; // Create all the 2nd level pair pointers
FirstPtr++) {
ping();
for (SecondPtr = FirstPtr + 1; SecondPtr <= NumProperties; SecondPtr++) {
ping();
PerceptSources[ThisPercept][FirstSource] = FirstPtr;
PerceptSources[ThisPercept][SecondSource] = SecondPtr;
PerceptSources[ThisPercept][PerceptLevel] = ThisLevel;
// Next combination Percept will go in here
ThisPercept = ThisPercept + 1;
}
}
// End of range of level-2 Percepts - pairs of property binons
EndPercept = ThisPercept - 1;
// Setup the level-3+ PerceptSources()
while (EndPercept - StartPercept > 0) {
ping();
// populate next level up
ThisLevel = ThisLevel + 1;
for (FirstPtr = StartPercept; FirstPtr < EndPercept; FirstPtr++) {
ping();
for (SecondPtr = FirstPtr + 1; SecondPtr <= EndPercept; SecondPtr++) {
ping();
if (// if share a common sub Percept
PerceptSources[FirstPtr][SecondSource] == PerceptSources[SecondPtr][FirstSource]) {
PerceptSources[ThisPercept][FirstSource] = FirstPtr;
PerceptSources[ThisPercept][SecondSource] = SecondPtr;
PerceptSources[ThisPercept][PerceptLevel] = ThisLevel;
// Next combination Percept will go in here
ThisPercept = ThisPercept + 1;
}
}
}
// Start next range after end of previous range
StartPercept = EndPercept + 1;
// End of range of this level Percepts
EndPercept = ThisPercept - 1;
}
// ActBin holds action and expectation binons = 2^N = NumPercepts + 1
ActBin = NumPercepts + 1;
BinonTypeName[ActBin][BinName] = "Action";
BinonTypeName[ActBin][BinAbbreviation] = "Ac";
// The number of types so far = 2^N
NumBinonTypes = ActBin;
} else {
// no other value allowed
Stop();
}
} else // Else setting up a device
{
if (// If it is an existing device then restting it
SenseOrDeviceNum + ActBin <= NumBinonTypes) {
BinTypNum = SenseOrDeviceNum;
} else if (// else if it is the next new device number then
SenseOrDeviceNum + ActBin == NumBinonTypes + 1) {
// = 2^N+x, number of property binons, Percept combination binon types,
NumBinonTypes = NumBinonTypes + 1;
BinTypNum = NumBinonTypes;
// N=3, The number of device response binons and D-Habit combinations of them
NumDHabits = (2 << (SenseOrDeviceNum - 1)) - 1;
// VB TO JAVA CONVERTER NOTE: The ending condition of VB 'For' loops is tested only on entry to the loop. VB to Java Converter has created a temporary variable in order to use the initial value of ActBin + NumDHabits for every iteration:
var tempVar = ActBin + NumDHabits;
for (DHabitBinTyp = ActBin + 1 + SenseOrDeviceNum; DHabitBinTyp <= tempVar; DHabitBinTyp++) {
ping();
BinonTypeName[DHabitBinTyp][BinName] = "D-Habit";
BinonTypeName[DHabitBinTyp][BinAbbreviation] = "DH";
}
NumBinonTypes = ActBin + NumDHabits;
} else {
// no other value allowed
Stop();
}
}
BinonTypeName[BinTypNum][BinName] = BinNam;
BinonTypeName[BinTypNum][BinAbbreviation] = BinAbb;
// points back to the device number
BinonTypes[BinTypNum][SensOrDevNum] = SenseOrDeviceNum;
BinonTypes[BinTypNum][SymbolicOrMagnitude] = Senses[SenseOrDeviceNum][SymbolicOrMagnitude];
BinonTypReturned.set(BinTypNum);
}
// End of SetupBinonTypes()
public final void SetupDevice(int DeviceNum, String DName, String BinonName, String BinonAbbrev, int MagnOrSymb, int LowerLimit, int UpperLimit, String Responses, int LinOrCirc, int IntOrLog) {
// This routine returns the Device number (DeviceNum) for the given Device type if none is provided
// DName$: is the name of the device type
// IntensityRange: is the range or number of response values for the device if it takes magnitude values
// Responses$: is a string of characters representing the possible movements
// BinonType: The response binon type
int UseDevice;
var BinTypNum = new Var<>(0);
String DisplayResponses;
// -------------------- Devices ------------------------------------------------
// Public NumDevices 'Number of output devices
// Public MaxDevices 'Maximum number of devices = max 8 devices
// Public Device$(1 To 8) 'Names of device, up to 8 devices
//
// Public Devices[1 To 8][1 To 5] 'Properties of the output / response devices
// '1st index = Device number
// '2nd index = Device property
// Public DeviceResponses$(1 To 4) 'A string of the possible symbolic responses for the devices
// ---- Devices() - 2nd index values - Device Properties - DEFINED ABOVE
// Public PropertyBinonType '1, Response property binon type e.g. 1 = LetrBin
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator
// Public LowerRangeLimit '3, Lower limit of range of response values, zero is minimum (97 = "a")
// Public UpperRangeLimit '4, Upper limit of range of response values, 255 is maximum (122 = "z")
// Public LinearOrCircular '5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Motor rotations are Circular (0 to 360)
// Public IntegersOrLogs '6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
// Public Symbolic '1, Indicates that the values for this device are symbolic, Range a -> z
// Public Magnitude '2, Indicates that the values for this device are numeric, integers, range 0 -> limit
// Public Linear '1, Indicates that the values go from the lower limit to upper limit
// Public Circular '2, Indicates that the values rap around from the upper limit to 0
// Public IntegerValues '1, Indicates that the values are integer readings
// Public LogValues '2, Indicates that the values are already logs - orders of magnitude
if (// Can't assign another new device number
NumDevices == MaxDevices) {
Stop("NumDevices == MaxDevices (" + NumDevices + ")");
}
// There are only so many device types in DeviceValues array
// currently set to 8 in Adaptron.Initialize_Adaptron()
if (// don't have a device number yet so assign and return it
DeviceNum == 0) {
// The new device number for this device
NumDevices = NumDevices + 1;
// The returned device number
DeviceNum = NumDevices;
} else if (// else it is more than allowed
DeviceNum > MaxDevices) {
Stop("DeviceNum > MaxDevices (" + DeviceNum + "/" + MaxDevices + ")");
} else if (// else is it higher than the next one available
DeviceNum > NumDevices + 1) {
Stop("DeviceNum > NumDevices+1 (" + DeviceNum + "/" + (NumDevices + 1) + ")");
} else if (// else use the one passed in - overriding an existing device
DeviceNum <= NumDevices) {
} else if (// next device number provided
DeviceNum == NumDevices + 1) {
// The new device type number for this device = DeviceNum
NumDevices = DeviceNum;
}
UseDevice = DeviceNum;
if (// only 256 values allowed for response intensity
IntensityRange > 256) {
Stop("IntensityRange > 256 (" + IntensityRange + ")");
}
Device[UseDevice] = DName;
Devices[UseDevice][SymbolicOrMagnitude] = MagnOrSymb;
// lower limit number / range of response values
Devices[UseDevice][LowerRangeLimit] = LowerLimit;
// upper limit number / range of response values
Devices[UseDevice][UpperRangeLimit] = UpperLimit;
// the symbolic responses
DeviceResponses[UseDevice] = Responses;
if (// Magnitude READINGS
Devices[UseDevice][SymbolicOrMagnitude] == Magnitude) {
// can be circular or linear
Devices[UseDevice][LinearOrCircular] = LinOrCirc;
// no symbolic responses are possible
DeviceResponses[UseDevice] = "";
} else // Symbolic readings can not be circular
{
// non circular
Devices[UseDevice][LinearOrCircular] = Linear;
}
Devices[UseDevice][IntegersOrLogs] = IntOrLog;
// SetupBinonTypes(SenseOrDeviceNum, BinNam$, BinAbb$, IsASense, BinonTypReturned)
SetupBinonTypes(UseDevice, BinonName, BinonAbbrev, IsDevice, BinTypNum);
// The binon number usually = highest number so far
Devices[UseDevice][PropertyBinonType] = BinTypNum.get();
// Fill in device info. on world page
StringBuilder deviceInfo = new StringBuilder();
for (int Dvc = 1; Dvc <= NumDevices; Dvc++) {
ping();
if (Devices[Dvc][SymbolicOrMagnitude] == Magnitude) {
DisplayResponses = Devices[Dvc][LowerRangeLimit] + " to" + Devices[Dvc][UpperRangeLimit];
} else // symbolic values
{
DisplayResponses = DeviceResponses[Dvc];
DisplayResponses = mapCharacters(DisplayResponses, c -> eq(str(c), NoMoveOrTurn) ? ASpace : c);
}
deviceInfo.append(takeFirst(8, Device[Dvc] + ": ") + DisplayResponses + " " + SymbOrMagn(IsDevice, Dvc) + "\r\n");
}
World.showDeviceValues(str(deviceInfo));
}
// End of SetupDevice()
public // Called from DesignBody.FinalSetup(), & ResetWld_Click()
void Reset_Adaptron() {
// Resets all changing info. to starting places.
// Must be called before setting up any senses/sensors.
int String;
int D;
int I;
// necessary to reset the sequence
ResetRnd(-1);
OverLimit = false;
// True if create all combinations, False if use only familiar parts
CreateAll = false;
// CreateAll = True '
// always starts with body pointing North
BodyPointing = North;
World.PointUnder();
// start with no senses
NumSenses = 0;
// start with no devices
NumDevices = 0;
// World.MoveDown() etc set this to indicate the direction the robot moved
Motion = NoMove;
// and it is used as the stimulus input of the Motion sense
for (// +1 so it covers the Percept sense too
I = 1; // +1 so it covers the Percept sense too
I <= MaxSenses; // +1 so it covers the Percept sense too
I++) {
ping();
// Names of sense
Sense[I] = "";
}
// Initially the long term memory history is empty
StoreAt = 0;
// Initialize STMs
// clear out memory display stuff - index into INPUTS$() and OUTPUTS$()
LIN = 0;
// Count of inputs
COUNTIN = 0;
// This clears BinonDisplay.ChngResults.Text and LTM
ClearMemory();
for (I = 0; I <= 500; I++) {
ping();
if (I > 0) {
}
for (String = 1; String <= MaxSenses; String++) {
ping();
INPUTS[I][String] = "";
}
for (D = 1; D <= MaxDevices; D++) {
ping();
OUTPUTS[I][D] = "";
}
}
// Adapt.IO.Text = "";
// Adapt.LTMem.Text = "";
// UNUSED TriggerObj = NullObject;
// set true if last response was reflexive.
DoingReaction = false;
DoingRepeat = false;
// ActiveActon = NullAct; //no subconscious acton active
// UNUSED ExploreObj = NullObject; //will be set if reflexive response done.
// DoingAct1 = NullAct; //will be set if reflexive response done.
// UNUSED NumTrigLinks = 0; //Number of LTM episodic action links
// UNUSED NumActons = 0;
// The number of Acts entries in use
NumActs = 0;
// Rotate through all reflexive acts
RotateActs = false;
// initialized so next one will be #2 - not the Relax response = #1
LastAct = 1;
if (// Rotation through acts starts with Relax
RotateActs) {
LastAct = 0;
}
// persist changes
change();
}
// End of Reset-Adaptron()
private void ResetRnd(int i) {
// TODO
}
public void ClearMemory() {
// Called by Reset_Adaptron()
int Lk;
int T;
int I;
for (I = 1; I <= MaxBinons; I++) {
ping();
Binons[I][OLv] = 0;
Binons[I][O1] = NullObject;
Binons[I][O2] = NullObject;
ZeroTheCounts(I);
}
// there are no binons
NumBinons = 0;
for (// For all property binons and their Percept combinations and Actions
T = 1; // For all property binons and their Percept combinations and Actions
T <= MaxBinonTypes; // For all property binons and their Percept combinations and Actions
T++) {
ping();
// The names and abbreviations for the various binon types
BinonTypeName[T][BinName] = "";
BinonTypeName[T][BinAbbreviation] = "";
BinonTypes[T][SymbolicOrMagnitude] = Symbolic;
// Pointer points back to sense or device
BinonTypes[T][SensOrDevNum] = 0;
}
// clear SensorValues() and SensedBinons()
ClearSenses();
// clear out all the perceptions in STM()
ClearPerceptions();
TopLevel = 0;
for (// Clear perceived Parallel Percept and property binon entries
T = 1; // Clear perceived Parallel Percept and property binon entries
T <= MaxPercepts; // Clear perceived Parallel Percept and property binon entries
T++) {
ping();
Percepts[T][BinId][Current] = NullObject;
Percepts[T][BinId][Fired] = NullObject;
Percepts[T][XQCnt][Current] = 0;
Percepts[T][XQCnt][Fired] = 0;
}
for (// Clear out all targets
Lk = 1; // Clear out all targets
Lk <= MaxTargets; // Clear out all targets
Lk++) {
ping();
Targets[Lk][NLnk] = NullTarget;
Targets[Lk][TargetBinon] = NullObject;
}
NumTargets = 0;
ClearExpectations();
World.setBinonDisplayObjList("");
World.setBinonDisplayChngResults("");
// Percent
JND = 20;
// SizeBase# = 1.2 for a 20% just noticeable difference
AssignBases();
// persist changes
change();
}
// End of ClearMemory()
public // Called by ClearMemory()
void ZeroTheCounts(// Called by ClearMemory()
int Habit) {
Binons[Habit][TQ] = 0;
Binons[Habit][GQ] = 0;
}
// End ZeroTheCounts()
public // Called by ClearMemory()
void ClearSenses() {
for (int Sens = 1; Sens <= MaxSenses; Sens++) {
ping();
SensorValues[Sens][XQCnt][Fired] = 0;
SensorValues[Sens][Valu][Fired] = 0;
SensorValues[Sens][XQCnt][Current] = 0;
SensorValues[Sens][Valu][Current] = 0;
SensedBinons[Sens] = NullObject;
}
NumProperties = 0;
}
// End of ClearSenses()
public // Used by ClearMemory() and processing STM perceptions in PerceptionAction()
void ClearPerceptions() {
// Clear out all the Current and previous perceptions that are sources for Habits in the STM()
int Percpt;
int Lvl;
World.appendBinonDisplayChngResults(" ** Clearing Perceptions " + "\r\n");
for (Lvl = 1; Lvl <= MaxLevels; Lvl++) {
ping();
for (Percpt = Fired; Percpt <= MaxLevels; Percpt++) {
ping();
EmptySTM(Lvl, Percpt);
}
}
}
// End of ClearPerceptions()
public // Called by ClearMemory()
void AssignBases() {
double Percnt;
Percnt = /*Microsoft.VisualBasic.Conversion.Val*/
(JND) / 100.0;
// 1.2 for a 20% just noticeable difference
SizeBase = 1 + Percnt;
// If it is 2.0 then that is a 100% just noticeable difference
IntensityBase = 1 + Percnt;
}
// End of AssignBases()
public final int Buckit(double Valuu, double Base) {
// Base# = 1.2 'Ln(1.3) = 0.26, Ln(1.2) = 0.18
// XXX
return (int) Math.round(100 * Math.log(Valuu) / Math.log(Base));
}
// End of Buckit()
public final void IdBinons(int OLvl, int Prt, int Obj1, int TQNum, int Obj2, int GQNum, int IDLRatio, int SeqOrPar, int ExpectIt, Var ObjId, Var NewOne) {
// OLvl = Level of the binon, 1 stimulus property binons and response binons, 2+ Percepts or Action patterns
// PrT = Property Type value
// Obj1 = The left source binon
// Obj2 = The right source binon
// IDLRatio = The IDL ratio value
// SeqOrPar = whether it is an Action sequence or a parallel Percept
// ObjId = The object / binon identifier returned, = NullObject if over the limit
// NewOne = Returned True if object newly created, False if it already existed.
// If a new binon is created it is Active but Idle - waiting to repeat
// ---- Binon Properties - 2nd index values
// Public BType '1, The type of binon
// Public O1 '2, Left source binon pointer
// Public TQ '3, the count of times the trigger has fired
// Public O2 '4, Right source binon pointer
// Public GQ '5, the number of times the goal has fired
// Public IDL '6, The ratio value of the binon
// Public IntVl '7, Interest Value (NOVEL, INTERESTING, or Familiar)
// Public OLv '8, Level of object = number of lowest level parts involved
// Public SP '9, Sequential or Parallel property
// Public TriggerList '10, points to the linked list of target binons [Targets()]
// ' for which this binon is the left source binon (not the right source binon).
// Public TriggerCount '11, Count of its sequential right targets, >1 means it has more than one goal
// ' Used for prediction reliability, may be set >1 if needs to be combined with previous
// Public GoalList '12, points to the linked list of target binons [Targets()]
// ' for which this binon is the right source binon (not the left source binon)
// Public GoalCount '13, Count of its sequential left targets, >1 means can not predict its trigger
// ' Used for reliability of determining the cause, may be set >1 if needs to be combined with next
// Public AE '14, Action (Percept - Act) or Attention (Act - Percept) level 1 Sequential binon
// Given two objects/parts Obj1 and Obj2
// see if we have an object ObjId with the same values and the same Obj1 and Obj2.
// Return the found or newly created binon
if (Obj1 == 0)
throw fail("obj1 = 0");
if (Obj2 == 0)
throw fail("obj2 = 0");
if (// if can not find the exact match
NumBinons >= MaxBinons) {
ObjId.set(NullObject);
World.appendBinonDisplayChngResults("\r\n" + "Binon limit of " + MaxBinons + " reached!");
Stop();
return;
}
// Return no binon - none created by default
ObjId.set(NullObject);
// Assume we will not find it already exists and will create a new one
NewOne.set(true);
// First determine if we have any binons of the given type with the given ratio
if (// if none then do not check if ExistBinon
NumBinons > 0) {
// If the binons already exists then the ExistBinon routine sets the ObjId
// ExistBinon(OLvl, PrTyp, Bin1&, Bin2&, V1, ItsAE, ObjId&)
if (ExistBinon(OLvl, Prt, Obj1, Obj2, IDLRatio, ExpectIt, ObjId)) {
// This applies to Percept and property binons only when attended to
// DecreaseBinonInterest(BTyp, Bino&)
DecreaseBinonInterest(ObjId.get());
NewOne.set(false);
}
}
if (// If it does not already exist then create it
ObjId.get() == NullObject) {
// it was not found - so add it as a new one
ObjId.set(NumBinons + 1);
Binons[ObjId.get()][BType] = Prt;
// The left source binon
Binons[ObjId.get()][O1] = Obj1;
Binons[ObjId.get()][TQ] = TQNum;
// The right source binon
Binons[ObjId.get()][O2] = Obj2;
Binons[ObjId.get()][GQ] = GQNum;
// stored object ratio values
Binons[ObjId.get()][IDL] = IDLRatio;
// Do level 1 binons become familiar immediately? No they should also go from Novel to Interesting to Familiar
// Percepts start out Novel, then become Interesting and then Familiar
// Perceptual sequences start out Novel and each time attention is paid to them they become Interesting and Familiar
if (// If it is a Property or Percept binon then
SeqOrPar == Parallel) {
if (// if it is a Property binon then
Prt <= NumProperties) {
// Property binons start out Novel
SetInterest(ObjId.get(), NOVEL);
// Familiar for testing purposes
SetInterest(ObjId.get(), FAMILIAR);
} else // else it is a Percept binon
{
// Percept binons start out Novel
SetInterest(ObjId.get(), NOVEL);
// Familiar for testing purposes
SetInterest(ObjId.get(), FAMILIAR);
}
} else {
// Sequential binons start out Novel
SetInterest(ObjId.get(), NOVEL);
// tmp Call SetInterest(ObjId, FAMILIAR) 'Familiar - for testing
}
Binons[ObjId.get()][OLv] = OLvl;
// Sequential or ParallelPrt,
Binons[ObjId.get()][SP] = SeqOrPar;
if (// AE value should be 0
SeqOrPar == Parallel && ExpectIt != 0) {
Stop();
}
// only used if SP=Sequential and OLvl=1, Action=1, Attention=2
Binons[ObjId.get()][AE] = ExpectIt;
// =0, an NLnk pointer at end of linked list
Binons[ObjId.get()][TriggerList] = NullTarget;
// Count of its sequential right targets, >1 means can not predict its goal
Binons[ObjId.get()][TriggerCount] = 0;
// =0, an NLnk pointer at end of linked list
Binons[ObjId.get()][GoalList] = NullTarget;
// Count of its sequential left targets, >1 means can not predict its trigger
Binons[ObjId.get()][GoalCount] = 0;
// '--- Linked List of Target Binons - for Percepts and Actions -------------
// Public NumTargets& 'The number of Target binon entries created so far
// Public MaxTargets& '10000 = the max number of Target binon entries possible
//
// Public Targets&(1 To 10000, 1 To 2) 'pointed to by Binons(Typ, ID, TriggerList) or by Binons(Typ, ID, GoalList)
// '---- Targets' 2nd index property values
// Public NLnk '1 = The pointer to the next Targets() entry in this linked list,
// ' may be a NullTarget at end of linked list
// Public TargetBinon '2 = a left or right Target binon
//
// Public NullTarget '=0, an NLnk pointer at end of linked list
// The target binon ObjId is triggered by source binon Obj1 so add it to the right target list for Obj1
if (// cannot be property binon
Obj1 != NullObject) {
// create a new target
NumTargets = NumTargets + 1;
if (// have we exeeded the maximum
NumTargets > MaxTargets) {
Stop();
}
// The right target is the newly created binon
Targets[NumTargets][TargetBinon] = ObjId.get();
// It should point to the 1st one on existing list
Targets[NumTargets][NLnk] = Binons[Obj1][TriggerList];
// ObjId becomes the 1st one on the right target list of Obj1
Binons[Obj1][TriggerList] = NumTargets;
if (SeqOrPar == Sequential) {
// Count of right targets for Obj1
Binons[Obj1][TriggerCount] = Binons[Obj1][TriggerCount] + 1;
}
}
// The source binon Obj2 is the goal of this target binon ObjId so add it to the left target list of Obj2
if (// cannot be property binon
Obj2 != NullObject) {
// create a new target
NumTargets = NumTargets + 1;
if (// have we exeeded the maximum
NumTargets > MaxTargets) {
Stop();
}
// The left target is the newly created binon
Targets[NumTargets][TargetBinon] = ObjId.get();
// It should point to the 1st one on existing list
Targets[NumTargets][NLnk] = Binons[Obj2][GoalList];
// ObjId becomes the 1st one on the left target list of Obj2
Binons[Obj2][GoalList] = NumTargets;
if (SeqOrPar == Sequential) {
// Count of left targets for Obj2
Binons[Obj2][GoalCount] = Binons[Obj2][GoalCount] + 1;
}
}
NumBinons = ObjId.get();
// tmp BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text & " - Created New Binon = " & _
// DisplayStimulu[Prt][ObjId] + "\r\n";
}
// End if not ExistBinon
}
// End of IdBinons()
public final void DecreaseBinonInterest(int Bino) {
// Updates the interest in a stimulus, Novel -> Interesting -> Familiar
// called when the stimulus is added to the perception list
// unused int Intrst;
switch(InterestIn(Bino)) {
case NOVEL:
if (InterestLevels == 3) {
// Novel -> Interesting
SetInterest(Bino, INTERESTING);
} else // Interestlevels=2
{
// Novel -> Familiar
SetInterest(Bino, FAMILIAR);
}
break;
case INTERESTING:
// Interesting -> Familiar
SetInterest(Bino, FAMILIAR);
break;
}
}
// End of DecreaseBinonInterest()
public final void SetInterest(int Objct, int IntLvl) {
// Sets the interest level of the given object.
Binons[Objct][IntVl] = IntLvl;
}
// End of SetInterest()
public final int InterestIn(int Objct) {
return Binons[Objct][IntVl];
}
// End of Function InterestIn()
public final boolean ExistBinon(int OLvl, int PrTyp, int Bin1, int Bin2, int V1, int ItsAE, Var ObjId) {
boolean tempExistBinon = false;
// Given two objects numbered Bin1 and Bin2 etc. see if we have an object in Binons()
// that matches this combination, if so return its number in ObjId
// ObjID = 0 if not found and ExistBinon is set to False
// Ratios of Values are used for recognition of Time (duration) patterns
// Pairs of object / binon parts (Obj1 and Obj2) are used for recognition of:
// Sense patterns, sensor patterns and symbol patterns etc.
int OO;
// range of binons to search
int StartAt;
int EndAt;
// assume it does not exist
tempExistBinon = false;
// return NullObject if not found
ObjId.set(NullObject);
StartAt = 1;
EndAt = NumBinons;
for (// For all the known objects of this type
OO = StartAt; // For all the known objects of this type
OO <= EndAt; // For all the known objects of this type
OO++) {
ping();
// Object level is an identifying property of a binon
if (// If it is at the same level then
Binons[OO][OLv] == OLvl) {
if (// if it is the same binon type then
Binons[OO][BType] == PrTyp) {
// O1 = Object Part 1 pointer and O2 = Object Part 2 pointer
// Given Id of the object - search for same pair of parts and AE
if (Binons[OO][O1] == Bin1 && Binons[OO][O2] == Bin2 && Binons[OO][AE] == ItsAE) {
if (// If it has the same quantity IDL Ratio?
V1 == Binons[OO][IDL]) {
ObjId.set(OO);
tempExistBinon = true;
// terminate FindIt loop
OO = NumBinons;
}
}
}
}
}
return tempExistBinon;
}
// End of ExistBinon()
public final void PerceptionAction(int[][][] SensorValues, Object[] DeviceValues) {
// Called by Adapt.Inpu_KeyPress() for each stimulus/response cycle.
// SensorValues() contains the stimuli from the senses/sensors
// DeviceValues() are output responses to the devices to change the body/environment
int ObjtLvl;
int NovelLvl;
String HabitIt = null;
int Pass;
boolean CheckIt = false;
// Action-Expectation (Response-Stimulus) or Expectation-Action (Stimulus-Response)
int AEorEA = 0;
int SourceBinon;
// unused int SourceXQCnt;
// unused int SourceTQCnt;
// 0. INITIAL STATE: based on the variables: PracticingBinon and ConcentrationLevel, will be either;
// a) an Action being executed / practiced that identifies the expected Percept stimulus and
// a concentration level of novel or interesting. Plus zero or more other Actions that also match
// the attended-to past experience and have expectations of what will happen next.
//
// Or b) no Action being performed and concentration level of familiar but may have
// a previous attended-to stimulus that repeated a certain quantity of times and is expecting it to repeat again.
//
// Or c) no attended-to stimulus or practicing Perceptual sequence because it is the first time through
// In parallel there may be zero or more subconsciously executing Actions that will stop if they don't
// get their next expected stimulus or their source binons become idle and will continue otherwise.
StoreAt = StoreAt + 1;
if (// stop further Go / Continue stepping
StoreAt == MaxMemory) {
// XXX World.Go.Enabled = false;
}
// display the cycle count
World.setBinonDisplayChngResults("Step = " + StoreAt + "\r\n");
// 1. PERCEIVE PERCEPTS:
// Get stimuli from all senses / sensors and recognize / create all Percept binon combinations of
// familiar stimuli. Both source binons must be familiar before they can be combined.
// This happens when a change occurs on any sense / sensor. This includes all areas of sensors that
// attention is or is not focused on. This includes creation of stimuli that are expected and unexpected.
// Novel stimuli get created and are remembered in the novel state. Is it possible that novel ones are only
// kept if they have attention paid to them? When we sleep the novel ones are probably pruned.
// Otherwise you end up with too many of them. Maybe it is only Actions that have to be attended to so
// that their familiarity / interest is reduced. The interest of the Percept is reduced on occurrence repetition.
// For a three stage novelty reduction, if and when Percepts occur again they are changed to Interesting.
// The third time they occur they become familiar and can be combined with other familiar ones.
// An Action has to be practiced before its interest level is reduced.
// If there is a clock then
// If RecogThem is called for every time it ticks (on a regular interval even if nothing changed) then
// The sensor repeat count (Level1, XQCnt, Fired) should be set to 1.
// (this is the case for hand writen digits or anywhere the environment is polled)
// If the reading is Magnitude then level 1 needs to count the repeats of the same value within the JND
// level 2 wil contain ratio binons (symbolic)
// Else if RecogThem is called every time a change occurs on at least one sense then
// Put the value of the duration into the sensors repeat count (XQCnt). (as for Morse code)
// Else if there is no clock then
// RecogThem is event driven and called only when a change occurs on at least one sense then
// set the XQCnt to 1 and for any repeaters do as above for a clock.
// SensorValues[NameBin][Valu][Fired] = Asc(Letr$) 'The letter
// SensorValues[NameBin][XQCnt][Fired] = Durat 'the number of times it has repeated
// SensorValues[ContBin][Valu][Fired] = DitDah 'The contrast intensity
// SensorValues[ContBin][XQCnt][Fired] = Durat 'the number of times it has repeated
// Pay attention to the expected sensors if concentrating - a Percept,
// create the Percepts that attract attention and place the most interesting in STM(1,Fired)
// Set GotAttendedTo = true if got the expected/attendedto stimuli/Percept
// Process the SensorValues()
ProcessStimuli(SensorValues);
// The Perception STM list has many binons at each level. The Fired one is the most recent fired binon
// before any processing has been done at that level. It is put in the Fired entry when
// the level below is processed.
// After the processing has been done the previous one contains what was in the Current and
// the Current contains what was in the Fired provided there was no repeat of an Action.
// 2. PERFORM ACTION RECOGNITION:
// High level algorithm - 30th December 2016
// Expectation = Expectation/Attention binon = A-R
// Action = Action Habit = R-A
// Perceptual sequence = Stimulus Habit (Percept at level 1) and = A-E at higher levels = R-A-R
// Action sequence = Response Habit (Device responses) and E-A higher up = A-R-A.
// Repeat the the algorithm below for these two situations:
// Pass 1/ Odd level Current Action sequence combined with Fired Perceptual sequence to produce next level up Fired Expectation,
// find out if right target Action of the Perceptual sequence is worth doing and then
// the even level Current Action is combined with just Fired Expectation to produce next level up Perceptual sequence,
// Find out if right target Action sequence of the Expectation is worth doing.
// Pass 2/ Odd level Current Perceptual sequence combined with Fired Action sequence to produce next level up Fired Action,
// find out if right target Expectation of the Action sequence is worth doing and then
// the even level Current Expectation is combined with just Fired Action to produce next level up Action sequence,
// find out if right target Perceptual sequence of the Action is worth doing.
// The algorithm: Repeat this for each level X of the STM() binon tree as long as the fired is not a null object
// If on an even level and doing pass 2/ then have a just Fired Action to process so
// check to see if the fired Action pattern matches the previous Action (X positions earlier) at this level
// If it repeats then increment the past entry for the repeat and move it up to current
// Else if it does not repeat or on an odd level or doing pass 1/ then
// combine the Current to the Fired at this level (if there is a current) and
// place it in the next level up Fired position
// end if
// If finished pass 1/ STM processing then use the highest level Action or Action sequence found worth doing and
// do its lowest level response. Put this response Action sequence in STM(level 1 Fired) and start pass 2
// If finished pass 2/ STM processing then use the highest level Expectation or Perceptual sequence found worth doing and
// attend to its lowest level expected Percept in ProcessStimuli().
// The stimulus Percept obtained will be the Fired Perceptual sequence to start this process again.
for (// For 1/ R-S & A-E combinations then 2/ S-R & E-A combinations
Pass = 1; // For 1/ R-S & A-E combinations then 2/ S-R & E-A combinations
Pass <= 2; // For 1/ R-S & A-E combinations then 2/ S-R & E-A combinations
Pass++) {
ping();
// Start by processing level 1 perceptions - always assigned
ObjtLvl = 1;
// set to the level at which the fired STM is novel
NovelLvl = 0;
// Move right amount to eliminate previous pattern
MoveAmount = 0;
// It may be a right source binon for some target binons
SourceBinon = STM[ObjtLvl][BinId][Fired];
while (// While there is a Fired familiar binon in STM
SourceBinon != NullObject) {
ping();
World.appendBinonDisplayChngResults(StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0/ Processing percepts at level" + vbToStr(ObjtLvl) + "\r\n");
// First move the STM entries right by the MoveAmount due to a repeater at a lower level
if (MoveAmount > 0) {
// declare undeclared variable
int Prcpt = 0;
// eliminates binon created with previous goal from STM
MoveRight(ObjtLvl, Current + MoveAmount, Current, 2 * Prcpt);
}
if (// If the STM fired binon is novel then
InterestIn(SourceBinon) > FAMILIAR) {
// It can not be combined with a current
NovelLvl = ObjtLvl;
} else // else check for a repeat and combine with current in STM
{
// do not check for a repeat of an Action
CheckIt = false;
if (// If the Stimulus / Expectation processing pass
Pass == 1) {
AEorEA = Attention;
HabitIt = "Percept";
if (// Odd level = 1, Even level = 0
ObjtLvl % 2 == 0) {
HabitIt = "Action";
// Check to see if it repeats - both A and E - even levels
CheckIt = true;
}
} else if (// else if the Action / Response processing pass
Pass == 2) {
// assume it will be an Action
AEorEA = Action;
HabitIt = "Action";
if (// If fired entry is an Action then (Pass=2 and remainder =0)
ObjtLvl % 2 == 0) {
HabitIt = "Expectation";
// Check to see if it repeats - both A and E - even levels
CheckIt = true;
}
}
World.appendBinonDisplayChngResults(StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0a/ Pass" + vbToStr(Pass) + " - " + HabitIt + " Processing" + "\r\n");
ProcessSTMLevel(ObjtLvl, SourceBinon, AEorEA, CheckIt);
}
// End if STM Fired binon is Novel
// Move all STM left, the fired entry into the current location
MoveLeft(ObjtLvl);
// Remember the highest not null fired level in STM
HighestPerceptLvl = ObjtLvl;
if (// track highest non-empty level
HighestPerceptLvl > TopLevel) {
TopLevel = HighestPerceptLvl;
}
// Go up the pattern tree combining Fired and Currents if they are patterns and fired is not nullobject
// check out the next level for current and fired
ObjtLvl = ObjtLvl + 1;
if (ObjtLvl <= MaxLevels) {
// It may be a right source binon for some target binons or Null
SourceBinon = STM[ObjtLvl][BinId][Fired];
} else {
SourceBinon = NullObject;
Stop();
}
}
// Move all higher levels left by one minus moveamount
// move left one but right based on repeater found
MoveAmount = 1 - MoveAmount;
for (; // for all higher levels that have something in them
ObjtLvl <= TopLevel; // for all higher levels that have something in them
ObjtLvl++) {
ping();
if (MoveAmount == 1) {
// processed one more level 1 stimulus
MoveLeft(ObjtLvl);
} else if (MoveAmount < 0) {
MoveRight(ObjtLvl, Current - MoveAmount, Current, 2 * ObjtLvl);
}
}
// Fill in the top part of BinonDisplay.ChngResults.Text
ReportObjects1();
// It may be a right source binon for some target binons
SourceBinon = STM[HighestPerceptLvl][BinId][Current];
if (Pass == 1) {
// If finished pass 1/ STM processing then based on the recognized Perceptual sequence or Expectation find any
// predicted action and use this highest level Action or Action sequence found worth doing and
// do its lowest level response in PerformAction().
// Or if the predicted action is learnt / familiar then use thinking (deduction) and find one worth doing
// Put this response Action sequence in STM(level 1, Fired) and start pass 2
// determine what response to produce - do thinking
DetermineResponse();
// Keep a record of STM() binons for display of LTM
LTMEMORY[StoreAt][LtmESType] = BinonTypeOf(SourceBinon);
LTMEMORY[StoreAt][LtmESActBin] = SourceBinon;
World.appendBinonDisplayChngResults(DisplaySTM());
} else // else Pass = 2
{
// If finished pass 2/ STM processing then based on the recognized Action or Action sequence find any
// predicted perception and use this highest level Expectation or Perceptual sequence found worth doing and
// do its lowest level expected Percept and attend to it in ProcessStimuli().
// This effectively means DetermineStimulus() needs to determine what stimulus to attend to
// The stimulus Percept obtained will be the Fired Perceptual sequence to start this process again.
// Keep a record of STM() binons for display of LTM
LTMEMORY[StoreAt][LtmARType] = BinonTypeOf(SourceBinon);
LTMEMORY[StoreAt][LtmARActBin] = SourceBinon;
// The level 1 perceived stimulus could be a familiar stimulus but unexpected.
// It is unexpected because none of the active Perceptual sequences were expecting it.
// Reports on Percepts() and STM() & expectation
ReportPerceptions();
// Report on Binons
ReportObjects2();
}
// End if Pass =1 or Pass = 2
}
}
// End of PerceptionAction()
public final // Called from PerceptionAction()
void ProcessStimuli(// Called from PerceptionAction()
int[][][] SensorValues) {
// SensorValues() contains the sensor readings for ProcessStimuli() to process.
// ProcessStimuli() is not currently provided with the Percept that it expects to get/should attend to.
// Instead ProcessStimuli() assumes that the previous stimuli will repeat and just delivers any changes.
// ProcessStimuli is asked to attend to the senses / sensors specified in the given Percept (not yet).
// After calling ProcessSenses() to put sensory stimuli from all senses into SensedBinons() it
// uses the SenseBinons() and puts the perceived ones in the Percepts(). Not yet based on what was being attended to.
// If nothing was attended to then all the sensory stimuli are used.
// It creates the parallel combinations (Percepts) of the property SensedBinons().
// Combinations are formed if the parts are both familiar and both changed or both familiar and not changed.
// The most interesting Percept is then the largest / highest level (most complex) one that changed or
// if there was no change then just the highest level one.
// The most interesting stimulus is then placed in STM(level 1, Fired).
// SenseBinons() consist of:
// TextBin = the symbolic value for the letter - symbolic
// ContBin = Intensity = the value for the sensor measurement - Magnitude
int Sens;
int PerceptType;
String GotWhat;
int TopType;
int TopBinon;
int TopInterest;
int OL;
boolean HaveAChange = false;
int RepeatCount;
int FirstBinon;
int IntInF = 0;
int SecondBinon;
int TheType;
// Property binons and their combinations are at level 1
OL = 1;
// Assume no change will take place on any sense
HaveAChange = false;
// The expectation is the previous stimulus will repeat
// Report on all Percepts, Actions and expectations
ReportPerceptions();
// Obtain the SensedBinons() for all property types SensorValues()
ProcessSenses(OL, SensorValues);
// The expectation is a repeat of the previous stimuli (if there are any) Property and Percept binons.
// Magnitude stimuli values must change by a JND to be detected
// Symbolic stimuli values are always available because they are uniquely identified.
// Determine what attracts attention by combining the stimuli that have changed.
// If nothing has changed then a repeat of the previous stimuli has occurred.
// For all the senses/property and Percept types
// copy the SensedBinons() into the 1st level Fired Percepts (property binons level),
// the other Percept combinations of property binons are created below
for (// For each property type = sense
Sens = 1; // For each property type = sense
Sens <= NumSenses; // For each property type = sense
Sens++) {
ping();
TheType = Sens;
Percepts[TheType][XQCnt][Fired] = SensorValues[Sens][XQCnt][Fired];
// Property binons into Percepts Level 1
Percepts[TheType][BinId][Fired] = SensedBinons[Sens];
if (// use the previous SensedBinon
Percepts[TheType][BinId][Current] != NullObject) {
if (SensedBinons[Sens] != Percepts[TheType][BinId][Current]) {
// This property binon has changed
HaveAChange = true;
}
} else // Else the Current entry is empty the first time through
{
if (StoreAt != 1) {
Stop();
}
}
}
// end for each property binon
// Create all the combinations of Percepts
CreatePerceptCombos();
// Report on Percept perceptions
DisplayPercepts(Fired);
// ------ What attracts attention and thus what to pay attention to / focus on
// The highest level, most interesting changed, not null current Percept binon
// captures attention for sequential processing
// Will be the highest complexity if no changed one found
TopBinon = NullObject;
TopType = NullType;
if (HaveAChange) {
// The interest level of the highest changed binon
TopInterest = NoInterest;
for (// For all the Percept binon types from complex to property binons
PerceptType = NumPercepts; // For all the Percept binon types from complex to property binons
PerceptType >= 1; // For all the Percept binon types from complex to property binons
PerceptType--) {
ping();
// The Percept that fired of this type - maybe NullObject
FirstBinon = Percepts[PerceptType][BinId][Fired];
// The previous or expected binon of this type - maybe NullObject
SecondBinon = Percepts[PerceptType][BinId][Current];
if (// If the fired one is different / changed then
FirstBinon != SecondBinon) {
// If have a perceived binon and an expected one then
if (FirstBinon != NullObject) {
// Interest level of this Percept
IntInF = InterestIn(FirstBinon);
// If it is familiar and interest so far is also familiar then we use the largest changed combination
if (IntInF == FAMILIAR) {
if (// The first / highest familiar one
TopInterest == NoInterest) {
// subroutine UseThisOne
TopType = PerceptType;
// Save the highest level changed interesting Percept
TopBinon = FirstBinon;
// will be familiar - only used if HaveAChange=True
TopInterest = IntInF;
}
// Else if it is novel then use the lowest level highest interest that has changed
} else if (// If it is more or equal interest than the one so far then
IntInF >= TopInterest) {
// subroutine UseThisOne
TopType = PerceptType;
// Save the highest level changed interesting Percept
TopBinon = FirstBinon;
// will be familiar - only used if HaveAChange=True
TopInterest = IntInF;
}
} else // else one or both binons are NullObjects
{
}
// End if it has a value
} else // else got expected - no difference / change
{
}
// End if it has changed
}
// If there is no change then the largest (highest level) not null combination is focused on.
} else // else there is no change in stimuli
{
for (// For all the Percept binon types from complex to property binons
PerceptType = NumPercepts; // For all the Percept binon types from complex to property binons
PerceptType >= 1; // For all the Percept binon types from complex to property binons
PerceptType--) {
ping();
// The Percept that fired of this type - maybe NullObject
FirstBinon = Percepts[PerceptType][BinId][Fired];
if (FirstBinon != NullObject) {
// subroutine UseThisOne
TopType = PerceptType;
// Save the highest level changed interesting Percept
TopBinon = FirstBinon;
// will be familiar - only used if HaveAChange=True
TopInterest = IntInF;
// terminate loop
PerceptType = 1;
}
}
}
if (// report about a different stimulus then - unexpected
HaveAChange) {
GotWhat = "Got UNEXPECTED: ";
} else // else we got what was expected
{
GotWhat = "Got EXPECTED: ";
}
World.appendBinonDisplayChngResults(rep(' ', 55) + GotWhat + DisplayPattern(TopBinon) + "\r\n");
// Clears PracticingBinon, PerceivedBinon etc.
ClearExpectations();
// Must have a property or Percept stimulus so place the value Percepts(..Fired)
// in the Fired entry of STM[) at level 1][set its XQ count][set ExpectLevel, Expcts(] etc.
RepeatCount = 0;
if (TopBinon != NullObject) {
RepeatCount = Percepts[TopType][XQCnt][Fired];
// FireTheBinon(PercptLvl, TheBinon&, TQCnt, XQCnt)
// will set the XQ count and the Perceived etc.
FireTheBinon(OL, TopBinon, 1, RepeatCount);
RememberStimulus(TopBinon, StoreAt);
}
// Move the fired Percepts() actually sensed into the current entries and clear the Fired entries
for (// For all property and Percept binon types
PerceptType = 1; // For all property and Percept binon types
PerceptType <= NumPercepts; // For all property and Percept binon types
PerceptType++) {
ping();
Percepts[PerceptType][BinId][Current] = Percepts[PerceptType][BinId][Fired];
// clear their entries
Percepts[PerceptType][BinId][Fired] = NullObject;
Percepts[PerceptType][XQCnt][Current] = Percepts[PerceptType][XQCnt][Fired];
Percepts[PerceptType][XQCnt][Fired] = 0;
}
}
// End of ProcessStimuli()
public final // Called from ProcessStimuli()
void ProcessSenses(// Called from ProcessStimuli()
int OL, // Called from ProcessStimuli()
int[][][] SensorValues) {
// Goes through the Raw sensor data in SensorValues(), creates the property type SensedBinons().
// SensorValues consist of:
// Text = the symbolic value for the letter - symbolic
// Intensity = the value for the sensor measurement - Magnitude
var SensedBinon = new Var<>(0);
var NewBee = new Var<>(false);
int PropBinonType;
int PrevLogVal;
int FiredLogVal;
int ValuDiff;
// ' -------------------------- Senses and Sensors --------------------------
//
// Public NumSenses 'The number of physical senses, Max of 8
// 'Currently equals the NumProperties since each sense currently = 1 property type
// Public MaxSenses 'Maximum number of senses = max 8 physical senses
// unused String[] Sense = new String[1 + 8]; //Names of senses, up to 8 physical senses
//
// Public Senses[1 To 8][1 To 6] 'Properties of the different senses
// '1st index = Sense number
// '2nd index = Sense property
//
// '---- Senses() - 2nd index values - Sense Properties
// Public PropertyBinonType '1, Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator
// Public LowerRangeLimit '3, Lower limit of range of values, zero is minimum (65 = "A")
// Public UpperRangeLimit '4, Upper limit of range of values, 255 is maximum (90 ="Z")
// Public LinearOrCircular '5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360)
// Public IntegersOrLogs '6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
// Public NumberOfSensors '7 Number of sensors in sensor array
// Public SensorsDependentOrIndependent '8 are sensors adjacent (dependent) or independent
//
// Public Symbolic '1, Indicates that the values from this sense are symbolic, range A -> Z
// Public Magnitude '2, Indicates that the values from this sense are numeric, integers, range 0 -> Limit
//
// Public Linear '1, Indicates that the values go from the lower limit to upper limit
// Public Circular '2, Indicates that the values rap around from the upper limit to 0
//
// Public IntegerValues '1, Indicates that the values are integer readings
// Public LogValues '2, Indicates that the values are already logs - orders of magnitude
// '-------------------- Values of stimuli from senses / sensors ------------------------------
//
// Public SensorValues[1 To 8][1 To 2][0 To 1] 'Stimulus values from senses/sensors
// '1st index is sense number, currently = property binon type
// '2nd index is what type of information is in the SensorValues(), XQCnt or Valu
// '3rd index is Fired for the most recent stimulus value and Current for the previous
//
// '---- SensorValues 2nd index values - type of information in SensorValues()
// Public XQCnt '=1, the count of times the value has repeated, also used below
// Public Valu '=2, the value for the stimulus, if symbolic then value = Asc(Symbol$)
// Public NoName$ '"_", The character used when no letter provided for the IDL value of a TextBin binon
//
// '---- SensorValues 3rd index values - which past stimulus it is - also used below
// Public Fired '=0 'stimulus put in this level upon firing before being processed
// Public Current '=1 'The Fired one becomes the Current one after processing
// ------ Create binons from Sensed values that have changed and put them in SensedBinons()
// and move the fired SensorValues to the previous entries for all senses = property types
for (// For each sense (TextBin and ContBin) = for each property type
int Sens = 1; // For each sense (TextBin and ContBin) = for each property type
Sens <= NumSenses; // For each sense (TextBin and ContBin) = for each property type
Sens++) {
ping();
// In Morse code only one property per sense
PropBinonType = Sens;
if (// If symbolic then
Senses[Sens][SymbolicOrMagnitude] == Symbolic) {
// Symbolic values always put in SensedBinons() whether they changed or not.
// Create or find the binon for this symbolic value
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
IdBinons(OL, PropBinonType, NullObject, 0, NullObject, 0, SensorValues[Sens][Valu][Fired], Parallel, 0, SensedBinon, NewBee);
// Fired Symbolic value changed
SensedBinons[Sens] = SensedBinon.get();
} else // Else ValueType = Magnitude
{
// Goal
FiredLogVal = Buckit(SensorValues[Sens][Valu][Fired], SizeBase);
// The first time though we will not have a previous (Current) sensor reading (PrevLogVal)
if (// no previous value
SensorValues[Sens][Valu][Current] == 0) {
// there is a change in the Magnitude reading
ValuDiff = 1;
} else {
// Trigger
PrevLogVal = Buckit(SensorValues[Sens][Valu][Current], SizeBase);
// Adjacent repeat quantities are used to produce a ratio - same as these two lines of code:
// ValuDiff = Int(Abs(PrevLogVal - FiredLogVal) / 100) 'the difference in the Logs = ratio of repeats
// If FiredLogVal > PrevLogVal Then ValuDiff = -ValuDiff 'keep the sign
// Trigger minus Goal Logs
ValuDiff = (PrevLogVal - FiredLogVal) / 100;
}
// Using ValuDiff will produce values of 1 and -1 as the contrast (Intensity) SensorValues()
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, _
// IDLRatio, SeqOrPar, ExpectIt, ObjId, NewOne As boolean);
IdBinons(OL, PropBinonType, NullObject, 0, NullObject, 0, ValuDiff, Parallel, 0, SensedBinon, NewBee);
// Fired Magnitude value changed by a JND
SensedBinons[Sens] = SensedBinon.get();
}
// save the previous value
SensorValues[Sens][Valu][Current] = SensorValues[Sens][Valu][Fired];
// save the previous repeat count
SensorValues[Sens][XQCnt][Current] = SensorValues[Sens][XQCnt][Fired];
}
// End of loop for each property type = sense
}
// End of ProcessSenses()
public final // Create all the combinations of Percepts
void CreatePerceptCombos() {
var SensedBinon = new Var<>(0);
var NewBee = new Var<>(false);
int PropBinonType;
int OL;
int FirstType;
int FirstBinon;
int IntInF;
boolean FirstChanged = false;
int SecondType;
int SecondBinon;
int IntInS;
boolean SecondChanged = false;
// For all the possible pairs of not null 1st level Percepts() = Property binon level
// Create the 2nd and higher level combinations,
// combine changed with changed and no change with no change but only if both property binons are familiar.
// Fill in Percepts() with a NullObject if either source binon is a NullObject or novel
// Need to create the Percept combinations of property binons - data driven algorithm from PerceptSources()
for (// PropBinonType used for position of the combination
PropBinonType = NumProperties + 1; // PropBinonType used for position of the combination
PropBinonType <= NumPercepts; // PropBinonType used for position of the combination
PropBinonType++) {
ping();
FirstType = PerceptSources[PropBinonType][FirstSource];
SecondType = PerceptSources[PropBinonType][SecondSource];
OL = PerceptSources[PropBinonType][PerceptLevel];
// CombineThem; //Uses Percepts[TheType][BinId][Current] to determine change
// CombineThem:
FirstBinon = Percepts[FirstType][BinId][Fired];
SecondBinon = Percepts[SecondType][BinId][Fired];
// assume the combination will not be produced
Percepts[PropBinonType][BinId][Fired] = NullObject;
if (// if both sources are not null
FirstBinon != NullObject && SecondBinon != NullObject) {
IntInF = InterestIn(FirstBinon);
IntInS = InterestIn(SecondBinon);
// Both source binons must be familiar before they can be combined
if (CreateAll || (IntInF == FAMILIAR && IntInS == FAMILIAR)) {
// Both source binons must have changed or both stayed the same before they can be combined
// Percepts[TheType][BinId][Current]
FirstChanged = false;
if (Percepts[FirstType][BinId][Current] != FirstBinon) {
FirstChanged = true;
}
SecondChanged = false;
if (Percepts[SecondType][BinId][Current] != SecondBinon) {
SecondChanged = true;
}
if (// If both changed or both stayed the same then
FirstChanged == SecondChanged) {
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
IdBinons(OL, PropBinonType, FirstBinon, 0, SecondBinon, 0, 0, Parallel, 0, SensedBinon, NewBee);
// exp Call SetInterest(PropBinonType, SensedBinon, FAMILIAR) 'Percept binons always familiar
// The property combination binon has fired (been recognized) and is expecting to fire again
Percepts[PropBinonType][BinId][Fired] = SensedBinon.get();
// Need value in Fired because it will be moved into current
Percepts[PropBinonType][XQCnt][Fired] = Percepts[FirstType][XQCnt][Fired];
} else // else no combination binon created at level 1 - Source Percepts() are not familiar & changed
{
}
} else // else no combination binon created at level 1 - Source Percepts() are not familiar
{
}
} else // else no combination binon created at level 1 - Source Percepts() are NullObjects
{
}
// end of CombineThem
}
}
// End CreatePerceptCombos()
public final // called from PerceptionAction()
void ActivateAction(// called from PerceptionAction()
int DoBinon) {
// DoBinon& is the PracticingBinon Action that is to be done
var DHabitBinon = new Var<>(0);
// GetDHabit returns the Action or D-Habit Binon
// Get the level 1 D-Habit to perform
GetDHabit(DoBinon, DHabitBinon);
PerformDHabit(DHabitBinon.get());
}
// End of ActivateAction()
public final // called from ActivateAction()
void PerformDHabit(// called from ActivateAction()
int DoBinon) {
// DoBinon is a level 1 Binon (D-Habit) that contains the device response to perform.
// DoBinon after pass 1 has been done is the expected response.
// It calls PerformResponses() which performs the DoBinon.
// This means it outputs the LetrBin. Then it fires the binon so it is on the STM().
var Letter = new Var<>("");
// unused int LetterBinon = 0;
int DeviceNum = 0;
// unused boolean NewBee = false;
int OutType;
int OutBinon = 0;
// '-------------------- Devices ------------------------------------------------
//
// Public NumDevices 'Number of output devices
// Public MaxDevices 'Maximum number of devices = max 8 devices
// Public Device$(1 To 8) 'Names of device, up to 8 devices
//
// Public Devices[1 To 8][1 To 5] 'Properties of the output / response devices
// '1st index = Device number
// '2nd index = Device property
// Public DeviceResponses$(1 To 4) 'A string of the possible symbolic responses for the device
// ---- Devices() - 2nd index values - Device Properties - DEFINED ABOVE
// Public PropertyBinonType '1, Response property binon type e.g. 1 = LetrBin
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator
// Public LowerRangeLimit '3, Lower limit of range of response values, zero is minimum (97 = "a")
// Public UpperRangeLimit '4, Upper limit of range of response values, 255 is maximum (122 = "z")
// Public LinearOrCircular '5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Motor rotations are Circular (0 to 360)
// Public IntegersOrLogs '6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
// Public Symbolic '1, Indicates that the values for this device are symbolic, Range a -> z
// Public Magnitude '2, Indicates that the values for this device are numeric, integers, range 0 -> limit
// Public Linear '1, Indicates that the values go from the lower limit to upper limit
// Public Circular '2, Indicates that the values rap around from the upper limit to 0
// Public IntegerValues '1, Indicates that the values are integer readings
// Public LogValues '2, Indicates that the values are already logs - orders of magnitude
// Find the response parts of DoBinon - should use Devices() to identify the binon types involved
if (// If there was no response in DoBinon then
DoBinon == NullObject) {
// should always have one selected by DetermineResponse()
Stop();
// DeviceNum = 1 'Letters = LetrBin
// OutType = Devices[DeviceNum][PropertyBinonType] 'Currently = LetrBin for device #1
// Letter$ = NoResp$
// 'Should distinguish between symbolic versus Magnitude responses
// 'Create or find the binon for this symbolic value
// 'IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
// Call IdBinons(1, OutType, NullObject, 0, NullObject, 0, Asc(Letter$), Parallel, 0, OutBinon, NewBee)
} else // else have a letter to output
{
OutBinon = DoBinon;
OutType = BinonTypeOf(DoBinon);
// the device number for this response type binon
DeviceNum = BinonTypes[OutType][SensOrDevNum];
}
// Output the response (if any) and setup the expectation
// GetValue adds text to 3rd parameter = Letter$ so empty it
Letter.set("");
GetValue(OutBinon, Letter);
Letter.set(StringHelper.trim(Letter.get(), ' '));
World.appendBinonDisplayChngResults(" OUTPUT response = " + Letter + "\r\n");
DeviceValues[DeviceNum][XQCnt] = 1;
DeviceValues[DeviceNum][Valu] = Binons[OutBinon][IDL];
// Clears PerceivedBinon
ClearExpectations();
// FireTheBinon(PercptLvl, TheBinon&, TQCnt, XQCnt)
// will set PerceivedBinon
FireTheBinon(1, OutBinon, 1, 1);
RememberResponse(OutBinon, StoreAt);
}
// End PerformDHabit()
public final void ReportPerceptions() {
// Display the Fired, Current and previous perceptions in Percepts()
// unused String OLvl = null;
// unused String Prcpt = null;
// unused String Pcpts = null;
DisplayPercepts(Current);
// Report on Perceptual sequence perceptions
World.appendBinonDisplayChngResults(DisplaySTM() + "\r\n");
}
// End of ReportPerceptions()
public final void DisplayPercepts(int CurrOrFired) {
int BinType;
// Report on Percept recognitions
World.appendBinonDisplayChngResults(" Percepts = ");
for (// All binon types except Actions
BinType = 1; // All binon types except Actions
BinType <= NumPercepts; // All binon types except Actions
BinType++) {
ping();
World.appendBinonDisplayChngResults(DisplayPercept(BinType, CurrOrFired));
}
World.appendBinonDisplayChngResults("\r\n");
}
// End of DisplayPercepts()
public final String DisplayPercept(int BType, int CurrOrFired) {
return StringHelper.trim(String.valueOf(Percepts[BType][XQCnt][CurrOrFired]), ' ') + "x" + DisplayPattern(Percepts[BType][BinId][CurrOrFired]) + " ";
}
// End of DisplayPercept$()
public final String DisplaySTM() {
String tempDisplaySTM = "";
int OLvl;
int Prcpt;
String Pcpts;
// Report on perceptions in STM()
if (// No STM entries then
STM[1][BinId][Current] == NullObject) {
tempDisplaySTM = "STM is empty" + "\r\n";
} else {
for (OLvl = 1; OLvl <= MaxLevels; OLvl++) {
ping();
// printVars_str DisplaySTM(+OLvl, +MaxLevels);
// empty this line
Pcpts = "";
for (// find out if any are not null at this level
Prcpt = OLvl + 2; // find out if any are not null at this level
Prcpt >= Fired; // find out if any are not null at this level
Prcpt--) {
ping();
if (STM[OLvl][BinId][Prcpt] != NullObject) {
Pcpts = Pcpts + DisplaySTMEntry(OLvl, Prcpt) + " ";
}
}
if (// Only if there was a fired entry
!Pcpts.equals("")) {
// Put level # at start of line
Pcpts = " " + "Lvl=" + StringHelper.trim(String.valueOf(OLvl), ' ') + " " + Pcpts;
tempDisplaySTM = tempDisplaySTM + Pcpts + "\r\n";
} else // else no current entry at this level
{
// terminate the loop
OLvl = MaxLevels;
}
}
tempDisplaySTM = tempDisplaySTM + "\r\n";
}
return tempDisplaySTM;
}
// End of DisplaySTM$()
public final String DisplaySTMEntry(int Percpt, int CurrFired) {
int BinonId;
// unused String BinonSt = null;
var VL = new Var<>("");
BinonId = STM[Percpt][BinId][CurrFired];
GetValue(BinonId, VL);
// display 6 chars of pattern
VL.set(substring(substring(VL.get(), 0, 20) + " ", 0, 7));
return "#" + StringHelper.trim(vbToStr(CurrFired), ' ') + "=" + StringHelper.trim(String.valueOf(STM[Percpt][XQCnt][CurrFired]), ' ') + "x" + StringHelper.trim(String.valueOf(STM[Percpt][TQCnt][CurrFired]), ' ') + DisplayStimulu(BinonId) + " " + VL;
}
// End of DisplaySTMEntry$()
public final String DisplayPattern(int StimBin) {
String tempDisplayPattern;
var BinonTyp = new Var<>("");
var VL = new Var<>("");
int NumChr;
int StimTyp;
StimTyp = BinonTypeOf(StimBin);
if (StimTyp == NullType) {
tempDisplayPattern = " ~ ";
} else if (// Have a type but no binon
StimBin == NullObject) {
GetTypeInfo(StimTyp, BinonTyp, VL);
tempDisplayPattern = VL.get().substring(0, 2) + " ~";
} else {
// Level 2 is 11 characters, level 3 is 17 characters
NumChr = 5 + 6 * (StimTyp - 1);
GetValue(StimBin, VL);
tempDisplayPattern = DisplayStimulu(StimBin) + " " + substring(VL.get(), 0, NumChr);
}
return tempDisplayPattern;
}
// End of DisplayPattern$()
public final String DisplayStimulu(int StimBin) {
String tempDisplayStimulu;
var BTyp = new Var<>("");
var Rdg = new Var<>("");
String Inf;
String Gl;
int StimTyp;
StimTyp = BinonTypeOf(StimBin);
if (StimBin == NullObject || StimTyp == NullType) {
tempDisplayStimulu = "-00";
} else {
GetTypeInfo(StimTyp, BTyp, Rdg);
Gl = StringHelper.trim(Rdg.get().substring(0, 2), ' ') + StringHelper.trim(String.valueOf(StimBin), ' ');
Inf = IntSymb(InterestIn(StimBin));
tempDisplayStimulu = Inf + Gl + AESR(StimBin);
}
return tempDisplayStimulu;
}
// End of DisplayStimulu$()
public final String InterestSymbol(int BinNum) {
int IntIn;
IntIn = InterestIn(BinNum);
return IntSymb(IntIn);
}
// End of InterestSymbol$()
public String IntSymb(Object Intrst) {
String tempIntSymb;
tempIntSymb = ASpace;
switch((Integer) Intrst) {
case NOVEL:
tempIntSymb = chr(254);
break;
case INTERESTING:
tempIntSymb = "!";
break;
case FAMILIAR:
tempIntSymb = "-";
break;
}
return tempIntSymb;
}
// End of IntSymb$()
public // Called by ClearMemory(), ProcessStimuli() and PerformAction()
void ClearExpectations() {
PerceivedBinon = NullObject;
}
// End of ClearExpectations()
public final void FireTheBinon(int PercptLvl, int TheBinon, int TQCount, int XQCount) {
// Called from ProcessStimuli() for the most changed stimulus combination
// Called from CreateCombo which is called by ProcessSTMLevel() every time a familiar stimulus is experienced
// Called from PerformAction() after response produced
// The binon has fired so place it in the Fired entry at this level in the STM, increment its XQ count,
// idle it and make it the most recent target of its left and right source binons.
// A newly created binon can not fire - can not be put on the STM()
int Uselink;
// Make it the most recent target binon of its left and right source binons
ImYourMostRecent(TheBinon, TriggerList);
ImYourMostRecent(TheBinon, GoalList);
if (InterestIn(TheBinon) != NOVEL) {
if (// If a valid binon has fired
TheBinon != NullObject) {
STM[PercptLvl][BinId][Fired] = TheBinon;
if (// should be zero
STM[PercptLvl][XQCnt][Fired] != 0) {
Stop();
}
// It has fired this many times
STM[PercptLvl][XQCnt][Fired] = XQCount;
// trigger firing count for comparison of size of repeaters
STM[PercptLvl][TQCnt][Fired] = TQCount;
// BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text & " + Binon " & _
// DisplayPattern$(TheType, TheBinon) & " Fired" & vbCrLf
//
// Want the PerceivedBinon to be the highest fired Perceptual or Action sequence binon
// that triggers at least one associating binon or the level-1 S or R that has no associating binon
if (// If at level-1 start with the S or R
PercptLvl == 1) {
// Track the trigger of expected goal for the Action
PerceivedBinon = TheBinon;
} else {
if (// If on an odd level - Perceptual - or Action sequence then
isSorR(TheBinon)) {
// determine its first associating binon, if any
Uselink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(TheBinon));
if (// If the fired binon has at least one associating binon
Uselink != NullTarget) {
// Track the trigger of expected goal for the Action
PerceivedBinon = TheBinon;
} else // else use the previously assigned PerceivedBinon
{
}
} else // else we are on an even level - A- or Expectation
{
// Stop
}
}
} else {
// The fired binon should never be null
Stop();
}
} else // else it is novel and can not be put on STM()
{
String Res = (" " + PercptLvl).substring((" " + PercptLvl).length() - 5) + vbToStr(Binons[TheBinon][TriggerCount]) + vbToStr(Binons[TheBinon][GoalCount]) + " " + DisplayPattern(TheBinon) + " NEW" + "\r\n";
World.appendBinonDisplayChngResults("\r\n" + Res);
}
// End If TheBinon is not novel
}
// End of FireTheBinon()
public final void ImYourMostRecent(int HabBinon, int TriggerOrGoal) {
int SourceBinon;
int TgtLink;
int TgtBinon;
int PrevLink;
int FirstLink;
boolean FoundIt = false;
if (TriggerOrGoal == TriggerList) {
// Left source binon - trigger
SourceBinon = Binons[HabBinon][O1];
} else {
// Right source binon - goal
SourceBinon = Binons[HabBinon][O2];
}
if (SourceBinon != NullObject) {
// Find the target binon on the trigger or goal list of the source binon and move it to the front of the list
TgtLink = Binons[SourceBinon][TriggerOrGoal];
FirstLink = TgtLink;
FoundIt = false;
PrevLink = NullTarget;
while (!FoundIt) {
ping();
if (// should have been on the list
TgtLink == NullTarget) {
Stop();
}
// The target binon
TgtBinon = Targets[TgtLink][TargetBinon];
if (// If it matches the HabBinon then found the entry
TgtBinon == HabBinon) {
FoundIt = true;
if (// If not at the start of the list already
PrevLink != NullTarget) {
// remove the TgtLink Targets() entry from linked list
Targets[PrevLink][NLnk] = Targets[TgtLink][NLnk];
// TgtLink Targets() entry points to old first one on list
Targets[TgtLink][NLnk] = FirstLink;
// It is now the 1st one / most recent target of source binon
Binons[SourceBinon][TriggerOrGoal] = TgtLink;
}
} else {
// Link for the previous Targets() entry
PrevLink = TgtLink;
// go to the next link in Targets list
TgtLink = Targets[TgtLink][NLnk];
}
}
}
}
// End of ImYourMostRecent()
public final double MostRecentTriggerTargetLink(int TheBinon) {
double tempMostRecentTriggerTargetLink;
// Called from FireTheBinon() when upadting STM() and DetermineResponse() when thinking
int TgtLink;
// Obtain the link to the most recent (first) target ActBin for the trigger
// The list of all targets for which it is the trigger
TgtLink = Binons[TheBinon][TriggerList];
tempMostRecentTriggerTargetLink = NullTarget;
if (// If TheBinon has any sequential right targets then
Binons[TheBinon][TriggerCount] > 0) {
while (TgtLink != NullTarget) {
ping();
if (// The type of right target binon of the the given stimulus
BinonTypeOf(Targets[TgtLink][TargetBinon]) == ActBin) {
tempMostRecentTriggerTargetLink = TgtLink;
// found the first useful Perceptual sequence - terminate the loop
TgtLink = NullTarget;
} else // else some of the right targets could be Percepts?
{
// skip Percepts
TgtLink = Targets[TgtLink][NLnk];
}
}
}
return tempMostRecentTriggerTargetLink;
}
// End of MostRecentTriggerTargetLink()
public final void GetDHabit(int TheBinon, Var FoundBinon) {
// This finds the level-1 D-Habit or response binon for the given binon (TheBinon - may be an Action) and
// returns it as the expected binon (FoundBinon - may be a D-Habit or response binon)
// unused int NameBinon = 0;
// If it is the NullObject then that is returned
FoundBinon.set(TheBinon);
while (BinonTypeOf(FoundBinon.get()) == ActBin) {
ping();
FoundBinon.set(Binons[FoundBinon.get()][O2]);
}
// Now the Found binon type is a D-Habit binon
}
// End of GetDHabit()
public final // called by PerceptionAction()
void ProcessSTMLevel(// called by PerceptionAction()
int ObjtLvl, // called by PerceptionAction()
int SourceBinon, // called by PerceptionAction()
int AorE, // called by PerceptionAction()
boolean CheckRepeat) {
// If CheckRepeat then determine if the Fired at this level is same as repeat position.
// If it is a repeater then increases its count.
// Then combines the Current and Fired entries and puts them at one level higher in STM
// The fired binon at ObjtLvl is still in Fired position in STM when done.
int Prcpt;
int TQFired;
int XQFired;
int OldPercBin;
int TQRepeat;
int TrgtLvl;
// tmp BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text & Trim(Str$(ObjtLvl)) & "-0a/ Fired binon " & _
// DisplayPattern[SourceType][SourceBinon] + "\r\n";
// check to see if the pattern matches the previous pattern at this level
// if it matches then
// increment the past entry for the repeat and move it up to current
// Repeater at this level will be in this entry position
Prcpt = ObjtLvl;
TrgtLvl = ObjtLvl + 1;
if (// If need to check if an Action or Expectation repeats then
CheckRepeat) {
World.appendBinonDisplayChngResults(StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0c/ Check for repeater Action" + "\r\n");
// Any repeater should be in the correct position = ObjtLvl
OldPercBin = STM[ObjtLvl][BinId][Prcpt];
if (// If the old = Fired it is a repeat binon
OldPercBin == SourceBinon) {
// Trigger quantity (size) of the SourceBinon just fired
TQFired = STM[ObjtLvl][TQCnt][Fired];
// Trigger quantity (size) for the older Prcpt binon
TQRepeat = STM[ObjtLvl][TQCnt][Prcpt];
if (// If the repeater is the same size as the fired one then
TQRepeat == TQFired) {
// tmp BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text & Trim(Str$(ObjtLvl)) & "-0b/ Pattern " & _
// DisplayPattern[SourceType][SourceBinon] + " Repeats" + "\r\n";
// Increment its repeat count by the number of time it fired (duration at level 1)
XQFired = STM[ObjtLvl][XQCnt][Fired];
STM[ObjtLvl][XQCnt][Prcpt] = STM[ObjtLvl][XQCnt][Prcpt] + XQFired;
MoveAmount = MoveAmount + ObjtLvl;
// MoveRight(ObLvl, FromEntry, ToEntry, UpTo)
// repeater ends up in Fired entry
MoveRight(ObjtLvl, Prcpt, Fired, 2 * Prcpt);
// clear the fired next level up
EmptySTM(TrgtLvl, Fired);
} else // same pattern but different size
{
// Stop 'OK - treat as not repeating
// tmp BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text & Trim(Str$(ObjtLvl)) & "-0c/ Pattern " & _
// DisplayPattern(SourceType, SourceBinon) + " does Not repeat" + "\r\n";
}
} else {
// tmp BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text & Trim(Str$(ObjtLvl)) & "-0c/ Pattern " & _
// DisplayPattern(SourceType, SourceBinon) + " does Not repeat" + "\r\n";
}
}
// If it does not repeat
// Then as a goal combine the trigger previous to it at this level
// (if there is a trigger) and place it in the next level up fired position
if (// If there is a trigger previous to the fired location
STM[ObjtLvl][BinId][Current] != NullObject) {
if (// and there is a goal at the repeater position
STM[ObjtLvl][BinId][Fired] != NullObject) {
if (// set to 0 if already used
ObjtLvl > 1 || STM[ObjtLvl][XQCnt][Current] != 0) {
// Place the result in Fired of level above
CreateCombo(ObjtLvl, Current, AorE);
} else {
// why?
Stop();
}
if (Prcpt + 2 <= MaxLevels) {
// Remove used trigger binon
EmptySTM(ObjtLvl, Prcpt + 2);
}
} else // The fired binon is NullObject
{
Stop();
}
}
}
// End ProcessSTMLevel()
public final void MoveRight(int ObLvl, int FromEntry, int ToEntry, int UpTo) {
// Move all the entries at the ObLvl to the right so that the one at FromEntry ends up at ToEntry position
// Null out previous locations, stop when the From Entry reaches the UpTo position
int Prcpt;
int NewPrcpt;
int Distance;
// how far they have to move
Distance = FromEntry - ToEntry;
if (UpTo > MaxLevels) {
UpTo = MaxLevels;
}
for (Prcpt = FromEntry; Prcpt <= UpTo; Prcpt++) {
ping();
NewPrcpt = Prcpt - Distance;
MoveOnePerception(ObLvl, Prcpt, NewPrcpt);
// Nullify where it came from
EmptySTM(ObLvl, Prcpt);
}
}
// End MoveRight()
public final void MoveLeft(int ObLvl) {
// Move all the entries at this ObLvl to the left one position so the Fired is in the Current
int Prcpt;
boolean HaveAPercept = false;
int ToPrcpt;
// assume this level is empty
HaveAPercept = false;
ToPrcpt = ObLvl + 2;
if (ToPrcpt >= MaxLevels) {
ToPrcpt = MaxLevels - 1;
}
for (Prcpt = ToPrcpt; Prcpt >= Fired; Prcpt--) {
ping();
if (STM[ObLvl][BinId][Prcpt] != NullObject) {
HaveAPercept = true;
}
// Move it left one position
MoveOnePerception(ObLvl, Prcpt, Prcpt + 1);
}
// and clear the fired entry
EmptySTM(ObLvl, Fired);
if (!HaveAPercept) {
TopLevel = TopLevel - 1;
}
}
// End MoveLeft()
public final void MoveOnePerception(int ObLvl, int FromEntry, int ToEntry) {
STM[ObLvl][BinId][ToEntry] = STM[ObLvl][BinId][FromEntry];
STM[ObLvl][XQCnt][ToEntry] = STM[ObLvl][XQCnt][FromEntry];
STM[ObLvl][TQCnt][ToEntry] = STM[ObLvl][TQCnt][FromEntry];
}
// End of MoveOnePerception()
public void EmptySTM(int OLvl, int PrevCurrFired) {
STM[OLvl][BinId][PrevCurrFired] = NullObject;
STM[OLvl][XQCnt][PrevCurrFired] = 0;
STM[OLvl][TQCnt][PrevCurrFired] = 0;
}
// End of EmptySTM()
public final void CreateCombo(int ObjtLvl, int TrigPrcpt, int AorE) {
// If it is possible, Combine the trigger (Current) and goal (Fired) binons in the STM()
int TriggerBinon;
int TQNum;
int IntInTrig;
int Bin12;
int TQCount;
int GoalBinon;
int GQNum;
int IntInGoal;
int Bin21;
int Prev1LogRpts;
int Prev2LogRpts;
int RptsDiff;
var ResultBinon = new Var<>(0);
int TgtLvl;
var NewBee = new Var<>(false);
int Bin11;
int Bin22;
boolean CombineThem = false;
// Returned NullObject if not found or created
ResultBinon.set(NullObject);
TriggerBinon = STM[ObjtLvl][BinId][TrigPrcpt];
if (ObjtLvl == 1) {
// wait until it has stopped repeating
STM[ObjtLvl][TQCnt][TrigPrcpt] = STM[ObjtLvl][XQCnt][TrigPrcpt];
}
if (// If have a trigger pattern then
TriggerBinon != NullObject) {
GoalBinon = STM[ObjtLvl][BinId][TrigPrcpt - 1];
if (// and if have a goal pattern then
GoalBinon != NullObject) {
IntInTrig = InterestIn(TriggerBinon);
IntInGoal = InterestIn(GoalBinon);
if (// if both familiar then
IntInTrig == FAMILIAR && IntInGoal == FAMILIAR) {
Bin12 = Binons[TriggerBinon][O2];
Bin21 = Binons[GoalBinon][O1];
// If at source level 2 or higher they must overlap
// or they are adjacent at source level = 1
if ((ObjtLvl > 1 && Bin12 == Bin21) || ObjtLvl == 1) {
// When the 1st binon left source is specific enough to uniquely predict its next stimulus
// and the 2nd binon right source is specific enough to uniquely predict its previous stimulus and
// when the common source binon (Bin12 = Bin21) uniquely predicts both its goal and
// trigger binon then stop combining the trigger (TriggerBinon) with the goal (GoalBinon).
CombineThem = true;
if (ObjtLvl > 1) {
CombineThem = false;
Bin11 = Binons[TriggerBinon][O1];
Bin22 = Binons[GoalBinon][O2];
if (// ****** NOTE add True to the condition to turn off
Binons[Bin11][TriggerCount] != 1 || Binons[Bin22][GoalCount] != 1 || Binons[Bin21][TriggerCount] != 1 || Binons[Bin21][GoalCount] != 1) {
CombineThem = true;
}
}
if (CombineThem) {
// the repeat value of the trigger - XQ count
TQNum = STM[ObjtLvl][XQCnt][TrigPrcpt];
// the repeat value of the goal - XQ count
GQNum = STM[ObjtLvl][XQCnt][TrigPrcpt - 1];
// Use the trigger and goal binons to create a new binon with
// the correct ratio and place it in the Fired perception at the TgtLvl
TgtLvl = ObjtLvl + 1;
// Trigger
Prev1LogRpts = Buckit(TQNum, SizeBase);
// Goal
Prev2LogRpts = Buckit(GQNum, SizeBase);
// Adjacent repeat quantities are used to produce a ratio - same as:
// QtyDiff = Int(Abs(Prev1LogRpts - Prev2LogRpts) / 100)
// the difference in the Logs = ratio of repeats
// If Prev2LogRpts > Prev1LogRpts Then RptsDiff = -RptsDiff 'keep the sign
// Trigger minus Goal Logs
RptsDiff = (Prev1LogRpts - Prev2LogRpts) / 100;
// The new binon is Active but Idle - waiting for a repeat
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
IdBinons(TgtLvl, ActBin, TriggerBinon, TQNum, GoalBinon, GQNum, RptsDiff, Sequential, AorE, ResultBinon, NewBee);
// The binon has fired so place it in the Fired entry at the target level, increment its XQ count,
// idle it and make it the most recent target of its trigger and goal.
// The size of the lowest level left part
TQCount = STM[ObjtLvl][TQCnt][TrigPrcpt];
// Add the fired stimulus to the Perceived STM().
// FireTheBinon will set the XQ count and the PerceivedBinon.
// FireTheBinon(PercptLvl, TheBinon&, TQCnt, XQCnt)
// will set the XQ count
FireTheBinon(TgtLvl, ResultBinon.get(), TQCount, 1);
}
}
// End if they overlap properly
}
// End if they are both familiar
} else // Else the fired one is Nullobject
{
// It should not be possible for fired one to be NullObject '
Stop();
}
// End if the goal binon exists
} else // Else the trigger is NullObject
{
// It should be not NullObject - already checked in ProcessSTMLevel()
Stop();
}
// End if the trigger binon exists
}
// End of CreateCombo()
public final void ReportObjects1() {
// Report information after perception and attention - before practice
// Reports only the objects perceived in BinonDisplay.ChngResults
String Res;
String Ptrn;
int ExprObj;
// -------------------------- Status of perception before attending to the stimuli --------------
if (Processing50) {
return;
}
World.appendBinonDisplayChngResults("\r\n" + " # EObj Pattern - Fired Binon List" + "\r\n");
Res = "";
for (var J = 1; J <= HighestPerceptLvl; J++) {
ping();
ExprObj = STM[J][BinId][Current];
if (ExprObj != NullObject) {
Ptrn = "";
if (// If we have an expected binon at this level then
ExprObj == PerceivedBinon) {
Ptrn += " This is the Perceived or Performed Binon";
}
Res = Res + (" " + J).substring((" " + J).length() - 5) + vbToStr(Binons[ExprObj][TriggerCount]) + vbToStr(Binons[ExprObj][GoalCount]) + " " + DisplayPattern(ExprObj) + " " + Ptrn + "\r\n";
}
}
World.appendBinonDisplayChngResults(Res + "\r\n");
}
// End ReportObjects1()
public final void ReportObjects2() {
// Report after Pass 2 - after prerceiving stimulus, doing response and expecting a stimulus
// Reports on Objects in ObjList textbox
StringBuilder Res2 = new StringBuilder();
var Rdgs = new Var<>("");
StringBuilder Res1;
String Ptrn;
String IntInfo;
var VL = new Var<>("");
var Ty1 = new Var<>("");
var Ty2 = new Var<>("");
// unused String BN = null;
// unused String Brand = null;
int BnTyp;
int Objct;
var BinTyp = new Var<>("");
int ObjLvl;
// unused int Prcpt;
int TypInteger;
String Inf = null;
// -------------------- The binon list after being processed ------------
if (Processing50) {
return;
}
// Fill in Binon list in BinonDisplay.ObjList.Text
int NumChr;
for (// Property binons and Percept combinations, Perceptual sequences and Responses
BnTyp = 1; // Property binons and Percept combinations, Perceptual sequences and Responses
BnTyp <= NumBinonTypes; // Property binons and Percept combinations, Perceptual sequences and Responses
BnTyp++) {
ping();
// Rdgs$ = abbreviation - not used - use BinTyp$ only
GetTypeInfo(BnTyp, BinTyp, Rdgs);
Res2.append(BnTyp).append(", ").append(Rdgs).append(BinTyp).append("\r\n");
for (// For each level of binons
ObjLvl = 1; // For each level of binons
ObjLvl <= MaxLevels; // For each level of binons
ObjLvl++) {
ping();
Res1 = new StringBuilder();
for (// For all binons
Objct = 1; // For all binons
Objct <= NumBinons; // For all binons
Objct++) {
ping();
Ptrn = "";
if (// if have a binon at this level then
Binons[Objct][OLv] == ObjLvl) {
if (BinonTypeOf(Objct) == BnTyp) {
Inf = "";
VL.set("");
GetValue(Objct, VL);
// Level 2 is 11 characters, level 3 is 17 characters
NumChr = 5 + 6 * (Binons[Objct][OLv] - 1);
// display 14 chars of pattern
Ptrn = substring(VL.get(), 0, NumChr);
if ((Ptrn == null ? 0 : Ptrn.length()) == 1) {
Ptrn = " " + Ptrn;
}
TypInteger = BinonTypeOf(Binons[Objct][O1]);
GetTypeInfo(TypInteger, Ty1, Ty1);
TypInteger = BinonTypeOf(Binons[Objct][O2]);
GetTypeInfo(TypInteger, Ty2, Ty2);
IntInfo = InterestSymbol(Objct);
Res1.append(substring(" " + Objct, (" " + Objct).length() - 3)).append(substring((" " + Binons[Objct][OLv]), (" " + Binons[Objct][OLv]).length() - 3)).append(AESR(Objct)).append(" ").append(substring(Ty1.get(), 0, 2)).append(substring(" " + Binons[Objct][O1], (" " + Binons[Objct][O1]).length() - 3)).append(" ").append(substring(Ty2.get(), 0, 2)).append(substring(" " + Binons[Objct][O2], (" " + Binons[Objct][O2]).length() - 3)).append(substring(" " + Binons[Objct][IDL], (" " + Binons[Objct][IDL]).length() - 4)).append(takeLast(2, vbToStr(Binons[Objct][TriggerCount]))).append(takeLast(2, vbToStr(Binons[Objct][GoalCount]))).append(substring(" " + IntInfo, (" " + IntInfo).length() - 3)).append(substring(" " + Binons[Objct][TQ], (" " + Binons[Objct][TQ]).length() - 3)).append(substring(" " + Binons[Objct][GQ], (" " + Binons[Objct][GQ]).length() - 3)).append(" ").append(Ptrn).append(" ").append(DisplayHabit(Objct)).append("\r\n");
}
}
// End if it is this Binon type
}
if (!StringHelper.isNullOrEmpty(Res1.toString())) {
Res2.append(Res1).append("\r\n");
}
}
Res2.append("\r\n");
}
// value set above
World.setBinonDisplayObjList(Res2.toString());
}
// End of ReportObjects2()
public final String AESR(int Objct) {
String tempAESR;
if (// AE property is 0 for parallel binons
BinonTypeOf(Objct) <= NumPercepts) {
// Level 1 Percept or property binon
tempAESR = " P";
} else {
// level 1 Response binon = LetrBin
tempAESR = " A";
}
if (// AE not assigned for level 1 Stimuli or Responses
Binons[Objct][AE] == Action) {
if (// two letters refer to types/roles of source binons
!isSorR(Objct)) {
// Action binon
tempAESR = " A";
} else {
// Action sequence
tempAESR = " AA";
}
} else if (Binons[Objct][AE] == Attention) {
if (!isSorR(Objct)) {
// Expectation binon
tempAESR = " E";
} else {
// Perceptual sequence
tempAESR = " PP";
}
}
return tempAESR;
}
// End of AESR$()
public final boolean isSorR(int Objct) {
// If the binon is at an odd sequential level then it is either an S or R
// If the binon is at an even sequential level then it is either an A or an E
// If the binon is not sequential (an ActBin) then it is either an S or R
// remainder is 1 if odd level, 0 if even level
return Binons[Objct][OLv] % 2 == 1 || BinonTypeOf(Objct) != ActBin;
}
public final String DisplayHabit(int ObjBin) {
StringBuilder tempDisplayHabit;
// Displays the list of target binons for which this one is the left source and / or right source
int Link;
// unused int Bin = 0;
tempDisplayHabit = new StringBuilder();
// Display the list of target binons this one triggers
// does the binon trigger at least one target binon
Link = Binons[ObjBin][TriggerList];
while (Link != NullTarget) {
ping();
// add target binon type and objID
tempDisplayHabit.append("l").append(DisplayStimulu(Targets[Link][TargetBinon]));
// go to the next one on the list
Link = Targets[Link][NLnk];
if (Link != NullTarget) {
tempDisplayHabit.append(", ");
}
}
// does the binon goal at least one target binon
Link = Binons[ObjBin][GoalList];
if (Link != NullObject && !StringHelper.isNullOrEmpty(tempDisplayHabit.toString())) {
tempDisplayHabit.append(", ");
}
while (Link != NullTarget) {
ping();
// add target binon type and objID
tempDisplayHabit.append("r").append(DisplayStimulu(Targets[Link][TargetBinon]));
// go to the next one on the list
Link = Targets[Link][NLnk];
if (Link != NullTarget) {
tempDisplayHabit.append(", ");
}
}
return tempDisplayHabit.toString();
}
// End of DisplayHabit()
public final // Called from PerceptionAction()
void DetermineResponse() {
// Enter here if finished pass 1/ STM processing then based on the recognized Perceptual sequence or Expectation find any
// predicted action and use this highest level Action or Action sequence found worth doing and
// do its lowest level response in PerformAction().
// Or if the predicted action is learnt / familiar then use thinking (deduction) and find one worth doing
// Put this response Action sequence in STM(level 1, Fired) and start pass 2
int FirstLink;
int Thinklink;
int ThinkBinon;
// unused int EndLink = 0;
String Reason = null;
// unused int GoalBinon = 0;
// unused int TrigTargetBinon = 0;
// The binon being practiced. Concentration Level is based upon it.
var PracticingBinon = new Var<>(0);
int DoneBinon;
var NewBee = new Var<>(false);
int OutType;
int UL;
int ll;
int NextResponse;
var ResponseBinon = new Var<>(0);
int I;
int CurrentResponse;
int UseResponse;
int HaveResponse;
int NumberOfResponses;
String ThisResponse = null;
// FireTheBinon() will have found any response worth doing and PerceivedBinon will be the level
// for the Perceptual sequence trigger to find the response to do.
// The Practicing binon may be the NullObject because no Actions were being performed.
// This happens when there are no Actions for the stimulus as the trigger.
// This means no expectation. After a stimulus is familiar and the one following it is also familiar then
// we have a novel Action for the trigger and at least have one expectation
// Note: it should be just the perceived binon that is used based on any number >0 triggercount
// the interest in redoing its most recent determines if need to practice it. triggercount=1 needed to
// do deductions - certain / reliable inference, if >1 then just the most recent possible goal is used
// and this gives induction reasoning - no certainty because sometime in the past at least one different goal has happened
// even after thinking then babble
PracticingBinon.set(NullObject);
// If have a perceived binon (it is an Perceptual sequence) with associating Action binons then
// check to see if it is worth doing - if not then think
// The right target binon link - if any
FirstLink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(PerceivedBinon));
if (// If have a link to a recent right target Action binon then
FirstLink != NullTarget) {
// This must be an Action
PracticingBinon.set(Targets[FirstLink][TargetBinon]);
if (// If it is worth doing then
InterestIn(PracticingBinon.get()) > FAMILIAR) {
Reason = " STM Perceived binon is the trigger of its most recent novel Action";
// use PracticingBinon below by calling ActivateAction()
} else // else the binon is not worth practicing so think about it
{
// #1 Approach: ----------------------------
// An alternate approach here is to go up the most recent right target binons of the tree
// looking for an Action that is novel and if found then activate all the right targets traversed so
// that the sequence is done at a concentration level to repeat / learn the novel one.
// Let us just try one traversal up this right target binon tree via the intermediate Perceptual sequence.
// The right target binon link - if any
Thinklink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(PracticingBinon.get()));
// This will be an Perceptual sequence - but we need to go up one more level to the Action - if any
if (// If there is a right target link to an associating binon then
Thinklink != NullTarget) {
ThinkBinon = Targets[Thinklink][TargetBinon];
// The right target Action binon link - if any
Thinklink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(ThinkBinon));
} else // Else no right target Perceptual sequence binon
{
}
// #2 Approach: ----------------------------
// Obtain the response that could be performed and see if it triggers an Expectation (stimulus) worth expecting
// 2 GoalBinon = Binons[PracticingBinon][O2] 'The goal that could be done - Action sequence
// 2 Thinklink = MostRecentTriggerTargetLink(GoalBinon) 'Does it have a right target - an Expectation
// 2 Reason$ = " Thought about associated goal of STM perceived is trigger of a most recent novel Expectation"
// -----------------------------------------
if (// If there is a right target link to an associating binon then
Thinklink != NullTarget) {
// The Approach#1 Action or Approach#2 Expectation to practice
ThinkBinon = Targets[Thinklink][TargetBinon];
if (// if the next A- or Expectation is worth expecting then
InterestIn(ThinkBinon) > FAMILIAR) {
// there is a next Perceptual sequence to expect so do the current Action - PracticingBinon
// use PracticingBinon below by calling ActivateAction()
Reason = " Thought about right target of STM perceived is trigger of a most recent novel Action";
} else // Else the next Action sequence (goal of PracticingBinon) is not worth doing so
{
// do not do the practicing binon - it is familiar / learnt
PracticingBinon.set(NullObject);
}
// End if the next binon was worth doing
} else // else there is no next possible stimulus - no associating Expectation so
{
// do not do the practicing binon - it is familiar / learnt
PracticingBinon.set(NullObject);
}
// End if there was no next Perceptual sequence to expect
}
// End if the associating Action (PracticingBinon) is worth doing
} else // Else no right target link of PerceivedBinon - no PracticingBinon
{
}
// End of Is there a right target link of Perceived binon
// If don't have a binon to practice, even after thinking, then find something to do or babble
if (// If the PracticingBinon is still a NullObject then
PracticingBinon.get() == NullObject) {
Reason = "";
// If the Practicing Binon is null because the highest STM recognized Perceptual sequence (PerceivedBinon)
// has no associating Action binons (is novel or familiar but followed by a novel binon) then
// we do nothing to see if it repeats
int DeviceNum;
if (// If there is no associating binons for the perception
FirstLink == NullTarget) {
// so use the 1st device and its first symbolic or range response, PracticingBinon must be set
// Letters = LetrBin
DeviceNum = 1;
// Currently = Wheels for device #1
OutType = Devices[DeviceNum][PropertyBinonType];
if (// Use Range of values
Devices[DeviceNum][SymbolicOrMagnitude] == Magnitude) {
NextResponse = Devices[DeviceNum][LowerRangeLimit];
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
IdBinons(1, OutType, NullObject, 0, NullObject, 0, NextResponse, Parallel, 0, PracticingBinon, NewBee);
} else // If Devices[DeviceNum][SymbolicOrMagnitude] = Symbolic Then 'Use first response values
{
// Will be a NoResp$
String Letter = DeviceResponses[DeviceNum].substring(0, 1);
// Letter$ = NoResp$
// Create or find the binon for this symbolic value
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
IdBinons(1, OutType, NullObject, 0, NullObject, 0, asc(Letter), Parallel, 0, PracticingBinon, NewBee);
}
Reason = " First response of first action device - Babbling";
} else // else have an associating Action sequence for PerceivedBinon then
{
// Find the most recent response at the lowest level and use the next one
// The Action most recently practiced at the next level up
DoneBinon = Targets[FirstLink][TargetBinon];
// GetDHabit returns the lowest level response binon in ResponseBinon
// Get the level 1 most recent response done
GetDHabit(DoneBinon, ResponseBinon);
// the device number for this response type binon
DeviceNum = BinonTypes[BinonTypeOf(ResponseBinon.get())][SensOrDevNum];
if (// Use Range of values
Devices[DeviceNum][SymbolicOrMagnitude] == Magnitude) {
ll = Devices[DeviceNum][LowerRangeLimit];
UL = Devices[DeviceNum][UpperRangeLimit];
if (// If it is the no response then
Binons[ResponseBinon.get()][IDL] == NoResp) {
NextResponse = ll;
} else {
NextResponse = Binons[ResponseBinon.get()][IDL] + 1;
if (// if off end of valid values then
NextResponse > UL) {
// wrap around to start again
NextResponse = ll;
}
}
// Create or find the binon for this symbolic value
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
IdBinons(1, BinonTypeOf(ResponseBinon.get()), NullObject, 0, NullObject, 0, NextResponse, Parallel, 0, PracticingBinon, NewBee);
} else // If Devices[DeviceNum][SymbolicOrMagnitude] = Symbolic Then 'Use given response values
{
// Find the last one used
CurrentResponse = 0;
NumberOfResponses = DeviceResponses[DeviceNum].length();
for (// go through the response string
I = 1; // go through the response string
I <= NumberOfResponses; // go through the response string
I++) {
ping();
if (Binons[ResponseBinon.get()][IDL] == asc(DeviceResponses[DeviceNum].substring(I - 1, I - 1 + 1))) {
CurrentResponse = I;
// terminate the loop
I = NumberOfResponses;
}
}
// Find the next non "z" entry
UseResponse = CurrentResponse;
// will be set to the next response entry position
HaveResponse = 0;
// 'A random response generator
// While HaveResponse = 0
// UseResponse = Int(NumberOfResponses * Rnd + 1) 'generate a number between 1 and and NumberofResponses
// ThisResponse$ = Mid$(DeviceResponses$(DeviceNum), UseResponse, 1)
// 'if it is a response that can be done and not a repeat of the last one chosen then
// If ThisResponse$ <> NoMoveOrTurn$ And UseResponse <> CurrentResponse Then
// HaveResponse = UseResponse 'a non-zero value will terminate the loop
// End If
// Wend
// Sequentially go through the available responses
while (HaveResponse == 0) {
ping();
UseResponse = UseResponse + 1;
if (// if off the end of the string then
UseResponse > NumberOfResponses) {
// start at the beginning again
UseResponse = 1;
}
ThisResponse = DeviceResponses[DeviceNum].substring(UseResponse - 1, UseResponse - 1 + 1);
if (// if it is a response that can be done then
!ThisResponse.equals(NoMoveOrTurn)) {
// a non-zero value will terminate the loop
HaveResponse = UseResponse;
}
}
// Create or find the binon for this symbolic value
// IdBinons(OLvl, Prt, Obj1&, TQNum, Obj2&, GQNum, IDLRatio, SeqOrPar, ExpectIt, ObjId&, NewOne As Boolean)
IdBinons(1, BinonTypeOf(ResponseBinon.get()), NullObject, 0, NullObject, 0, asc(ThisResponse), Parallel, 0, PracticingBinon, NewBee);
}
Reason = " Babbling";
}
// End if have no associating Action sequence
} else // Else have a binon to practice so do that one
{
}
// End if do not have a PracticingBinon
// Report on what is being practiced - if anything
if (// If practicing then
PracticingBinon.get() != NullObject) {
World.appendBinonDisplayChngResults(" * Practicing " + DisplayPattern(PracticingBinon.get()) + Reason + "\r\n");
} else {
Stop();
World.appendBinonDisplayChngResults(" * Not Practicing anything" + "\r\n");
}
// If have no action to practice at this point then PerformAction() will respond with nothing
// Perform the response and fire the binon to STM(1, Fired)
ActivateAction(PracticingBinon.get());
// Old notes
// If we are practicing (concentrating on) an Action then this active sequence will have a goal
// that it is trying to achieve. This is the goal of the most recent target binon (Action) triggered by the
// previously perceived/attended-to stimulus. It is the prediction, the expectation.
// The concentration level will be based on the wanted / pleasant (desirability) level of the goal or
// interest level (novel, interesting or familiar) of the redo interest of the Action being practiced.
// When practicing / concentrating we will only attend to the expected goal of the Action being practiced.
// All of the triggered target binons of the attended to stimulus are active / expecting but only the most recent one
// is being practiced, goal expected.
// If any expecting Action (including the one being practiced) does not get its expected goal then it becomes inactive.
// The binon recognized (fired) instead will be on the Percepts() list and attract attention.
// Thus the possible outcomes are:
// O1 - Get the expected goal of the practicing Action binon (PracticingResult$ = "Matched"
// O2 - Get the goal of a different triggered Expecting target Action binon (same triggering / attended-to binon)
// O3 - All expecting Actions could fail
// O3a - get a familiar goal stimulus but it is a novel sequence for the attended-to as the trigger
// O3b - get a novel or interesting stimulus at the AttendToLevel or lower.
// Note: you can be attending to a stimulus but not practicing because there are no right target Action binons
// of the attended-to stimulus.
// Note: only target Sequence / Action binons can be performed / practiced - not target property binons
// If concentrating - no expecting binon got its goal so - Outcome O3
// we find the "got-instead" goal
// This "got-instead" goal binon is the one obtained instead of the expected goal
// or if that is not available (a NullObject) then it is the next attended-to stimulus (the novel one produced).
// The logic should be:
// 1 If practicing an Action then (PracticingResult$ will be set Matched or Failed)
// When practicing an Action you are paying attention / focusing on / expecting a stimulus from sense of its goal
// 2 If it matched its goal and the goal has finished repeating then focus / pay attention to its goal. [set as AttendTo]
// Reduce its interest / novelty level.
// Can not be distracted because paying attention to the goal sense (change blindness) and got the goal?
// Or will any stimulus not expected by any of the other Actions (not being practiced) distract you? [set AttendTo]
// else it failed to match / get the goal of the practicing binon so
// the one being practiced stays at the same interest level.
// The actual sequence experienced becomes the most recent one (but no change in its interest level).
// Attention is paid to the stimulus "got-instead" of the goal at the same sense as the goal unless
// there is a stimulus that distracts you from this. [set AttendTo]
// Else not practicing so
// Pay attention to the most interesting - attractive? stimulus [set AttendTo]
// End
//
// ' The interest in a sequence is only reduced if it is the one being practiced and the goal is matched.
// ' What about another sequence that has the same trigger and its goal is expected but it is not the one being
// ' practiced but it is the one that is matched? It stays novel. If it becomes the most recent it will be practiced
// ' the next time its trigger occurs.
// 'If not practicing (e.g. due to a novel or interesting attended-to stimulus) then
// ' Attend to the most attractive perception
// ' If the attendto is novel or interesting, it can not be the left source for any target binons
// ' and has no goals.
// ' If the attendto is a novel Percept then we must remain not practicing (ConcentrationLevel = NoInterest).
// ' If the attendto is an Action then pay attention to the goal stimulus that caused the novel
// ' sequence. It will be familiar. Start practicing any
// ' If the attendto is familiar then
// ' use it as the trigger and its most recent sequential right target as an Action worth practicing.
// ' Set the concentration level based on the wanted (pleasant) goal (must be familiar) or
// ' the interest level of the most recent Action right target to practice.
// ' Its goal is the expectation. That is what is being predicted.
// ' If the interest / concentration level is familiar then use thinking to search for something
// ' more interesting to do
// ' end if
// 'end if
//
// ' If was practicing - failed or matched will have no AttendTo and Expected = goal set, PracticingBinon = NullObject
// ' - repeating trigger or goal and not interrupted then PracticingBinon will be set
// ' If not practicing AttendTo is not set, PracticingBinon = NullObject and ExpectedBinon = NullObject
// ' 10a. THINKING:
// ' If still no Action worth practicing then find one through thinking.
// ' Find an Action that will lead to one that needs practicing or that will produce a
// ' rewarding final goal stimulus.
// ' Pay attention to the goal stimulus of the most recent Action of the attended-to stimulus and
// ' treat it as though it was the attended-to stimulus and repeat steps 8 and 9 above.
// ' This is thinking of the goal by traversing the Actions for this stimulus as the trigger.
// ' This repeats until we come across an Action that has a desirable redo interest or
// ' a pleasant expected goal stimulus.
// ' There will be a limit on this looping to begin with. Some other criterion is required
// ' to stop this thinking. It must stop if it loops around to an already thought about Action.
// ' If it is successful the first thought about Action will be selected for performing in step 11
// ' as the active practicing Action at the appropriate concentration level.
// ' In a real-time system a thinking loop may continue until it is interrupted by an unexpected stimulus.
// ' Should the thinking loop also select additional Actions or should they only be started by a conscious stimulus?
// ' Where does boredom fit in - results from repetition of a conscious stimulus?
// ' Or if we have a limited number of thinking steps we may not find an Action worth doing.
// ' Should thinking be done after or before investigating the parts of the attended-to in step 9?
// ' Thinking is based on recalling the goal stimulus of the most recent Action
// ' for the attended-to stimulus and letting the interest in this goal stimulus determine whether to
// ' perform the Action. Should we store the thought as a thought so that it can be repeated
// ' if successful and learnt?
// ' We are bored when the only Action we have to do is a familiar one or there is no Action to do.
// ' If we get the expected goal of a familiar Action then the sequence is the next trigger.
//
// ' Also might consider the situation where do have a conscious active Action but it is being done at the
// ' interesting level and thinking produces a novel one to practice - if this is logically possible.
}
// End of DetermineResponse()
public class Bodies {
//
// Called to assign the different body configuration parameters
// Called to perform each sense/response action cycle by World.Go_Click()
//
//
// World data moved here because it can't be put in World form
// The positions of the world as appearing
String[][] WP = new String[40 + 1][40 + 1];
// in the Current World grid, a ABlock$ = "#" indicates
// the location is a blacked out square
// Label NG(0 To 383)
// Number Grid is stored in linear array of Labels NG(0) to NG(383)
// that have no borders. These contain the location letters that can be displayed.
// Label CWP(0 To 511)
// World Grid is stored in linear array of Labels CWP(0)->CWP(511)
// that have borders and can contain letters. The background colour is black for a block and light blue
// for the cursor. The CWP.Caption = "S" for where Smarty is.
String MaxBodies;
String BExternal;
int InputSense;
void BodyAssignStimuli() {
// Fills in the Values$() with KIN$() from last response
int Sens;
var Stimuli = new Var<>("");
// Public NumSenses 'The number of physical senses, Max of 8, set in SetUpSense()
// 'Currently equals the NumProperties since each sense currently = 1 property type
// Public MaxSenses 'Maximum number of senses = max 8 physical senses
// Public Sense$(1 To 8) 'Names of senses, up to 8 physical senses
// Public IsSense '1, Flag for Senses versus Devices
//
// Public Senses(1 To 8, 1 To 8) 'Properties of the different senses
// '1st index = Sense number
// '2nd index = Sense property
//
// '---- Senses() - 2nd index values - Sense Properties
// Public PropertyBinonType '1, Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin
// Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator
// Public LowerRangeLimit '3, Lower limit of range of values, zero is minimum (65 = "A")
// Public UpperRangeLimit '4, Upper limit of range of values, 255 is maximum (90 ="Z")
// Public LinearOrCircular '5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360)
// Public IntegersOrLogs '6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
// Public NumberOfSensors '7 Number of sensors in sensor array
// Public SensorsDependentOrIndependent '8 are sensors adjacent (dependent) or independent
// Public SensorValues[1 To 8][1 To 2][0 To 1] 'Stimulus values from senses/sensors
// '1st index is sense number, currently = property binon type
// '2nd index is what type of information is in the SensorValues(), XQCnt or Valu
// '3rd index is Fired for the most recent stimulus value and Current for the previous
//
// '---- SensorValues 2nd index values - type of information in SensorValues()
// Public XQCnt '=1, the count of times the value has repeated, also used below
// Public Valu '=2, the value for the stimulus, if symbolic then value = Asc(Symbol$)
// Public NoName$ '"_", The character used when no letter provided for the IDL value of a TextBin binon
//
// '---- SensorValues 3rd index values - which past stimulus it is - also used below
// Public Fired '=0 'stimulus put in this level upon firing before being processed
// Public Current '=1 'The Fired one becomes the Current one after processing
LIN = LIN + 1;
for (// For each sense
Sens = 1; // For each sense
Sens <= NumSenses; // For each sense
Sens++) {
ping();
if (Senses[Sens][SymbolicOrMagnitude] == Magnitude) {
// get the stimuli from body senses
GetStimuli(Sens, Stimuli);
// Stimuli$ = Chr$(of the range to far wall)
SensorValues[Sens][XQCnt][Fired] = 1;
// one character per sense
SensorValues[Sens][Valu][Fired] = asc(Stimuli.get());
// convert to "1" to "8"
INPUTS[LIN][Sens] = chr(SensorValues[Sens][Valu][Fired] + 48);
} else // Else Symbolic input
{
// Setup a motion sense if WheelsConfig.AddAWheelSensor = 1 is checked
if (// If its name is the sense of motion then
Sense[Sens].equals("Motion")) {
SensorValues[Sens][XQCnt][Fired] = 1;
SensorValues[Sens][Valu][Fired] = asc(Motion);
} else // else it is some other symbolic sense
{
// get the stimuli from body senses
GetStimuli(Sens, Stimuli);
SensorValues[Sens][XQCnt][Fired] = 1;
// one character per sense
SensorValues[Sens][Valu][Fired] = asc(Stimuli.get());
}
INPUTS[LIN][Sens] = chr(SensorValues[Sens][Valu][Fired]);
}
}
}
// End of BodyAssignStimuli()
public final // called from World.Go to perform a cycle
void BodyFunction2() {
// This routine determines the current stimuli and changes the body's state
// based on which body is currently being used.
String CurrentPlace = null;
char Kn;
char Resp;
// Smarty0$ body has a sensor that looks under at the current square and
// moves Up, Down, Left or Right. Always displayed as an O
// If a body can turn and change the direction it is pointing
// then it is displayed as an ^, >, <, or v
CurrentPlace = World.LookUnder();
// Public DeviceValues(1 To 8, 1 To 2) 'Response values for devices
// '1st index is device number, currently = response property binon type
// '2nd index is what type of information is in the DeviceValues(), XQCnt or Valu
//
// '---- DeviceValues 2nd index values - type of information in DeviceValues() - DEFINED ABOVE
// ' Public XQCnt '=1, the count of times the value needs repeating, also used below
// ' Public Valu '=2, the value for the response, if symbolic then Symbol$ = Chr$(value)
// Public NoResp$ '"-", The character representing no response for a LetrBin binon
// fills in the Values$() from the senses and
BodyAssignStimuli();
// the Motion$ from last response if turned on
PerceptionAction(SensorValues, DeviceValues);
if (NumDevices > 1) {
Stop();
}
Resp = (char) DeviceValues[1][Valu];
Kn = Resp;
switch(// Motion$ will be set by the World.Move routines
Resp) {
case NoResp:
// = Mid$(WheelMovement$, 1, 1)
Motion = NoMove;
break;
case MoveForward:
switch(BodyPointing) {
case East:
World.MoveEast();
break;
case South:
World.MoveSouth();
break;
case West:
World.MoveWest();
break;
case North:
World.MoveNorth();
break;
}
if (Motion.equals("Y")) {
Motion = WheelMovement.substring(1, 2);
}
break;
case MoveToLeft:
switch(BodyPointing) {
case East:
World.MoveNorth();
break;
case South:
World.MoveEast();
break;
case West:
World.MoveSouth();
break;
case North:
World.MoveWest();
break;
}
if (Motion.equals("Y")) {
Motion = WheelMovement.substring(2, 3);
}
break;
case MoveToRight:
switch(BodyPointing) {
case East:
World.MoveSouth();
break;
case South:
World.MoveWest();
break;
case West:
World.MoveNorth();
break;
case North:
World.MoveEast();
break;
}
// WheelMovement$ = "-flrb" & rotate left, right and around 180 degrees
if (Motion.equals("Y")) {
Motion = WheelMovement.substring(3, 4);
}
break;
case MoveBackward:
switch(BodyPointing) {
case East:
World.MoveWest();
break;
case South:
World.MoveNorth();
break;
case West:
World.MoveEast();
break;
case North:
World.MoveSouth();
break;
}
if (Motion.equals("Y")) {
Motion = WheelMovement.substring(4, 5);
}
break;
case // rotate right 90 degrees
TurnRght:
BodyPointing = BodyPointing + 1;
if (BodyPointing == 4) {
BodyPointing = 0;
}
// a rotate always happens
Motion = WheelMovement.substring(5, 6);
break;
case // rotate left 90 dgrees
TurnLft:
BodyPointing = BodyPointing - 1;
if (BodyPointing == -1) {
BodyPointing = 3;
}
// a rotate always happens
Motion = WheelMovement.substring(6, 7);
break;
case // rotate around 180 degrees
TurnArnd:
BodyPointing = BodyPointing + 2;
if (BodyPointing == 4) {
BodyPointing = 0;
}
if (BodyPointing == 5) {
BodyPointing = 1;
}
// a rotate always happens
Motion = WheelMovement.substring(7, 8);
break;
}
// Case Resp$
// Orient body pointer on world view if wheels turn
if (WheelsTurn) {
switch(// direction body is pointing, 0=East, 1=South, 2=West, 3=North
BodyPointing) {
case East:
// >
World.PointEast();
break;
case South:
// v
World.PointSouth();
break;
case West:
// <
World.PointWest();
break;
case North:
// ^
World.PointNorth();
// Case 4
// Call World.RangeSymbol ' "+" sign
break;
}
} else // else the wheels don't turn so display an A
{
// "A" = Adaptron pointing North
World.PointUnder();
}
// for HistoryDisplay of outputs
OUTPUTS[LIN][1] = OUTPUTS[LIN][1] + Kn;
// persist any changes in this object
change();
// dump all the history and LTMem()
World.Update_View();
// do this for each sense
// fillin the World.VB() value
World.DisplayStimuliAndResponse(SensorValues, Resp);
}
// End of BodyFunction2()
public final void GetStimuli(int Sens, Var ReturnedStimuli) {
// Get the stimulus value for each Sens.
// Currently each Sense is a single sensor
ReturnedStimuli.set("");
if (Senses[Sens][SymbolicOrMagnitude] == Magnitude) {
switch(// Based on the name of the sense
Sense[Sens]) {
case // Looking down at cell - distance 1 cell away
"VisionD":
ReturnedStimuli.set(ReturnedStimuli.get() + (char) 1);
break;
case // looking left based on body direction
"VisionL":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeWest()));
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeNorth()));
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeEast()));
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeSouth()));
break;
}
break;
case // looking right
"VisionR":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeEast()));
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeSouth()));
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeWest()));
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeNorth()));
break;
}
break;
case // looking forward
"VisionF":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeNorth()));
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeEast()));
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeSouth()));
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeWest()));
break;
}
break;
case // looking behind
"VisionB":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeSouth()));
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeWest()));
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeNorth()));
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + chr(World.RangeEast()));
break;
}
break;
}
} else // Sense is symbolic
{
if (// If vision just looking at next square then
Senses[Sens][LowerRangeLimit] == asc(Wall)) {
switch(// Based on the name of the sense
Sense[Sens]) {
case // Looking down at cell floor
"VisionD":
ReturnedStimuli.set(Wall);
break;
case // looking left based on body direction
"VisionL":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
}
break;
case // looking right
"VisionR":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
}
break;
case // looking forward
"VisionF":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
}
break;
case // looking behind
"VisionB":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
}
break;
}
if (// if it's not a wall then the square is empty
!ReturnedStimuli.get().equals(Wall)) {
ReturnedStimuli.set(EmptySquare);
}
} else // Else vision looking at symbolic location value in next square
{
switch(// Based on the name of the sense
Sense[Sens]) {
case // Looking down at cell
"VisionD":
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookUnder());
break;
case // looking left based on body direction
"VisionL":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
}
break;
case // looking right
"VisionR":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
}
break;
case // looking forward
"VisionF":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
}
break;
case // looking behind
"VisionB":
switch(BodyPointing) {
case North:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth());
break;
case East:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest());
break;
case South:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth());
break;
case West:
ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast());
break;
}
break;
}
}
// end if its looking for wall or space or looking for square location letter
}
// end if sense is magnitude or symbolic
}
// End of GetStimuli()
}
}
// end of Smarty
static final class StringHelper {
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Substring' when 'start' is a method
// call or calculated value to ensure that 'start' is obtained just once.
// ------------------------------------------------------------------------------------
public static String substring(String string, int start, int length) {
if (length < 0)
throw new IndexOutOfBoundsException("Parameter length cannot be negative.");
return string.substring(start, start + length);
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'IsNullOrEmpty'.
// ------------------------------------------------------------------------------------
public static boolean isNullOrEmpty(String string) {
return string == null || string.length() == 0;
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'IsNullOrWhiteSpace'.
// ------------------------------------------------------------------------------------
public static boolean isNullOrWhiteSpace(String string) {
if (string == null)
return true;
for (int index = 0; index < string.length(); index++) {
ping();
if (!Character.isWhitespace(string.charAt(index)))
return false;
}
return true;
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'Join' (2 parameter version).
// ------------------------------------------------------------------------------------
public static String join(String separator, String[] stringArray) {
if (stringArray == null)
return null;
else
return join(separator, stringArray, 0, stringArray.length);
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'Join' (4 parameter version).
// ------------------------------------------------------------------------------------
public static String join(String separator, String[] stringArray, int startIndex, int count) {
if (stringArray == null)
return null;
StringBuilder sb = new StringBuilder();
for (int index = startIndex; index < stringArray.length && index - startIndex < count; index++) {
ping();
if (separator != null && index > startIndex)
sb.append(separator);
if (stringArray[index] != null)
sb.append(stringArray[index]);
}
return sb.toString();
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Remove' (1 parameter version).
// ------------------------------------------------------------------------------------
public static String remove(String string, int start) {
return string.substring(0, start);
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Remove' (2 parameter version).
// ------------------------------------------------------------------------------------
public static String remove(String string, int start, int count) {
return string.substring(0, start) + string.substring(start + count);
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'TrimEnd'.
// ------------------------------------------------------------------------------------
public static String trimEnd(String string, Character... charsToTrim) {
if (string == null || charsToTrim == null)
return string;
int lengthToKeep = string.length();
for (int index = string.length() - 1; index >= 0; index--) {
ping();
boolean removeChar = false;
if (charsToTrim.length == 0) {
if (Character.isWhitespace(string.charAt(index))) {
lengthToKeep = index;
removeChar = true;
}
} else {
for (int trimCharIndex = 0; trimCharIndex < charsToTrim.length; trimCharIndex++) {
ping();
if (string.charAt(index) == charsToTrim[trimCharIndex]) {
lengthToKeep = index;
removeChar = true;
break;
}
}
}
if (!removeChar)
break;
}
return string.substring(0, lengthToKeep);
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'TrimStart'.
// ------------------------------------------------------------------------------------
public static String trimStart(String string, Character... charsToTrim) {
if (string == null || charsToTrim == null)
return string;
int startingIndex = 0;
for (int index = 0; index < string.length(); index++) {
ping();
boolean removeChar = false;
if (charsToTrim.length == 0) {
if (Character.isWhitespace(string.charAt(index))) {
startingIndex = index + 1;
removeChar = true;
}
} else {
for (int trimCharIndex = 0; trimCharIndex < charsToTrim.length; trimCharIndex++) {
ping();
if (string.charAt(index) == charsToTrim[trimCharIndex]) {
startingIndex = index + 1;
removeChar = true;
break;
}
}
}
if (!removeChar)
break;
}
return string.substring(startingIndex);
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Trim' when arguments are used.
// ------------------------------------------------------------------------------------
public static String trim(String string, Character... charsToTrim) {
return trimEnd(trimStart(string, charsToTrim), charsToTrim);
}
// ------------------------------------------------------------------------------------
// This method is used for string equality comparisons when the option
// 'Use helper 'stringsEqual' method to handle null strings' is selected
// (The Java String 'equals' method can't be called on a null instance).
// ------------------------------------------------------------------------------------
public static boolean stringsEqual(String s1, String s2) {
if (s1 == null && s2 == null)
return true;
else
return s1 != null && s1.equals(s2);
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadRight' (1 parameter version).
// ------------------------------------------------------------------------------------
public static String padRight(String string, int totalWidth) {
return padRight(string, totalWidth, ' ');
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadRight' (2 parameter version).
// ------------------------------------------------------------------------------------
public static String padRight(String string, int totalWidth, char paddingChar) {
StringBuilder sb = new StringBuilder(string);
while (sb.length() < totalWidth) {
ping();
sb.append(paddingChar);
}
return sb.toString();
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadLeft' (1 parameter version).
// ------------------------------------------------------------------------------------
public static String padLeft(String string, int totalWidth) {
return padLeft(string, totalWidth, ' ');
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadLeft' (2 parameter version).
// ------------------------------------------------------------------------------------
public static String padLeft(String string, int totalWidth, char paddingChar) {
StringBuilder sb = new StringBuilder();
while (sb.length() + string.length() < totalWidth) {
ping();
sb.append(paddingChar);
}
sb.append(string);
return sb.toString();
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string constructor which repeats a character.
// ------------------------------------------------------------------------------------
public static String repeatChar(char charToRepeat, int count) {
String newString = "";
for (int i = 1; i <= count; i++) {
ping();
newString += charToRepeat;
}
return newString;
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'LastIndexOf' (char version).
// ------------------------------------------------------------------------------------
public static int lastIndexOf(String string, char value, int startIndex, int count) {
int leftMost = startIndex + 1 - count;
int rightMost = startIndex + 1;
String substring = string.substring(leftMost, rightMost);
int lastIndexInSubstring = substring.lastIndexOf(value);
if (lastIndexInSubstring < 0)
return -1;
else
return lastIndexInSubstring + leftMost;
}
// ------------------------------------------------------------------------------------
// This method replaces the .NET string method 'LastIndexOf' (string version).
// ------------------------------------------------------------------------------------
public static int lastIndexOf(String string, String value, int startIndex, int count) {
int leftMost = startIndex + 1 - count;
int rightMost = startIndex + 1;
String substring = string.substring(leftMost, rightMost);
int lastIndexInSubstring = substring.lastIndexOf(value);
if (lastIndexInSubstring < 0)
return -1;
else
return lastIndexInSubstring + leftMost;
}
}
static final class FloatingPointToInteger {
public static byte ToSByte(double source) {
byte floor = (byte) Math.floor(source);
if (Math.abs(source - floor) == 0.5) {
if (floor % 2 == 0)
return floor;
else
return (byte) Math.ceil(source);
} else if (Math.abs(source - floor) < 0.5)
return floor;
else
return (byte) Math.ceil(source);
}
public static short ToInt16(double source) {
short floor = (short) Math.floor(source);
if (Math.abs(source - floor) == 0.5) {
if (floor % 2 == 0)
return floor;
else
return (short) Math.ceil(source);
} else if (Math.abs(source - floor) < 0.5)
return floor;
else
return (short) Math.ceil(source);
}
public static int ToInt32(double source) {
int floor = (int) Math.floor(source);
if (Math.abs(source - floor) == 0.5) {
if (floor % 2 == 0)
return floor;
else
return (int) Math.ceil(source);
} else if (Math.abs(source - floor) < 0.5)
return floor;
else
return (int) Math.ceil(source);
}
public static long ToInt64(double source) {
long floor = (long) Math.floor(source);
if (Math.abs(source - floor) == 0.5) {
if (floor % 2 == 0)
return floor;
else
return (long) Math.ceil(source);
} else if (Math.abs(source - floor) < 0.5)
return floor;
else
return (long) Math.ceil(source);
}
}
// debug sensor output
static boolean debugValues = false;
static int defaultSpacing = 10, spacing;
static JFrame mainFrame;
static List> gridComponents;
static JComponent mainGrid;
static JCheckBoxMenuItem miShowLocations;
static SingleComponentPanel scpMainGrid, scpVisionConfig, scpWheelsConfig, scpCurrentSmarty, scpStimuliAndResponse;
static JFrame historyFrame, memoryFrame;
static JSpinner worldSizeSpinner;
static JTextArea historyTextArea1, historyTextArea2;
static JTextArea taSensorValues, taDeviceValues;
// originally: BinonDisplay.ObjList.Text
static JTextArea memoryTextArea1;
// originally: BinonDisplay.ChngResults.Text
static JTextArea memoryTextArea2;
// AI instance
static Smarty smarty;
// queue for Smarty operations
static Q smartyQ = startQ("Smarty Q");
static String wallSymbol = unicode_blackSquare(), noWallSymbol = unicode_dottedSquare();
static Color lightBlue = colorFromHex("4169e1");
static String locationLetters = charRange('A', 'Z') + "[\\]^_`" + charRange('a', 'z') + charRange(123, 128);
static String smartyUnicode = unicode_slightlySmilingFace();
static int smartyFontSize = 40;
static String windowsFontID = "#1400468";
static String emojiFontID = "#1400470";
static String frameIconID = "#1102983";
static String monospacedFontID = /*#1400479*/
"#1400483";
static double monospacedFontSize = 12;
static boolean smartyBrainPersistence = false;
static String smartyImageID = "#1102987";
static String helpTextID = "#1031105";
static String worldFileExtension = "WLD";
static String bodyFileExtension = "BDY";
static String historyHelp = unindent_mls("\r\n A percept is the stimulus or simultaneous combination of stimuli observed.\r\n An action is the response or simultaneous combination of responses produced.\r\n Binon # numbers refer to the binons in memory that represent the percepts, actions, expectations, and perceptual or action sequences.\r\n P = Percept, E = Expectation, PP = Perceptual sequence A = Action, AA = Action sequence\r\n Read the paper: \"The Perception-Action Hierarchy and its Implementation Using Binons (Binary Neurons)\" on the www.adaptroninc.com website for more information.\r\n");
// translate Smarty's windows characters to unicode
static Map winToUnicode = litmap(Smarty.Smarty, unicode_slightlySmilingFace(), Smarty.UpArrow, unicode("2191"), Smarty.LeftArrow, unicode("2190"), Smarty.RightArrow, unicode("2192"), Smarty.DownArrow, unicode("2193"), Smarty.Wall, unicode_blackVerticalRectangle(), Smarty.EmptySquare, unicode_whiteVerticalRectangle(), Smarty.chr(Smarty.TurnRght), unicode("21B1"), Smarty.chr(Smarty.TurnLft), unicode("21B0"), Smarty.chr(Smarty.TurnArnd), unicode("21B7"), Smarty.chr(254), unicode_blackSmallSquare());
static boolean showTabs = true;
static int defaultWorldSize = 7, maxWorldSize = 8;
static ReliableSingleThread rstUpdateChngResults = rstWithPreDelay(250, new Runnable() {
public void run() {
try {
setText(memoryTextArea2, winToUnicode(state.binonDisplayChngResults));
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "setText(memoryTextArea2, winToUnicode(state.binonDisplayChngResults));";
}
});
static void rearrangeLetters() {
int iLetter = 0;
for (int y = 0; y < state.gridRows; y++) for (int x = 0; x < state.gridCols; x++) {
JCell cell = getCell(x, y);
if (cell.obstacle())
cell.letter = ' ';
else
cell.letter = locationLetters.charAt(iLetter++);
}
}
static class VisionMode {
static String nextSquare = "next square";
static String distanceToWall = "distance to wall";
static String wallOrNot = "wall or not";
}
static class CameraDirection {
static String down = "down";
static String left = "left";
static String right = "right";
static String inFront = "in front";
static String behind = "behind";
static List all = ll(down, left, right, inFront, behind);
}
static class SmartyBody extends Concept {
static final String _fieldOrder = "name cameraDirections visionMode wheels changed used";
String name = "Smarty0";
Set cameraDirections = litset(CameraDirection.down);
// see VisionMode
String visionMode = VisionMode.nextSquare;
Set wheels = litset("MoveForward", "MoveLeft", "MoveRight", "MoveBackward");
// changed w.r.t. file
boolean changed = false;
// used in Smarty execution
boolean used = false;
// for saving
String wheelsFlag(String flag) {
return wheels.contains(flag) ? "1" : "0";
}
void userCausedChange() {
print("Body: User caused change");
changed = true;
change();
}
}
static class State extends Concept {
static final String _fieldOrder = "fontScale worldName gridRows gridCols showLocations worldChanged startX startY smartyX smartyY smartyDirection selection cursorDirection obstacles history1 history2 memory1 sensorValuesText deviceValuesText binonDisplayChngResults body recentWorldFiles recentBodyFiles";
float fontScale = 1.5f;
String worldName = "Empty";
// actually these are always identical, could merge into one
int gridRows = defaultWorldSize, gridCols = defaultWorldSize;
boolean showLocations = false;
boolean worldChanged = false;
// Smarty's start position
int startX, startY;
int smartyX, smartyY;
// which way Smarty is looking - this or smarty.LeftArrow etc.
String smartyDirection = Smarty.Smarty;
Rect selection = rect(1, 1, 1, 1);
Pt cursorDirection = pt(1, 0);
BitSet obstacles = new BitSet();
String history1 = "", history2 = "", memory1 = "", sensorValuesText = "", deviceValuesText = "";
// memory2
String binonDisplayChngResults = "";
Ref body = new Ref();
// value is just true
Map recentWorldFiles = synchronizedMRUCache(5);
Map recentBodyFiles = synchronizedMRUCache(5);
void setSelection(Rect r) {
if (!cset_trueIfChanged(this, "selection", r))
return;
if (selection.h == 1 && selection.w > 1)
_setField("cursorDirection", pt(1, 0));
else if (selection.w == 1 && selection.h > 1)
_setField("cursorDirection", pt(0, 1));
repaintGrid();
}
void clearSelectedArea() {
fillSelection(false);
}
void invertSelection() {
JCell cell1 = getCell(selection.x, selection.y);
fillSelection(!cell1.obstacle());
}
void fillSelection(boolean b) {
for (Pt p : pointsInRect(selection)) if (// don't put an obstacle over Smarty
!(b && state.smartyX == p.x && state.smartyY == p.y))
getCell(p.x, p.y).setObstacle(b);
rearrangeLetters();
moveCursor();
}
void moveCursor() {
setCursor(selection.x + cursorDirection.x, selection.y + cursorDirection.y);
}
void setCursor(int x, int y) {
setSelection(rect(mod(x, gridCols), mod(y, gridRows), 1, 1));
}
void moveCursor(int dx, int dy) {
_setField("cursorDirection", pt(dx, dy));
setCursor(selection.x + cursorDirection.x, selection.y + cursorDirection.y);
}
void placeSmarty() {
getCell(selection.x, selection.y).setObstacle(false);
cset(state, "startX", selection.x, "startY", selection.y);
moveSmarty(selection.x, selection.y);
moveCursor();
}
void moveSmarty(int x, int y) {
if (!inRange(x, 0, gridCols) || !inRange(y, 0, gridRows))
throw fail("Smarty position not in range: " + x + "/" + y);
if (cset_trueIfChanged(this, "smartyX", x, "smartyY", y)) {
cset(this, "worldChanged", true);
repaintGrid();
}
}
void moveSmartyRelative(int x, int y) {
moveSmarty(smartyX + x, smartyY + y);
}
}
// end of State
static State state;
static class JCell extends JComponent {
int x, y;
char letter;
JCell(int x, int y) {
this.y = y;
this.x = x;
}
public void paint(Graphics _g) {
Graphics2D g = (Graphics2D) _g;
int w = getWidth(), h = getHeight();
Color color = Color.white;
if (state.selection.contains(x, y))
color = lightBlue;
else if (obstacle())
color = Color.black;
fillRect(g, 0, 0, w, h, color);
if (state.showLocations && !obstacle()) {
AutoCloseable __17 = tempSetFont(g, loadFont_cached(windowsFontID));
try {
drawTextWithTopLeftCornerAt(g, str(letter), new Pt(2, 0), Color.black);
} finally {
_close(__17);
}
}
if (state.smartyX == x && state.smartyY == y) {
AutoCloseable __18 = tempSetFontSize(g, smartyFontSize);
try {
/*temp tempSetFont(g, loadFont_cached(emojiFontID));
drawCenteredText(g, smartyUnicode, 0, 0, w, h, Color.black);*/
double size = 0.6;
int dx = iround((1 - size) / 2 * w);
int dy = iround((1 - size) / 2 * h);
if (eq(state.smartyDirection, smarty.Smarty))
drawScaledImage(g, loadImage2_cached(smartyImageID), rectFromPoints(dx, dy, w - dx, h - dy));
else {
// temp tempSetFont(g, loadFont_cached(windowsFontID));
String icon = lookupOrKeep(winToUnicode, state.smartyDirection);
drawCenteredText(g, icon, 0, 0, w, h, Color.black);
}
} finally {
_close(__18);
}
}
}
int index() {
return y * state.gridCols + x;
}
boolean obstacle() {
return main.contains(state.obstacles, index());
}
void setObstacle(boolean b) {
if (setBit_trueIfChanged(state.obstacles, index(), b)) {
cset(state, "worldChanged", true);
state.change();
}
}
{
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
main.requestFocus(mainGrid);
if (!isLeftButton(e))
return;
state.setSelection(new Rect(x, y, 1, 1));
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
// _print("Drag in " + x + "/" + y + ": " + e.getPoint());
Component dest = componentAtScreenLocationInWindow(mainFrame, e);
if (dest instanceof JCell) {
// _print("Target: " + dest);
state.setSelection(rectFromPointsInclusiveSorted(x, y, ((JCell) dest).x, ((JCell) dest).y));
}
}
});
}
public String toString() {
return x + "/" + y;
}
}
static JCell getCell(int x, int y) {
return gridComponents.get(y).get(x);
}
static JCell smartyCell() {
return getCell(state.smartyX, state.smartyY);
}
static boolean inGrid(int x, int y) {
return inRange(y, state.gridRows) && inRange(x, state.gridCols);
}
static void makeMainGrid() {
gridComponents = map(iotaZeroList(state.gridRows), y -> map(iotaZeroList(state.gridCols), x -> new JCell(x, y)));
mainGrid = setFocusable(setBackground(Color.black, hvgrid(gridComponents, 1)));
scpMainGrid.setComponent(mainGrid);
rearrangeLetters();
}
// always clears the world
static void setWorldSize(int size) {
state.obstacles.clear();
state.gridCols = state.gridRows = size;
setSpinnerValue(worldSizeSpinner, size);
state.selection = rect(1, 1);
cset(state, "startX", 0, "startY", 0);
state.moveSmarty(0, 0);
cset(state, "worldChanged", false);
state.change();
makeMainGrid();
resetSmarty();
}
static void repaintGrid() {
repaint(mainGrid);
}
// add more functions here
public static void main(final String[] args) throws Exception {
smartyMain();
}
static void smartyMain() {
System.out.println("Main class: " + strWithIdentityHashCode(mc()) + ", class loader: " + getClassLoader(mc()));
autoRestart(2.0);
// print all vm bus msgs from concepts
// vmBus_snoopToPrint((msg, arg) -> firstOfArrayOrSame(arg) instanceof Concepts);
setProgramDir(print("Using directory: ", mainDir()));
logProgramOutput();
_handleException_showThreadCancellations = true;
if (!isDevVersion())
hideConsole();
else
veryBigConsole();
db();
// make at least one instance
uniq(SmartyBody.class);
state = uniq(State.class);
smarty = uniq(Smarty.class);
initSmarty();
// default body
if (!state.body.has())
cset(state, "body", conceptWhere(SmartyBody.class));
// cset(state.body, used := false); // XXX
// prep GUI
// styling
jtattoo_mcWin();
// set swingFontScale_debug;
// scaling
updateFontScale(state.fontScale);
// no space bar for buttons
disableSpaceBarForAllButtons();
loadLibrary(windowsFontID);
defaultFrameIcon(frameIconID);
mainFrame = showFrame("Smarty");
// exitOnClose(mainFrame);
onWindowClosing(mainFrame, runnableThread(new Runnable() {
public void run() {
try {
// proper clean-up for standalone mode
cleanUp(mc());
cleanKillVM();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "cleanUp(mc()); // proper clean-up for standalone mode\r\n cleanKillVM();";
}
}));
historyTextArea1 = monospaced(uneditableBlackTextArea_noUndo());
historyTextArea2 = monospaced(uneditableBlackTextArea_noUndo());
memoryTextArea1 = /*withTypeWriterFont*/
monospaced(uneditableBlack(swing(() -> new JLineHeightTextArea(0.8))));
memoryTextArea2 = monospaced(uneditableBlackTextArea_noUndo(winToUnicode(state.binonDisplayChngResults)));
makeMenus();
registerCtrlKey(mainFrame, KeyEvent.VK_N, "New world", new Runnable() {
public void run() {
try {
print("new");
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "print(\"new\")";
}
});
registerCtrlKey(mainFrame, KeyEvent.VK_R, "Retrieve world", new Runnable() {
public void run() {
try {
;
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "";
}
});
registerCtrlKey(mainFrame, KeyEvent.VK_S, "Save world", new Runnable() {
public void run() {
try {
;
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "";
}
});
addMenu(mainFrame, "View", miShowLocations = jCheckBoxMenuItem("Locations (Ctrl+L)", state.showLocations, b -> {
cset(state, "showLocations", b);
repaintGrid();
}), jMenu("UI Zoom", "100%", new Runnable() {
public void run() {
try {
uiZoom(100);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "uiZoom(100)";
}
}, "112%", new Runnable() {
public void run() {
try {
uiZoom(112);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "uiZoom(112)";
}
}, "125%", new Runnable() {
public void run() {
try {
uiZoom(125);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "uiZoom(125)";
}
}, "140%", new Runnable() {
public void run() {
try {
uiZoom(140);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "uiZoom(140)";
}
}), "---", "Self-Test", runnableThread(new Runnable() {
public void run() {
try {
selfTest();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "selfTest();";
}
}), "Console", new Runnable() {
public void run() {
try {
activateConsole();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "activateConsole();";
}
});
registerCtrlKey(mainFrame, KeyEvent.VK_L, "Locations", new Runnable() {
public void run() {
try {
cset(state, "showLocations", !state.showLocations);
setChecked(miShowLocations, state.showLocations);
repaintGrid();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "cset(state, showLocations := !state.showLocations);\r\n setChecked(miShowL...";
}
});
JMenuBar menuBar = getMenuBar(mainFrame);
JMenuItem helpItem = jMenuItem("Help F1", runnableThread(new Runnable() {
public void run() {
try {
showHelp();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showHelp();";
}
}));
/*print(minSize := getMinimumSize(helpItem));
print(preferredSize := getPreferredSize(helpItem));*/
addMenuItem(menuBar, jPreferredWidthToMaxWidth(helpItem));
// spacer
addAndRevalidate(menuBar, jHorizontalGlue());
registerFunctionKey(mainFrame, 1, runnableThread(new Runnable() {
public void run() {
try {
showHelp();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showHelp();";
}
}));
registerKeyCode(mainFrame, KeyEvent.VK_SPACE, new Runnable() {
public void run() {
try {
state.invertSelection();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "state.invertSelection()";
}
});
registerKeyCode(mainFrame, KeyEvent.VK_UP, new Runnable() {
public void run() {
try {
state.moveCursor(0, -1);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "state.moveCursor(0, -1)";
}
});
registerKeyCode(mainFrame, KeyEvent.VK_LEFT, new Runnable() {
public void run() {
try {
state.moveCursor(-1, 0);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "state.moveCursor(-1, 0)";
}
});
registerKeyCode(mainFrame, KeyEvent.VK_DOWN, new Runnable() {
public void run() {
try {
state.moveCursor(0, 1);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "state.moveCursor(0, 1)";
}
});
registerKeyCode(mainFrame, KeyEvent.VK_RIGHT, new Runnable() {
public void run() {
try {
state.moveCursor(1, 0);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "state.moveCursor(1, 0)";
}
});
// react to any letter from A to Z
for (int key = KeyEvent.VK_A; key <= KeyEvent.VK_Z; key++) registerKeyCode(mainFrame, key, new Runnable() {
public void run() {
try {
state.placeSmarty();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "state.placeSmarty()";
}
});
worldSizeSpinner = jSpinner(state.gridCols, 1, maxWorldSize);
onChange(worldSizeSpinner, new Runnable() {
public void run() {
try {
int size = intFromSpinner(worldSizeSpinner);
if (state.gridCols != size) {
if (state.worldChanged) {
int result = swingShowConfirmDialog(mainFrame, "World has changed! - Save it before resizing?", "Smarty", JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION) {
saveWorldDialog(new Runnable() {
public void run() {
try {
newWorldWithoutConfirmation(size);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "newWorldWithoutConfirmation(size)";
}
});
return;
} else if (result == JOptionPane.CANCEL_OPTION) {
setSpinnerValue(worldSizeSpinner, state.gridCols);
return;
}
}
newWorldWithoutConfirmation(size);
}
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "int size = intFromSpinner(worldSizeSpinner);\r\n if (state.gridCols != size)...";
}
});
scpCurrentSmarty = singleComponentPanel();
JComponent middleArea = westAndCenterWithMargin(spacing, jvstackWithSpacing(spacing, withTitle(("World size (max=" + maxWorldSize + ")"), worldSizeSpinner), jbutton("Clear Selected Area", runnableThread(new Runnable() {
public void run() {
try {
state.clearSelectedArea();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "state.clearSelectedArea()";
}
})), withTitle("Current world", disableTextField(jLiveValueTextField(conceptFieldLiveValue("worldName", state)))), showTabs ? null : fontSizePlus(2, setForeground(Color.ORANGE, jCenteredLabel("Design or Select a body for Smarty"))), showTabs ? null : jbutton("Design or Select Smarty's Body", new Runnable() {
public void run() {
try {
showSmartyConfig();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showSmartyConfig();";
}
}), withTitle("Current Smarty", scpCurrentSmarty)), jvgridWithSpacing(spacing, withTitle(monospaced(jLabel("Sensors: Values: are:")), taSensorValues = monospaced(uneditableBlackTextArea_noUndo())), withTitle(monospaced(jLabel("Devices: Values: are:")), taDeviceValues = monospaced(uneditableBlackTextArea_noUndo()))));
JComponent controlArea = northAndCenterWithMargin(spacing, vstackWithSpacing(fontSizePlus(2, setForeground(Color.blue, jlabel("Design the World - Read the Help F1"))), jMinHeight(swingScale(200), middleArea)), jCenteredSection("Run Smarty", jflow(jbutton("Go / Continue", runnableThread(new Runnable() {
public void run() {
try {
goCmd();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "goCmd();";
}
})), jButton("See History", new Runnable() {
public void run() {
try {
showHistory();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showHistory();";
}
}), jbutton("See Memory", new Runnable() {
public void run() {
try {
showMemory();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showMemory();";
}
}), jbutton("Reset", new Runnable() {
public void run() {
try {
resetSmarty();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "resetSmarty();";
}
}), jbutton("EXIT", runnableThread(new Runnable() {
public void run() {
try {
killVM();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "killVM();";
}
})))));
scpMainGrid = singleComponentPanel();
makeMainGrid();
var mainPanel = westAndCenterWithMargins(spacing, jvstackWithSpacing(spacing, jFixedSize(500, scpMainGrid), scpStimuliAndResponse = singleComponentPanel()), controlArea);
if (showTabs) {
scpVisionConfig = singleComponentPanel();
scpWheelsConfig = singleComponentPanel();
updateTabs();
setFrameContents(mainFrame, jtabs("Smarty", mainPanel, "Vision", scpVisionConfig, "Wheels", scpWheelsConfig));
} else
setFrameContents(mainFrame, mainPanel);
centerPackFrame(mainFrame);
// set minimum width
jMinWidth_pure(mainFrame, max(1000, swingScale(800)));
centerFrameWithMinWidth(mainFrame);
// set min frame height
jMinHeight_pure(mainFrame, getHeight(mainFrame));
// disable height changes entirely (not good, may cut off at the bottom)
// frameMaxHeight(mainFrame, getHeight(mainFrame));
// smarty.World.Update_View();
setText(historyTextArea1, winToUnicode(state.history1));
setText(historyTextArea2, winToUnicode(state.history2));
setText(memoryTextArea1, winToUnicode(state.memory1));
setText(taSensorValues, winToUnicode(state.sensorValuesText));
setText(taDeviceValues, winToUnicode(state.deviceValuesText));
enableBodyControls(!state.body.get().used);
if (!smartyBrainPersistence)
resetSmarty();
if (!isDevVersion())
showHelp();
else {
// goCmd();
// selfTest();
}
}
// end of main function
static boolean isDevVersion() {
return isProgramID("#1031104");
}
static void updateTabs() {
scpVisionConfig.setComponent(visionConfigPanel(state.body.get()));
scpWheelsConfig.setComponent(wheelsConfigPanel(state.body.get()));
scpCurrentSmarty.setComponent(disableTextField(jLiveValueTextField(conceptFieldLiveValue("name", state.body.get()))));
updateFrameTitles();
}
static void enableBodyControls(boolean b) {
var panels = ll(scpVisionConfig, scpWheelsConfig);
for (var c : concatMap(panel -> allChildrenOfType(JComponent.class, panel), panels)) if (isInstanceOfAny(c, JCheckBox.class, JRadioButton.class, JTextField.class) && !(c instanceof BodyNameField))
setEnabled(c, b);
// Modify body button is enabled iff controls are not enabled
for (var c : concatMap(panel -> allChildrenOfType(ModifyBodyButton.class, panel), panels)) setEnabled(c, !b);
}
static void showHelp() {
String text = loadSnippet(helpTextID);
String heading = firstLine(text);
trim(dropFirstLine(text));
showCenterFrame(swingScale(650), swingScale(500), heading, makeUneditableWithTextColor(Color.black, wordWrapTextArea(text)));
}
// run in Swing thread
static void showHistory() {
Font ttFont = loadFont_cached(monospacedFontID, 12), helpFont = sansSerifFont(13);
if (historyFrame == null)
historyFrame = getFrame(showCenterFrame(maxPt(pt(800, 600), scalePt(600, 350, swingFontScale())), "History", withMargin(centerAndSouthWithMargin(spacing, centerAndSouthWithMargin(historyTextArea1, westAndCenterWithMargin(spacing, setFont(ttFont, topAlignLabel(jMultiLineLabel(linesLL("Step #", "Percept", "Binon #", "", "Expect", "Binon #", "", "Action", "Binon #", "", "Action", "Binon #", "")))), setFont(ttFont, historyTextArea2))), centerAndEastWithMargin(setFont(helpFont, jMultiLineLabel(historyHelp)), jvstackWithSpacing(jButton("See World", new Runnable() {
public void run() {
try {
showWorld();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showWorld();";
}
}), jButton("See Memory", new Runnable() {
public void run() {
try {
showMemory();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showMemory();";
}
})))))));
else
frameToFront(historyFrame);
updateFrameTitles();
}
// run in Swing thread
static void showMemory() {
Font ttFont = typeWriterFont(12), helpFont = sansSerifFont(13);
String Interestng;
if (smarty.InterestLevels == 3)
Interestng = smarty.IntSymb(smarty.INTERESTING) + "=Interesting, ";
else
// Only 2 interest levels
Interestng = "";
String IntSymbol = " " + smarty.IntSymb(smarty.NOVEL) + " = Novel, " + Interestng + smarty.IntSymb(smarty.FAMILIAR) + " = Familiar";
// originally: BinonDisplay.ObjListTitle.Caption
String title = "Bn# OL Ty TL BL TR BR V L R In LQ RQ Pattern " + " l = Left target, r = Right target," + IntSymbol;
if (memoryFrame == null)
memoryFrame = getFrame(showCenterFrame(scalePt(600, 350, swingFontScale()), "Smarty's Memory", jvsplit(0.5, 100, centerAndEastWithMargins(northAndCenterWithMargin(setFont(ttFont, jLabel(title)), setFont(ttFont, memoryTextArea1)), jvstackWithSpacing(jButton("See World", new Runnable() {
public void run() {
try {
showWorld();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showWorld();";
}
}), jButton("See History", new Runnable() {
public void run() {
try {
showHistory();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showHistory();";
}
}))), memoryTextArea2)));
else
frameToFront(memoryFrame);
updateFrameTitles();
}
static void showWorld() {
frameToFront(mainFrame);
}
static JRadioButton visionModeRadioButton(SmartyBody body, ButtonGroup buttonGroup, String visionMode, String text) {
var rb = jradiobutton(buttonGroup, text, eq(body.visionMode, visionMode));
onChange(rb, new Runnable() {
public void run() {
try {
if (isChecked(rb)) {
cset(body, "visionMode", visionMode);
body.userCausedChange();
}
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "if (isChecked(rb)) { cset(body, +visionMode); body.userCausedChange(); }";
}
});
return rb;
}
static class ModifyBodyButton extends JButton {
ModifyBodyButton() {
super("Modify Smarty's Body");
main.addActionListener(this, new Runnable() {
public void run() {
try {
modifyBody();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "modifyBody();";
}
});
}
}
// enable the controls to edit the body, after confirmation
static void modifyBody() {
if (state.body.get().used) {
if (!confirmOKCancel("Modifying Smarty's body will reset its state. Do you wish to continue?"))
return;
resetSmarty();
cset(state.body, "used", false);
}
enableBodyControls(true);
}
static class BodyNameField extends JTextField {
BodyNameField() {
setEnabled(false);
}
}
static JComponent bodyNamePanel(SmartyBody body) {
SimpleLiveValue lv = conceptFieldLiveValue("name", body);
lv.onChange(new Runnable() {
public void run() {
try {
body.userCausedChange();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "body.userCausedChange()";
}
});
return hstackWithSpacing(jMinWidth(swingScale(250), withLabel("Body name:", bindTextComponentToLiveValue(lv, swing(() -> new BodyNameField())))), swing(() -> new ModifyBodyButton()));
}
static JComponent visionConfigPanel(SmartyBody body) {
var buttonGroup = buttonGroup();
return northAndCenterWithMargins(spacing, bodyNamePanel(body), westAndCenterWithMargin(spacing, jCenteredSection("Camera", withLeftMargin(spacing, jvstackWithSpacing(spacing, itemPlus(jlabel("Select the camera directions"), map(CameraDirection.all, direction -> {
var cb = jCheckBox(direction, body.cameraDirections.contains(direction));
onChange(cb, new Runnable() {
public void run() {
try {
addOrRemove(body.cameraDirections, direction, isChecked(cb));
body.userCausedChange();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "addOrRemove(body.cameraDirections, direction, isChecked(cb)); body.userCaused...";
}
});
return cb;
}))))), jCenteredSection("Vision mode", jvstack(withLeftMargin(spacing * 2, jMultiLineLabel(unindentMLS(replaceSymbols("\r\n Square locations are identified with a letter.\r\n Looking down provides the letter of the current square.\r\n Looking in other directions provides the letter in the next square\r\n depending on the direction Smarty is facing.\r\n If it is a wall then the symbolic stimulus is a $wallSymbol\r\n ")))), visionModeRadioButton(body, buttonGroup, VisionMode.nextSquare, "Looking at the next square (symbolic values = letter in square)"), verticalStrut(20), withLeftMargin(spacing * 2, jMultiLineLabel(unindentMLS("\r\n Looking at the distance to the nearest wall will provide the\r\n number of squares from the current position to the wall in\r\n the direction the camera is facing. A wall next to the robot\r\n is one square away. Looking down will always return 1.\r\n "))), visionModeRadioButton(body, buttonGroup, VisionMode.distanceToWall, "Distance to wall (magnitude values = number of squares)"), verticalStrut(20), withLeftMargin(spacing * 2, jMultiLineLabel(unindentMLS("\r\n Looking at the next square will either see a wall or an empty square\r\n "))), visionModeRadioButton(body, buttonGroup, VisionMode.wallOrNot, replaceSymbols("Wall or not (symbolic values = $wallSymbol for a wall and $noWallSymbol for no wall)"))))));
}
static void showVisionConfig(SmartyBody body) {
showPackedFrame("Configure Smarty's Vision", visionConfigPanel(body));
}
static JCheckBox wheelsConfigCheckBox(SmartyBody body, String symbol, String text) {
var cb = jCheckBox(text, body.wheels.contains(symbol));
onChange(cb, new Runnable() {
public void run() {
try {
addOrRemove(body.wheels, symbol, isChecked(cb));
body.userCausedChange();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "addOrRemove(body.wheels, symbol, isChecked(cb)); body.userCausedChange();";
}
});
return cb;
}
static JComponent wheelsConfigPanel(SmartyBody body) {
return northAndCenterWithMargins(spacing, bodyNamePanel(body), vstackWithSpacing(spacing, westAndCenterWithMargin(spacing, jCenteredSection("Movement", withLeftMargin(spacing, jvstackWithSpacing(jlabel("Select the wheel motions"), wheelsConfigCheckBox(body, "MoveForward", "Forward = f"), wheelsConfigCheckBox(body, "MoveLeft", "Left = l"), wheelsConfigCheckBox(body, "MoveRight", "Right = r"), wheelsConfigCheckBox(body, "MoveBackward", "Backward = b")))), jCenteredSection("Help", withLeftMargin(jTopLabel(hhtml(nlToBr(mls_replaceDollarVars(winToUnicode("\r\n Motion in any direction will move one square.\r\n If there is a wall in the way it will not move. A \"-\" indicates no motion.\r\n The direction moved depends on the direction Smarty is facing.\r\n Smarty will appear as a $smiley if it cannot turn. It will then always be\r\n facing North (up) so moving right will move to the East (right).\r\n "), "smiley", himgForJLabel("#1102987", "width", swingScale(15), "height", swingScale(15), "align", "middle")))))))), westAndCenterWithMargin(spacing, jCenteredSection("Turning", withLeftMargin(spacing, vstackWithSpacing(wheelsConfigCheckBox(body, "TurnRight", "Turn to the right = Rotate clockwise 90 degrees = " + winToUnicode(Smarty.TurnRght)), wheelsConfigCheckBox(body, "TurnLeft", "Turn to the left = Rotate anti-clockwise 90 degrees = " + winToUnicode(Smarty.TurnLft)), wheelsConfigCheckBox(body, "TurnAround", "Turn around = Rotate 180 degrees = " + winToUnicode(Smarty.TurnArnd))))), jCenteredSection("Help", withLeftMargin(jMultiLineLabel(winToUnicode(mls_replaceDollarVars("\r\n Turning will stay on the same square. If Smarty is able to turn then it will appear as $left, $right, $up or $down to indicate the direction it is facing.\r\n ", "left", Smarty.LeftArrow, "right", Smarty.RightArrow, "up", Smarty.UpArrow, "down", Smarty.DownArrow)))))), jCenteredSection("Sensing", withLeftMargin(spacing, wheelsConfigCheckBox(body, "AddAWheelSensor", "Add a wheel sensor to detect if it moved or failed because it was up against a wall")))));
}
static void showWheelsConfig(SmartyBody body) {
var buttonGroup = buttonGroup();
showPackedFrame("Configure Smarty's Wheels", wheelsConfigPanel(body));
}
static void showSmartyConfig() {
showPackedFrameMinWidth(400, "Design or Select a body for Smarty", withMargin(centeredButtons("Vision", new Runnable() {
public void run() {
try {
showVisionConfig(state.body.get());
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showVisionConfig(state.body.get())";
}
}, "Wheels", new Runnable() {
public void run() {
try {
showWheelsConfig(state.body.get());
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showWheelsConfig(state.body.get())";
}
})));
}
// e.g. $wallSymbol and $noWallSymbol
static String replaceSymbols(String s) {
return replaceDollarVars(s, "wallSymbol", wallSymbol, "noWallSymbol", noWallSymbol);
}
static String exportWorldForSaving() {
List lines = new ArrayList();
lines.add(" " + state.gridRows);
for (int y = 0; y < state.gridRows; y++) for (int x = 0; x < state.gridCols; x++) {
JCell cell = getCell(x, y);
lines.add(state.smartyX == x && state.smartyY == y ? "A" : cell.obstacle() ? "#" : " ");
}
return lines(lines);
}
static void saveWorld(File f) {
String text = exportWorldForSaving();
saveTextFile(f, text);
infoBox("World saved: " + fileName(f));
cset(state, "worldName", fileNameWithoutExtension(f), "worldChanged", false);
addRecentWorldFile(f);
}
static void addRecentWorldFile(File f) {
swing(new Runnable() {
public void run() {
try {
removeAndPut(state.recentWorldFiles, f, true);
state.change();
makeMenus();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "removeAndPut(state.recentWorldFiles, f, true);\r\n state.change();\r\n makeMenu...";
}
});
}
static void addRecentBodyFile(File f) {
swing(new Runnable() {
public void run() {
try {
removeAndPut(state.recentBodyFiles, f, true);
state.change();
makeMenus();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "removeAndPut(state.recentBodyFiles, f, true);\r\n state.change();\r\n makeMenus();";
}
});
}
static void loadWorld(File f) {
try {
List lines = linesFromFile_list(f);
if (eqAfterRtrim(lines(lines), exportWorldForSaving())) {
infoBox("World is the same as current one");
return;
}
int i = 0;
int gridRows = parseInt(trim(lines.get(i++)));
if (gridRows < 1 || gridRows > maxWorldSize)
throw fail("Bad world size: " + gridRows);
setWorldSize(gridRows);
for (int y = 0; y < gridRows; y++) for (int x = 0; x < gridRows; x++) {
String line = lines.get(i++);
JCell cell = getCell(x, y);
if (eq(line, "#"))
cell.setObstacle(true);
else if (eq(line, "A"))
state.moveSmarty(x, y);
}
rearrangeLetters();
repaintGrid();
cset(state, "worldName", fileNameWithoutExtension(f));
cset(state, "worldChanged", false);
infoBox("World loaded: " + fileName(f));
addRecentWorldFile(f);
} catch (Throwable __e) {
messageBox(__e);
}
}
static void saveWorldDialog() {
saveWorldDialog(null);
}
static void saveWorldDialog(Runnable whenDone) {
{
swing(new Runnable() {
public void run() {
try {
JFileChooser fileChooser = new JFileChooser(mainDir());
fileChooser.setFileFilter(new FileNameExtensionFilter(("Smarty World files (*." + worldFileExtension + ")"), worldFileExtension));
if (fileChooser.showSaveDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
File f = defaultExtension(worldFileExtension, fileChooser.getSelectedFile());
saveWorld(f);
infoBox("World saved as " + f.getName());
} else
messageBox("World NOT saved");
callF(whenDone);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "JFileChooser fileChooser = new(mainDir());\r\n fileChooser.setFileFilter(new...";
}
});
}
}
static void withWorldSave(Runnable r) {
if (state.worldChanged) {
int result = swingShowConfirmDialog(mainFrame, "World has changed! - Save it?", "Smarty", JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION) {
saveWorldDialog(r);
return;
} else if (result == JOptionPane.CANCEL_OPTION)
return;
else
cset(state, "worldChanged", false);
}
r.run();
}
static void loadWorldDialog() {
withWorldSave(new Runnable() {
public void run() {
try {
loadWorldDialogWithoutConfirmation();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "loadWorldDialogWithoutConfirmation();";
}
});
}
static void loadWorldDialogWithoutConfirmation() {
swing(new Runnable() {
public void run() {
try {
JFileChooser fileChooser = new JFileChooser(mainDir());
fileChooser.setFileFilter(new FileNameExtensionFilter(("Smarty World files (*." + worldFileExtension + ")"), worldFileExtension));
if (fileChooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION)
loadWorld(fileChooser.getSelectedFile());
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "JFileChooser fileChooser = new(mainDir());\r\n fileChooser.setFileFilter(new F...";
}
});
}
static void newWorld() {
withWorldSave(new Runnable() {
public void run() {
try {
newWorldWithoutConfirmation();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "newWorldWithoutConfirmation();";
}
});
}
static void newWorldWithoutConfirmation() {
newWorldWithoutConfirmation(defaultWorldSize);
}
static void newWorldWithoutConfirmation(int size) {
setWorldSize(size);
cset(state, "worldName", "Empty", "worldChanged", false);
updateFrameTitles();
}
static File mainDir() {
return mkdirs(userDir("Adaptron/Smarty"));
}
static String exportBodyForSaving() {
String[] Body = new String[22];
bodyToArray(state.body.get(), Body);
return lines(dropFirst(Body));
}
static void saveBody(File f) {
String text = exportBodyForSaving();
saveTextFile(f, text);
cset(state.body.get(), "changed", false);
addRecentBodyFile(f);
}
static void bodyToArray(SmartyBody b, String[] Body) {
Body[1] = escapeNewLines(b.name);
// TODO: remaining values from AI?
// Vision.Value = 1 - checked
Body[2] = "1";
// Touch.Value
Body[3] = "0";
Body[4] = b.wheelsFlag("AddAWheelSensor");
// Wheels.Value
Body[5] = "1";
// Arms.Value
Body[6] = "0";
// VisionConfig.VisionDown
Body[7] = b.cameraDirections.contains(CameraDirection.down) ? "1" : "0";
// VisionConfig.VisionLeft
Body[8] = b.cameraDirections.contains(CameraDirection.left) ? "1" : "0";
// VisionConfig.VisionRight
Body[9] = b.cameraDirections.contains(CameraDirection.right) ? "1" : "0";
// VisionConfig.VisionInFront
Body[10] = b.cameraDirections.contains(CameraDirection.inFront) ? "1" : "0";
// VisionConfig.VisionBehind
Body[11] = b.cameraDirections.contains(CameraDirection.behind) ? "1" : "0";
// VisionConfig.VisionSymbolicOrMagnitude(0)
Body[12] = eq(b.visionMode, VisionMode.nextSquare) ? "True" : "False";
// VisionConfig.VisionSymbolicOrMagnitude(1)
Body[13] = eq(b.visionMode, VisionMode.distanceToWall) ? "True" : "False";
Body[14] = b.wheelsFlag("MoveForward");
Body[15] = b.wheelsFlag("MoveLeft");
Body[16] = b.wheelsFlag("MoveRight");
Body[17] = b.wheelsFlag("MoveBackward");
Body[18] = b.wheelsFlag("TurnRight");
Body[19] = b.wheelsFlag("TurnLeft");
Body[20] = b.wheelsFlag("TurnAround");
// VisionConfig.VisionSymbolicOrMagnitude(2)
Body[21] = eq(b.visionMode, VisionMode.wallOrNot) ? "True" : "False";
}
static void withBodySave(Runnable r) {
if (state.body.get().changed) {
int result = swingShowConfirmDialog(mainFrame, "Body has changed! - Save it?", "Smarty", JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION) {
saveBodyDialog(r);
return;
} else if (result == JOptionPane.CANCEL_OPTION)
return;
else
cset(state.body, "changed", false);
}
r.run();
}
static void newBody() {
withBodySave(new Runnable() {
public void run() {
try {
newBodyWithoutConfirmation();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "newBodyWithoutConfirmation();";
}
});
}
static void newBodyWithoutConfirmation() {
cdelete(state.body.get());
cset(state, "body", cnew(SmartyBody.class));
finishBodySetup();
}
static void loadBody(File f) {
try {
List lines = linesFromFile_list(f);
if (eqAfterRtrim(lines(lines), exportBodyForSaving())) {
infoBox("Body is the same as current one");
return;
}
String[] Body = asStringArray(itemPlusList("", lines));
newBody();
var b = state.body.get();
// TODO: remaining values
cset(b, "name", Body[1]);
if (eq(Body[4], "1"))
b.wheels.add("AddAWheelSensor");
if (eq(Body[7], "1"))
b.cameraDirections.add(CameraDirection.down);
if (eq(Body[8], "1"))
b.cameraDirections.add(CameraDirection.left);
if (eq(Body[9], "1"))
b.cameraDirections.add(CameraDirection.right);
if (eq(Body[10], "1"))
b.cameraDirections.add(CameraDirection.inFront);
if (eq(Body[11], "1"))
b.cameraDirections.add(CameraDirection.behind);
if (eq(Body[12], "True"))
b.visionMode = VisionMode.nextSquare;
if (eq(Body[13], "True"))
b.visionMode = VisionMode.distanceToWall;
if (eq(Body[14], "1"))
b.wheels.add("MoveForward");
if (eq(Body[15], "1"))
b.wheels.add("MoveLeft");
if (eq(Body[16], "1"))
b.wheels.add("MoveRight");
if (eq(Body[17], "1"))
b.wheels.add("MoveBackward");
if (eq(Body[18], "1"))
b.wheels.add("TurnRight");
if (eq(Body[19], "1"))
b.wheels.add("TurnLeft");
if (eq(Body[20], "1"))
b.wheels.add("TurnAround");
if (eq(Body[21], "True"))
b.visionMode = VisionMode.wallOrNot;
cset(b, "changed", false);
b.change();
updateTabs();
infoBox("Body loaded: " + fileName(f));
addRecentBodyFile(f);
finishBodySetup();
} catch (Throwable __e) {
messageBox(__e);
}
}
static void saveBodyDialog() {
saveBodyDialog(null);
}
static void saveBodyDialog(Runnable whenDone) {
{
swing(new Runnable() {
public void run() {
try {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setSelectedFile(newFile(mainDir(), sanitizeFileName(state.body.get().name)));
fileChooser.setFileFilter(new FileNameExtensionFilter(("Smarty Body files (*." + bodyFileExtension + ")"), bodyFileExtension));
if (fileChooser.showSaveDialog(mainFrame) == JFileChooser.APPROVE_OPTION) {
File f = defaultExtension(bodyFileExtension, fileChooser.getSelectedFile());
cset(state.body, "name", fileNameWithoutExtension(f));
updateTabs();
saveBody(f);
infoBox("Body saved as " + f.getName());
}
callF(whenDone);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "new JFileChooser fileChooser;\r\n fileChooser.setSelectedFile(newFile(mainDi...";
}
});
}
}
static void loadBodyDialog() {
withBodySave(new Runnable() {
public void run() {
try {
loadBodyDialogWithoutConfirmation();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "loadBodyDialogWithoutConfirmation();";
}
});
}
static void loadBodyDialogWithoutConfirmation() {
swing(new Runnable() {
public void run() {
try {
JFileChooser fileChooser = new JFileChooser(mainDir());
fileChooser.setFileFilter(new FileNameExtensionFilter(("Smarty Body files (*." + bodyFileExtension + ")"), bodyFileExtension));
if (fileChooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION)
loadBody(fileChooser.getSelectedFile());
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "JFileChooser fileChooser = new(mainDir());\r\n fileChooser.setFileFilter(new F...";
}
});
}
static String infosForWindowTitle() {
return " - World= " + state.worldName + ", Body= " + state.body.get().name + ", Run done on " + simpleDateFormat_defaultTZ_now("MM-dd-YYYY") + " (mm-dd-yyyy) " + simpleDateFormat_defaultTZ_now("HH:mm:ss");
}
static void updateFrameTitles() {
frameTitle(mainFrame, "Smarty's World" + infosForWindowTitle());
frameTitle(historyFrame, "Stimulus/Response, Percept/Action History" + infosForWindowTitle());
frameTitle(memoryFrame, "Smarty's Memory" + infosForWindowTitle());
}
// Make the dynamic menus
static void makeMenus() {
addMenu(mainFrame, "Worlds", "New... (Ctrl+N)", new Runnable() {
public void run() {
try {
newWorld();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "newWorld();";
}
}, "Retrieve... (Ctrl+R)", new Runnable() {
public void run() {
try {
loadWorldDialog();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "loadWorldDialog();";
}
}, "Save... (Ctrl+S)", new Runnable() {
public void run() {
try {
saveWorldDialog();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "saveWorldDialog();";
}
}, "---", mapWithIndexStartingAt1(reversed(keys(state.recentWorldFiles)), (idx, f) -> jMenuItem(idx + " " + fileName(f), new Runnable() {
public void run() {
try {
withWorldSave(new Runnable() {
public void run() {
try {
loadWorld(f);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "loadWorld(f)";
}
});
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "withWorldSave(r { loadWorld(f) })";
}
})), empty(state.recentWorldFiles) ? null : "---", "Exit", runnableThread(new Runnable() {
public void run() {
try {
killVM();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "killVM();";
}
}));
addMenu(mainFrame, "Bodies", "New... (Ctrl+N)", new Runnable() {
public void run() {
try {
newBody();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "newBody();";
}
}, "Retrieve... (Ctrl+R)", new Runnable() {
public void run() {
try {
loadBodyDialog();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "loadBodyDialog();";
}
}, "Save... (Ctrl+S)", new Runnable() {
public void run() {
try {
saveBodyDialog();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "saveBodyDialog();";
}
}, "---", mapWithIndexStartingAt1(reversed(keys(state.recentBodyFiles)), (idx, f) -> jMenuItem(idx + " " + fileName(f), new Runnable() {
public void run() {
try {
withBodySave(new Runnable() {
public void run() {
try {
loadBody(f);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "loadBody(f)";
}
});
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "withBodySave(r { loadBody(f) })";
}
})), empty(state.recentBodyFiles) ? null : "---", "Exit", runnableThread(new Runnable() {
public void run() {
try {
killVM();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "killVM();";
}
}));
}
static void goCmd() {
smartyQ.add(new Runnable() {
public void run() {
try {
goCmd_impl();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "goCmd_impl();";
}
});
}
static void goCmd_impl() {
try {
evalWithTimeout(10.0, new Runnable() {
public void run() {
try {
print("goCmd");
if (!state.body.get().used) {
finishBodySetup();
cset(state.body, "used", true);
enableBodyControls(false);
}
smarty.bodies.BodyFunction2();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "print(\"goCmd\");\r\n \r\n if (!state.body.get().used) {\r\n finishB...";
}
});
} catch (Throwable __e) {
messageBox(__e);
}
}
static int Indx(int row, int col) {
// C is the across / column location - 0 based
// R is the down / row location - 0 based
// the function gives the index into NG and CWP linear arrays - 0 based
// can not be greater than 199 because 200+ used for wall letters
return state.gridCols * row + col;
}
// NG(I).Caption is contents of cell x/y
// with I = WallNo(x, y, direction)
// NG Caption is either "" or smarty.Smarty
// or Chr$(64 + InNG - 200) [location letter?]
// WP$ seems to hold the playing field
// WP$(R, C) can be ABlock$
/* From Brett:
WP$ contains either a space, a block or the smarty symbol.
The smarty symbol may be an S, >, <, ^, v or + depending on which way smarty is pointing.
NG().captions contain the letter for each location. The LookUnder$() routine returns the letter
for the camera that looks down at the current square. LookNorth$() etc. and other Look routines
return the cell letter that is one cell away.
The higher index values into NG() can contain letter for the walls set by the IDWalls() routine.
But this feature is not in use and the higher index entries of NG are invisible so a mouse down
cannot be done on them.
Note also that ScopeLeft$() and other Scope routines that would return wall letters are not in use.
*/
static int InRow() {
return state.smartyY;
}
static int InCol() {
return state.smartyX;
}
static void setSmartyDirection(String smartyDirection) {
if (cset_trueIfChanged(state, "smartyDirection", smartyDirection))
repaintGrid();
}
// query cell for Smarty's brain
static String WP(int y, int x) {
if (x == InCol() && y == InRow())
return state.smartyDirection;
else
return getCell(x, y).obstacle() ? smarty.ABlock : smarty.ASpace;
}
// put more static functions here
static class TheWorld extends Smarty.TheWorld {
// find what letter we are standing on
public String LookUnder() {
return str(smartyCell().letter);
}
void moveRelative(int x, int y) {
x += state.smartyX;
y += state.smartyY;
if (!inGrid(x, y) || getCell(x, y).obstacle())
smarty.Motion = smarty.NoMove;
else {
smarty.Motion = "Y";
state.moveSmarty(x, y);
}
}
public void MoveWest() {
moveRelative(-1, 0);
}
public void MoveSouth() {
moveRelative(0, 1);
}
public void MoveEast() {
moveRelative(1, 0);
}
public void MoveNorth() {
moveRelative(0, -1);
}
public void DisplayStimuliAndResponse(int[][][] inputValues, char response) {
List leftStack = new ArrayList();
List rightStack = new ArrayList();
for (int Sens = 1; Sens <= smarty.NumSenses; Sens++) {
int NumSensors = smarty.Senses[Sens][smarty.NumberOfSensors];
if (NumSensors == 0)
continue;
if (NumSensors != 1)
warn("More than one sensor in sense");
String label = smarty.Sense[Sens] + ":";
var inputValue = inputValues[Sens][smarty.Valu][smarty.Fired];
String text;
if (smarty.Senses[Sens][smarty.SymbolicOrMagnitude] == smarty.Magnitude)
text = str(charPlus(inputValue, '0')) + (debugValues ? " [magn " + inputValue + "]" : "");
else
text = lookupOrKeep(winToUnicode, str((char) inputValue)) + // A, B, C etc
(debugValues ? " [char " + inputValue + "]" : "");
leftStack.add(withLabel(withTypeWriterFont(jlabel(label)), jlabel(text)));
}
for (int Devs = 1; Devs <= smarty.NumDevices; Devs++) {
String label = smarty.Device[Devs] + ":";
rightStack.add(withLabel(withTypeWriterFont(jlabel(label)), jlabel(winToUnicode(response))));
}
scpStimuliAndResponse.set(jhgridWithSpacing(vstack(leftStack), vstack(rightStack)));
}
public void Update_View() {
// called by World.LookInside_Click() to SeeHistory and Bodies.BodyFunction2()
// refreshes all the subwindows
historyDisplay();
dumpLTM();
}
public void setBinonDisplayObjList(String text) {
cset(state, "memory1", text);
setText(memoryTextArea1, winToUnicode(text));
}
public void setBinonDisplayChngResults(String text) {
cset(state, "binonDisplayChngResults", text);
rstUpdateChngResults.trigger();
}
public void appendBinonDisplayChngResults(String text) {
cset(state, "binonDisplayChngResults", state.binonDisplayChngResults + text);
rstUpdateChngResults.trigger();
}
String lookDirection(int dx, int dy) {
int x = InCol() + dx, y = InRow() + dy;
// If off top of board or next one is a block
if (// must be on board
inGrid(x, y))
if (eq(WP(y, x), smarty.ABlock))
// looking at a wall
return smarty.Wall;
else
// valid square to move into
return str(getCell(x, y).letter);
else
// looking beyond grid
return smarty.Wall;
}
public String LookNorth() {
return lookDirection(0, -1);
}
public String LookSouth() {
return lookDirection(0, 1);
}
public String LookWest() {
return lookDirection(-1, 0);
}
public String LookEast() {
return lookDirection(1, 0);
}
public void PointUnder() {
setSmartyDirection(smarty.Smarty);
}
public void PointNorth() {
setSmartyDirection(smarty.UpArrow);
}
public void PointSouth() {
setSmartyDirection(smarty.DownArrow);
}
public void PointWest() {
setSmartyDirection(smarty.LeftArrow);
}
public void PointEast() {
setSmartyDirection(smarty.RightArrow);
}
public int RangeNorth() {
return rangeDirection(0, -1);
}
public int RangeSouth() {
return rangeDirection(0, 1);
}
public int RangeWest() {
return rangeDirection(-1, 0);
}
public int RangeEast() {
return rangeDirection(1, 0);
}
public int rangeDirection(int dx, int dy) {
// Distance to wall
int x = InCol(), y = InRow();
int i = 0;
do {
++i;
x += dx;
y += dy;
// End if off rightside of board or next one is a block
} while (inGrid(x, y) && !getCell(x, y).obstacle());
return i;
}
public void showSensorValues(String text) {
cset(state, "sensorValuesText", text);
setText(taSensorValues, winToUnicode(text));
}
public void showDeviceValues(String text) {
cset(state, "deviceValuesText", text);
setText(taDeviceValues, winToUnicode(text));
}
}
// end of TheWorld
static void initSmarty() {
smarty.World = new TheWorld();
smarty.Initialize_Adaptron();
}
static void finishBodySetup() {
resetSmarty();
}
static void resetSmarty() {
print("Finishing body setup");
ResetSmartyLocation();
// set all memory, S-List, Habit stack
smarty.Reset_Adaptron();
cset(state, "history1", "", "history2", "", "memory1", "");
setText(historyTextArea1, "");
setText(historyTextArea2, "");
setText(memoryTextArea1, "");
setText(memoryTextArea2, "");
bodyToArray(state.body.get(), smarty.BodySetting);
// pnl("BodySetting", smarty.BodySetting);
/*if (Vision.Value = 1)*/
smarty.SetupVision();
// if (Touch.Value = 1) smarty.SetupTouch();
/*if (Wheels.Value = 1)*/
smarty.SetupWheels();
// if (Arms.Value = 1) smarty.SetupArms();
// Setup display of stimuli at bottom of World screen
SetupStimulusResponseDisplay();
updateTabs();
}
// not needed
static void SetupStimulusResponseDisplay() {
}
// from Adapt.frm / HISTORYDISPLAY
static void historyDisplay() {
List lines = new ArrayList();
StringBuilder[] ILines$ = new StringBuilder[10 + 1];
// After 250 events the IO.Text area wraps the lines
int GroupSize = 250;
StringBuilder NumberLine$ = new StringBuilder();
StringBuilder OLine1$ = new StringBuilder();
for (int Group = 0; Group <= (smarty.LIN - 1) / GroupSize; Group++) {
int EndLIN = min(GroupSize * Group + GroupSize, smarty.LIN);
for (int E = GroupSize * Group + 1; E <= EndLIN; E++) {
if (E == GroupSize * Group + 1) {
// If it is the 1st position / event in the line then
NumberLine$ = new StringBuilder("Step # : ");
for (// Add labels to start of lines
int Sn = 1; // Add labels to start of lines
Sn <= smarty.NumSenses; // Add labels to start of lines
Sn++) // The name of the sense
ILines$[Sn] = new StringBuilder(takeFirst(smarty.Sense[Sn] + ": ", 9));
// The name of the action device
OLine1$ = new StringBuilder(takeFirst(smarty.Device[1] + ": ", 9));
}
// visual-basic style int-to-string!
String E_str = " " + E;
// the event number
NumberLine$.append(E_str);
// the space taken up by the event number
int Wdth = l(E_str);
for (int Sn = 1; Sn <= smarty.NumSenses; Sn++) ILines$[Sn].append(takeLast(" " + smarty.INPUTS[E][Sn], Wdth));
OLine1$.append(takeLast(" " + smarty.OUTPUTS[E][1], Wdth));
}
lines.add(str(NumberLine$));
for (int Sn = 1; Sn <= smarty.NumSenses; Sn++) lines.add(str(ILines$[Sn]));
lines.add(str(OLine1$));
lines.add("");
}
String text = rtrim(lines(lines));
cset(state, "history1", text);
setText(historyTextArea1, winToUnicode(text));
}
// end of historyDisplay
static void dumpLTM() {
// Called by Update_View
String MemValT = null;
int[] MemSize = new int[2000 + 1];
String Sen = null;
String Att = null;
String Pe = null;
String Ob = null;
Object BinTyp = null;
// a Spac$,
boolean DisplayIt = false;
// '-------------------- Long Term Memory (LTM) - Monitoring Info. -------------------------
// 'For Display purposes only by Adapt.DUMPLTM in Adapt.LTMem
// 'Long term memory contains a list of the stimuli that have been paid attention to.
// 'It stores Perceptual sequences as a pair of sequential memory locations.
//
// Public LTMEMORY&(1 To 2000, 1 To 6)
// '1st index is StoreAt cycle number
// '2nd index is what type of information is in the LTM
//
// '---- LTMEMORY() 2nd index values - type of information in LTMEMORY()
// Public LtmPerceptTyp '1 Percept binon type
// Public LtmPerceptBin '2 Percept binon
// Public LtmESType '3 Type of ES Binon - may be an SS
// Public LtmESActBin '4 ES Actbin
// Public LtmARType '5 Type of AR Binon - may be an RR
// Public LtmARActBin '6 AR ActBin
// Public LtmActionTyp '7 Action binon type
// Public LtmActionBin '8 Action binon
for (// find the widest binon # for all the StoreAt positions
var I = 1; // find the widest binon # for all the StoreAt positions
I <= smarty.StoreAt; // find the widest binon # for all the StoreAt positions
I++) {
MemSize[I] = intMax(l(str(I)) + 1, 3, l(vbToStr(smarty.LTMEMORY[I][smarty.LtmPerceptBin])), l(vbToStr(smarty.LTMEMORY[I][smarty.LtmESActBin])), l(vbToStr(smarty.LTMEMORY[I][smarty.LtmARActBin])), l(vbToStr(smarty.LTMEMORY[I][smarty.LtmActionBin])));
}
StringBuffer text = new StringBuffer();
int GroupSize = 250;
var tempVar = (smarty.StoreAt - 1) / GroupSize;
for (int Group = 0; Group <= (smarty.StoreAt - 1) / GroupSize; Group++) {
// Only put up the available values
int EndLIN = GroupSize * Group + GroupSize;
if (EndLIN > smarty.StoreAt)
EndLIN = smarty.StoreAt;
StringBuilder MemLine = new StringBuilder();
for (// For each event in LTM display the event number
int E = GroupSize * Group + 1; // For each event in LTM display the event number
E <= EndLIN; // For each event in LTM display the event number
E++) MemLine.append(pad(MemSize[E], str(E)));
text.append(MemLine + "\r\n");
// ------Percepts(.., Fired) Type
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
// Att$ = Str$(STM(1, BinTp, Current))
Att = smarty.BinonTypeName[smarty.LTMEMORY[E][smarty.LtmPerceptTyp]][smarty.BinAbbreviation];
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
// ------Percepts(.., Fired) Binon
// Trigger STIMULUS intensity
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
// Att$ = Str$(STM(1, BinId, Current))
Att = str(smarty.LTMEMORY[E][smarty.LtmPerceptBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
// ------ES ActBin type
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
Att = smarty.AESR(smarty.LTMEMORY[E][smarty.LtmESActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
// ------ LTMEMORY ActBin Object binon
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
Att = String.valueOf(smarty.LTMEMORY[E][smarty.LtmESActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
// ------AR ActBin type
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
Att = smarty.AESR(smarty.LTMEMORY[E][smarty.LtmARActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
// ------ LTMEMORY ActBin Object binon
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
Att = String.valueOf(smarty.LTMEMORY[E][smarty.LtmARActBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
// ------Actions(.., Fired) Type
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
Att = smarty.BinonTypeName[smarty.LTMEMORY[E][smarty.LtmActionTyp]][smarty.BinAbbreviation];
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n");
// ------Actions(.., Fired) Binon
MemLine = new StringBuilder();
for (// For each event in LTM
int E = GroupSize * Group + 1; // For each event in LTM
E <= EndLIN; // For each event in LTM
E++) {
Att = String.valueOf(smarty.LTMEMORY[E][smarty.LtmActionBin]);
MemLine.append(pad(MemSize[E], Att));
}
text.append(MemLine + "\r\n\r\n");
}
String s = rtrim(str(text));
cset(state, "history2", s);
setText(historyTextArea2, winToUnicode(s));
}
// End of dumpLTM
static void uiZoom(double percent) {
if (cset_trueIfChanged(state, "fontScale", toFloat(percent / 100)))
restart();
}
static void updateFontScale(float scale) {
swingFontScale(scale);
spacing = iround(defaultSpacing * scale);
}
static void selfTest() {
new SelfTest().run();
}
static class SelfTest {
Scorer scorer = new Scorer();
void loadWorldAndBody(String worldText, String bodyText) {
File bodyFile = programFile("body.tmp");
File worldFile = programFile("world.tmp");
saveTextFile(worldFile, dropLeadingEmptyLines(worldText));
loadWorld(worldFile);
saveTextFile(bodyFile, dropLeadingEmptyLines(bodyText));
loadBody(bodyFile);
}
public void run() {
activateConsole();
print("Self-Test START");
String text = loadSnippet("#1031220");
List parts = splitAtMultipleEqualsLines(text);
assertEqualsVerbose(6, l(parts));
loadWorldAndBody(parts.get(0), parts.get(1));
List outputTexts = subList(parts, 2);
do {
// step 1
if (!step(outputTexts))
break;
text = loadSnippet("#1031228");
outputTexts = getMulti(splitAtMultipleEqualsLines(text), 2, 3, 0, 1);
// step 2
if (!step(outputTexts))
break;
// step 10
text = loadSnippet("#1031229");
outputTexts = getMulti(splitAtMultipleEqualsLines(text), 0, 1, 2, 3);
for (int _repeat_12 = 0; _repeat_12 < 7; _repeat_12++) {
goCmd_impl();
}
if (!step(outputTexts))
break;
// step 50
text = loadSnippet("#1031230");
outputTexts = getMulti(splitAtMultipleEqualsLines(text), 2, 3, 0, 1);
for (int _repeat_13 = 0; _repeat_13 < 39; _repeat_13++) {
goCmd_impl();
}
if (!step(outputTexts))
break;
} while (false);
// second test case
text = loadSnippet("#1031231");
parts = splitAtMultipleEqualsLines(text);
assertEqualsVerbose(6, l(parts));
loadWorldAndBody(parts.get(0), parts.get(1));
do {
// step 30
outputTexts = getMulti(subList(parts, 2), 2, 3, 0, 1);
for (int _repeat_14 = 0; _repeat_14 < 29; _repeat_14++) {
goCmd_impl();
}
if (!step(outputTexts))
break;
} while (false);
// third test case
text = loadSnippet("#1031238");
parts = splitAtMultipleEqualsLines(text);
assertEqualsVerbose(6, l(parts));
loadWorldAndBody(parts.get(0), parts.get(1));
do {
// step 50
outputTexts = getMulti(subList(parts, 2), 2, 3, 0, 1);
for (int _repeat_15 = 0; _repeat_15 < 49; _repeat_15++) {
goCmd_impl();
}
if (!step(outputTexts))
break;
} while (false);
print("SELF-TEST RESULT: " + scorer);
}
// returns false if something failed
boolean step(List outputTexts) {
goCmd_impl();
List diffs = new ArrayList();
printAsciiHeading("HISTORY 1");
print(addAndReturn(diffs, unidiff2(historyTextArea1, outputTexts.get(2))));
printAsciiHeading("HISTORY 2");
print(addAndReturn(diffs, unidiff2(historyTextArea2, outputTexts.get(3))));
printAsciiHeading("MEMORY 1");
print(addAndReturn(diffs, unidiff2(memoryTextArea1, outputTexts.get(0))));
printAsciiHeading("MEMORY 2");
print(addAndReturn(diffs, unidiff2(state.binonDisplayChngResults, outputTexts.get(1))));
boolean ok = allStringsEmpty(diffs);
scorer.add(ok, nOutputs(nempties(diffs)) + " differ");
return ok;
}
}
static String unidiff2(JTextComponent ta, String text) {
return unidiff2(getText(ta), text);
}
static String unidiff2(String actual, String text) {
return unidiff(cleanUpForDiff(text), cleanUpForDiff(actual));
}
static String cleanUpForDiff(String text) {
return fixNewLines(rtrim(dropLeadingEmptyLines(text)));
}
static void ResetSmartyLocation() {
if (!getCell(state.startX, state.startY).obstacle())
state.moveSmarty(state.startX, state.startY);
}
static String winToUnicode(Object text) {
return mapCharacters(str(text), c -> lookupOrKeep(winToUnicode, str(c)));
}
static A monospaced(A a) {
return setFont(monospacedFontID, swingScale(monospacedFontSize), a);
}
static int strL(String s) {
return s == null ? 0 : s.length();
}
static int lCharSequence(CharSequence s) {
return s == null ? 0 : s.length();
}
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
static Object first(Object list) {
return first((Iterable) list);
}
static A first(List list) {
return empty(list) ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static A first(IterableIterator i) {
return first((Iterator) i);
}
static A first(Iterator i) {
return i == null || !i.hasNext() ? null : i.next();
}
static A first(Iterable i) {
if (i == null)
return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static Character first(String s) {
return empty(s) ? null : s.charAt(0);
}
static Character first(CharSequence s) {
return empty(s) ? null : s.charAt(0);
}
static A first(Pair p) {
return p == null ? null : p.a;
}
static Byte first(byte[] l) {
return empty(l) ? null : l[0];
}
static int min(int a, int b) {
return Math.min(a, b);
}
static long min(long a, long b) {
return Math.min(a, b);
}
static float min(float a, float b) {
return Math.min(a, b);
}
static float min(float a, float b, float c) {
return min(min(a, b), c);
}
static double min(double a, double b) {
return Math.min(a, b);
}
static double min(double[] c) {
double x = Double.MAX_VALUE;
for (double d : c) x = Math.min(x, d);
return x;
}
static float min(float[] c) {
float x = Float.MAX_VALUE;
for (float d : c) x = Math.min(x, d);
return x;
}
static byte min(byte[] c) {
byte x = 127;
for (byte d : c) if (d < x)
x = d;
return x;
}
static short min(short[] c) {
short x = 0x7FFF;
for (short d : c) if (d < x)
x = d;
return x;
}
static int min(int[] c) {
int x = Integer.MAX_VALUE;
for (int d : c) if (d < x)
x = d;
return x;
}
static int l(Object[] a) {
return a == null ? 0 : a.length;
}
static int l(boolean[] a) {
return a == null ? 0 : a.length;
}
static int l(byte[] a) {
return a == null ? 0 : a.length;
}
static int l(short[] a) {
return a == null ? 0 : a.length;
}
static int l(long[] a) {
return a == null ? 0 : a.length;
}
static int l(int[] a) {
return a == null ? 0 : a.length;
}
static int l(float[] a) {
return a == null ? 0 : a.length;
}
static int l(double[] a) {
return a == null ? 0 : a.length;
}
static int l(char[] a) {
return a == null ? 0 : a.length;
}
static int l(Collection c) {
return c == null ? 0 : c.size();
}
// consumes the iterator && closes it if possible
static int l(Iterator i) {
return iteratorCount_int_close(i);
}
static int l(Map m) {
return m == null ? 0 : m.size();
}
static int l(CharSequence s) {
return s == null ? 0 : s.length();
}
static long l(File f) {
return f == null ? 0 : f.length();
}
static int l(Object o) {
return o == null ? 0 : o instanceof String ? l((String) o) : o instanceof Map ? l((Map) o) : o instanceof Collection ? l((Collection) o) : o instanceof Object[] ? l((Object[]) o) : o instanceof boolean[] ? l((boolean[]) o) : o instanceof byte[] ? l((byte[]) o) : o instanceof char[] ? l((char[]) o) : o instanceof short[] ? l((short[]) o) : o instanceof int[] ? l((int[]) o) : o instanceof float[] ? l((float[]) o) : o instanceof double[] ? l((double[]) o) : o instanceof long[] ? l((long[]) o) : (Integer) call(o, "size");
}
static int l(MultiSet ms) {
return ms == null ? 0 : ms.size();
}
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
static String rep(int n, char c) {
return repeat(c, n);
}
static String rep(char c, int n) {
return repeat(c, n);
}
static List rep(A a, int n) {
return repeat(a, n);
}
static List rep(int n, A a) {
return repeat(n, a);
}
static void change() {
// mainConcepts.allChanged();
// safe version for now cause function is sometimes included unnecessarily (e.g. by EGDiff)
callOpt(getOptMC("mainConcepts"), "allChanged");
}
// sbool ping_actions_shareable = true;
static volatile boolean ping_pauseAll = false;
// poll pauseAll flag every 100
static int ping_sleep = 100;
static volatile boolean ping_anyActions = false;
static Map ping_actions = newWeakHashMap();
static ThreadLocal ping_isCleanUpThread = new ThreadLocal();
// always returns true
static boolean ping() {
if (ping_pauseAll || ping_anyActions)
ping_impl(true);
// ifndef LeanMode ping_impl(); endifndef
return true;
}
// returns true when it slept
static boolean ping_impl(boolean okInCleanUp) {
try {
if (ping_pauseAll && !isAWTThread()) {
do Thread.sleep(ping_sleep); while (ping_pauseAll);
return true;
}
if (ping_anyActions) {
// don't allow sharing ping_actions
if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get()))
failIfUnlicensed();
Object action = null;
synchronized (ping_actions) {
if (!ping_actions.isEmpty()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty())
ping_anyActions = false;
}
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Exception __e) {
throw rethrow(__e);
}
}
static String vbToStr(long l) {
return l < 0 ? str(l) : " " + l;
}
// Use like this: printVars_str(+x, +y);
// Or: printVars("bla", +x);
// Or: printVars bla(+x);
static void printVars_str(Object... params) {
String s = "";
if (odd(l(params))) {
s = str(first(params));
if (endsWithLetterOrDigit(s))
s += ": ";
params = dropFirst(params);
}
print(s + renderVars_str(params));
}
static List replace(List l, A a, A b) {
for (int i = 0; i < l(l); i++) if (eq(l.get(i), a))
l.set(i, b);
return l;
}
static List replace(A a, A b, List l) {
return replace(l, a, b);
}
// replace all occurrences of a in s with b
static String replace(String s, String a, String b) {
return s == null ? null : a == null || b == null ? s : s.replace(a, b);
}
static String replace(String s, char a, char b) {
return s == null ? null : s.replace(a, b);
}
static List takeFirst(List l, int n) {
return l(l) <= n ? l : newSubListOrSame(l, 0, n);
}
static List takeFirst(int n, List l) {
return takeFirst(l, n);
}
static String takeFirst(int n, String s) {
return substring(s, 0, n);
}
static String takeFirst(String s, int n) {
return substring(s, 0, n);
}
static CharSequence takeFirst(int n, CharSequence s) {
return subCharSequence(s, 0, n);
}
static List takeFirst(int n, Iterable i) {
if (i == null)
return null;
List l = new ArrayList();
Iterator it = i.iterator();
for (int _repeat_0 = 0; _repeat_0 < n; _repeat_0++) {
if (it.hasNext())
l.add(it.next());
else
break;
}
return l;
}
static int[] takeFirst(int n, int[] a) {
return takeFirstOfIntArray(n, a);
}
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null)
return false;
if (// TODO: remove this
o instanceof ThreadLocal)
return isTrue(((ThreadLocal) o).get());
throw fail(getClassName(o));
}
static boolean isTrue(Boolean b) {
return b != null && b.booleanValue();
}
static boolean empty(Collection c) {
return c == null || c.isEmpty();
}
static boolean empty(Iterable c) {
return c == null || !c.iterator().hasNext();
}
static boolean empty(CharSequence s) {
return s == null || s.length() == 0;
}
static boolean empty(Map map) {
return map == null || map.isEmpty();
}
static boolean empty(Object[] o) {
return o == null || o.length == 0;
}
static boolean empty(Object o) {
if (o instanceof Collection)
return empty((Collection) o);
if (o instanceof String)
return empty((String) o);
if (o instanceof Map)
return empty((Map) o);
if (o instanceof Object[])
return empty((Object[]) o);
if (o instanceof byte[])
return empty((byte[]) o);
if (o == null)
return true;
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(Iterator i) {
return i == null || !i.hasNext();
}
static boolean empty(double[] a) {
return a == null || a.length == 0;
}
static boolean empty(float[] a) {
return a == null || a.length == 0;
}
static boolean empty(int[] a) {
return a == null || a.length == 0;
}
static boolean empty(long[] a) {
return a == null || a.length == 0;
}
static boolean empty(byte[] a) {
return a == null || a.length == 0;
}
static boolean empty(short[] a) {
return a == null || a.length == 0;
}
static boolean empty(MultiSet ms) {
return ms == null || ms.isEmpty();
}
static boolean empty(File f) {
return getFileSize(f) == 0;
}
static String mapCharacters(String s, IF1 f) {
return join(map(characters(s), f));
}
static String mapCharacters(IF1 f, String s) {
return mapCharacters(s, f);
}
static RuntimeException fail() {
throw new RuntimeException("fail");
}
static RuntimeException fail(Throwable e) {
throw asRuntimeException(e);
}
static RuntimeException fail(Object msg) {
throw new RuntimeException(String.valueOf(msg));
}
static RuntimeException fail(String msg) {
throw new RuntimeException(msg == null ? "" : msg);
}
static RuntimeException fail(String msg, Throwable innerException) {
throw new RuntimeException(msg, innerException);
}
static List takeLast(List l, int n) {
return newSubList(l, l(l) - n);
}
static List takeLast(int n, List l) {
return takeLast(l, n);
}
static String takeLast(int n, String s) {
return substring(s, l(s) - n);
}
static String takeLast(String s, int n) {
return substring(s, l(s) - n);
}
static Q startQ() {
return new Q();
}
static Q startQ(String name) {
return new Q(name);
}
static String unicode_blackSquare() {
return "\u25A0";
}
static String unicode_dottedSquare() {
return "\u2B1A";
}
static java.awt.Color colorFromHex(String hex) {
return awtColor(hex);
}
static String charRange(char first, char last) {
StringBuilder buf = new StringBuilder();
while (first <= last) buf.append(first++);
return str(buf);
}
static String charRange(int first, int last) {
return charRange((char) first, (char) last);
}
static String unicode_slightlySmilingFace() {
return codePointToString(0x1F642);
}
static String unindent_mls(String s) {
return autoUnindent_mls(s);
}
static HashMap litmap(Object... x) {
HashMap map = new HashMap();
litmap_impl(map, x);
return map;
}
static void litmap_impl(Map map, Object... x) {
if (x != null)
for (int i = 0; i < x.length - 1; i += 2) if (x[i + 1] != null)
map.put(x[i], x[i + 1]);
}
static String unicode(String hex) {
return codePointToString(parseHexInt(hex));
}
static String unicode_blackVerticalRectangle() {
return unicode("25AE");
}
static String unicode_whiteVerticalRectangle() {
return unicode("25AF");
}
static String unicode_blackSmallSquare() {
return "\u25AA";
}
static ReliableSingleThread rstWithPreDelay(int delay, Runnable r) {
return rstWithDelay(delay, r);
}
static ReliableSingleThread rstWithPreDelay(double seconds, Runnable r) {
return rstWithDelay(seconds, r);
}
// optimize by calling getText first
static boolean setText_opt = true;
static A setText(A c, Object text) {
setText((JComponent) c, text);
return c;
}
static A setText(final A c, Object text) {
// only for editable combo boxes at this point
final String s = strUnnull(text);
{
swing(new Runnable() {
public void run() {
try {
c.getEditor().setItem(s);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "c.getEditor().setItem(s);";
}
});
}
return c;
}
static void setText(JLabel c, Object text) {
setText((JComponent) c, text);
}
static JButton setText(JButton c, Object text) {
setText((JComponent) c, jlabel_textAsHTML_center_ifNeeded(strUnnull(text)));
return c;
}
static A setText(final A c, Object text) {
if (c == null)
return null;
final String s = strUnnull(text);
{
swing(new Runnable() {
public void run() {
try {
if (!setText_opt || neq(callOpt(c, "getText"), s))
call(c, "setText", s);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "if (!setText_opt || neq(callOpt(c, \"getText\"), s))\r\n call(c, \"setText\", s);";
}
});
}
return c;
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null)
for (A x : a) l.add(x);
return l;
}
static HashSet litset(A... items) {
return lithashset(items);
}
// not redirected
static volatile StringBuffer local_log = new StringBuffer();
// might be redirected, e.g. to main bot
static volatile Appendable print_log = local_log;
// in bytes - will cut to half that
static volatile int print_log_max = 1024 * 1024;
static volatile int local_log_max = 100 * 1024;
// total mute if set
static boolean print_silent = false;
static Object print_byThread_lock = new Object();
// special handling by thread - prefers F1
static volatile ThreadLocal