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 javax.swing.undo.UndoManager;
import java.nio.charset.Charset;
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.text.NumberFormat;
import java.nio.file.Path;
import java.text.*;
import java.util.TimeZone;
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 {
private int IntensityRange;
private static String[] Sense;
private boolean Processing50 = false;
static int MaxBodies;
static class Public {
}
static TheWorld World = new TheWorld();
static class WorldSize {
public static String Text;
}
static class TheWorld {
public static String LookUnder() {
return "";
}
public void MoveWest() {
}
public void MoveSouth() {
}
public void MoveEast() {
}
public void MoveNorth() {
}
public void PointEast() {
}
public void PointWest() {
}
public void PointNorth() {
}
public void PointSouth() {
}
public void PointUnder() {
}
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 int LookSouth() {
return 0;
}
public int LookNorth() {
return 0;
}
public int LookEast() {
return 0;
}
public int LookWest() {
return 0;
}
public static class SenseInfo {
public static String Text;
}
public static class DeviceInfo {
public static String Text;
}
public static class Go {
public static boolean Enabled = false;
}
}
// end of World
static class BinonDisplay {
public static class ObjList {
public static String Text;
}
public static class ChngResults {
public static String Text;
}
}
static class Adapt {
public static void Update_View() {
}
static class IO {
public static String Text;
}
static class LTMem {
public static String Text;
}
}
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%
static int JND;
// an "S"
static String Smarty;
// "<"
static String LeftArrow;
// ">"
static String RightArrow;
// "^"
static String UpArrow;
// "v"
static String DownArrow;
// "+"
static String FourWay;
// "Smarty0" The initial / default Body name
static String Smarty0;
// Contains the current body being used
static String[] BodySetting;
// 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
static int BodyPointing;
// direction body is pointing, 0=East, 1=South, 2=West, 3=North
static final int North = 3;
final int East = 0;
final int South = 1;
// direction body is pointing, 0=East, 1=South, 2=West, 3=North
final int West = 2;
// -------------------------- Senses and Sensors --------------------------
// The number of physical senses, Max of 10, dynamically set in SetUpSense()
static int NumSenses;
// Currently equals the NumProperties since each sense currently = 1 property type
// Maximum number of senses = max 10 physical senses
static int MaxSenses;
// 1, Flag for Senses versus Devices
static int IsSense;
// unused String StringSense; //Names of senses, up to 10 physical senses - assigned in SetupSense()
// Properties of the different senses
static 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
static int PropertyBinonType;
// 2, Symbolic or Magnitude indicator
static int SymbolicOrMagnitude;
// 3, Lower limit of range of values, zero is minimum (65 = "A")
static int LowerRangeLimit;
// 4, Upper limit of range of values, 255 is maximum (90 ="Z")
static int UpperRangeLimit;
// 5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360)
static int LinearOrCircular;
// 6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs
static int IntegersOrLogs;
// 7 Number of sensors in sensor array
static int NumberOfSensors;
// 8 are sensors adjacent (dependent) or independent
static int SensorsDependentOrIndependent;
// 1, Indicates that the values from this sense are symbolic, range A -> Z
static int Symbolic;
// 2, Indicates that the values from this sense are numeric, integers, range 0 -> Limit
static int Magnitude;
// 1, Indicates that the values go from the lower limit to upper limit
static int Linear;
// 2, Indicates that the values rap around from the upper limit to 0
static int Circular;
// 1, Indicates that the values are integer readings
static int IntegerValues;
// 2, Indicates that the values are already logs - orders of magnitude
static int LogValues;
// 1, Sensors in array are beside each other (adjacent)
static int Dependent;
// 2, Sensors are not associated with each other
static int Independent;
// -------------------- Values of stimuli from senses / sensors ------------------------------
// Stimulus values from senses/sensors
static int[][][] SensorValues = new int[10 + 1][2 + 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$)
static int Valu;
// =2, the count of times the value has repeated, also used below
static int XQCnt;
// "_", The character used when no letter provided for the IDL value of a TextBin binon
static String NoName;
// World.MoveDown() etc set this to indicate the direction the robot moved
static String Motion;
// "-" to indicate there was no motion in the Motion$ stimulus value
static String NoMove;
// "-flrb..." 'will contains the possible wheel motions
static String WheelMovement;
// WheelMovement$ = "-flrb" & TurnRght$ & TurnLft$ & TurnArnd$ ' rotate right, left and around 180 degrees
static String ABlock;
static String Wall;
static String EmptySquare;
// ---- SensorValues 3rd index values - which past stimulus it is - also used below
// =0 'stimulus put in this level upon firing before being processed
static int Fired;
// =1 'The Fired one becomes the Current one after processing
static int Current;
// -------------------- Devices ------------------------------------------------
// Number of output devices - max 4 - dynamically set in SetupDevice()
static int NumDevices;
// Maximum number of devices = max 4 devices
static int MaxDevices;
// Names of device, up to 4 devices - assigned in SetupDevice()
String[] Device = new String[4 + 1];
// 2, Flag for Devices versus Senses
static 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
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
static 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()]
static 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
static 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
static int AE;
// -1, Indicates the O1 or O2 pointer is not pointing to another binon
static 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
static 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
static final int INTERESTING = 2;
// Neutral, experienced 2 or 3 or more times
// 1 Neutral, experienced 2 or 3 or more times
static final int FAMILIAR = 1;
// -1 Interest not known yet
static int NoInterest;
// 2 or 3 - number of interest levels, 2= Novel and Familiar, 3= Novel, Interesting, and Familiar
static int InterestLevels;
// ---- Sequential or Parallel property values for Binons(x, SP)
// -1
static int Sequential;
// +1
static int Parallel;
// ---- Action or Attention property values for Binons(x, AE) - value = 0 for Parallel Percepts
// 1
static int Action;
// 2
static int Attention;
// ---- BinonType property values for Binons(x, BType)
// with 2 senses and 1 device this is =6, 4 senses & 4 devices = 33
static 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
static String[][] BinonTypeName = new String[68 + 1][2 + 1];
// ---- BinonTypeName$() 2nd index values
// 1
static int BinName;
// 2
static 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)
static 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
static 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
static 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)
static 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
static int MaxPercepts;
// Current and Fired Property binon and Percept IDs and XQ count
static 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
static 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
static int FirstSource;
// =2, the second / right source Percept binon
static int SecondSource;
// =3, The level in the Percept tree
static int PerceptLevel;
// -------------------- Left and Right Targets ---------------------------------------
// --- Linked List of Target Binons - for all binons -------------
// The number of Target binon entries created so far
static int NumTargets;
// 10000 = the max number of Target binon entries possible
static int MaxTargets;
// pointed to by Binons(ID, TriggerList) or by Binons(ID, GoalList)
static 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,
static int NLnk;
// may be a NullTarget at end of linked list
// 2 = a left or right Target binon
static int TargetBinon;
// =0, an NLnk pointer at end of linked list
static 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
static int TopLevel;
// The highest STM() entry produced / fired per cycle
int HighestPerceptLvl;
// =25, The highest level of complexity to which the tree can grow
static int MaxLevels;
// STM current history of Patterns - a tree with parts at level 1
static int[][][] STM = new int[1 + 2][1 + 2][25];
// 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
static 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.
static 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[1 + 2][1 + 2];
// 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
static int LtmPerceptTyp;
// 2 Percept binon
static int LtmPerceptBin;
// 3 Type of ES Binon - may be an S
static int LtmESType;
// 4 ES Actbin
static int LtmESActBin;
// 5 Type of AR Binon - may be an R
static int LtmARType;
// 6 AR ActBin
static int LtmARActBin;
// 7 Action binon type
static int LtmActionTyp;
// 8 Action binon
static int LtmActionBin;
// LTM POSITION OF LAST STIMULUS - location in LTMEMORY() - incremented by PerceptionAction()
static int StoreAt;
// 2000
static 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)
static String[][] INPUTS = new String[2000][1 + 2];
// OUTPUT history - List of Responses for each device (1 to 4)
static String[][] OUTPUTS = new String[2000][1 + 2];
// -------------------- Other Variables ------------------------------------------
// 1.2 for a 20% just noticeable difference
static double SizeBase;
// If it is 2.0 then that is a 100% just noticeable difference
static double IntensityBase;
// -------------------- Operational Values - Adaptron --------------------
static String ASpace;
// Chr$(16) ">"
static char SequentialSign;
// "+" was Chr$(186) two vertical lines was "/"
static String ParallelSign;
// True if create all combinations
static boolean CreateAll = false;
// False if use only familiar parts
// ********* Counters, Temporary values, Flags and Pointers ******
// ---------------------- Operational Values -------------------------------
static int Normal;
static int Happy;
static int Unhappy;
// Used as ActTypes for body display
static 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
// The highest level active acton being done subconsciously
static Public ActiveActon;
// If set then this is being done subconsciously (not being practiced)
// The Act is being done even though it is not being practiced
static Public DoingAct1;
// 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
static boolean DoingReaction = false;
// set true if repeating a known response as a reflexive reaction
static boolean DoingRepeat = false;
// Last reflexive response used from Acts list
static 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$()
static int LIN;
// unused boolean FreezeSList; //When true don't do the DUMPSTIMS any more
// Count of inputs for display of history
static int COUNTIN;
// The list of recent .WLD files created - kept in RecentWldList.TXT
static String[] RecentWorld = new String[4];
// The list of recent .BDY files created - kept in RecentBdyList.TXT
static String[] RecentBody = new String[4];
// Either, Running World or just Started
static int OperatingMode;
static int Running;
static int Started;
// ********* Counters, Temporary values, Flags and Pointers ******
// unused Public I, J, T, M, H, N, K, P, F, S, Hab;
// unused Public ThoughtDesire;
static char vbDblQuote;
// --------------- Colours --------------
static int Black;
static int White;
static int LightBlue;
static int DarkBlue;
// End of (Declarations)
public static void Initialize_Adaptron() {
// Called only once from World form when it loads, World.Form_Load()
// Initialize all values that don't change
// J = wingdings happy face "+" '"S"
Smarty = "J";
LeftArrow = chr(239);
RightArrow = chr(240);
UpArrow = chr(241);
DownArrow = chr(242);
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 = "#";
// a block, Chr$(219) is a black square in Terminal font
Wall = chr(219);
// Chr$(177) is a fuzzy square in Terminal font
EmptySquare = chr(177);
// ---- 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 = " ";
// ">"
SequentialSign = (char) 16;
// 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;
}
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) {
LeftBinon = TheBinon;
// Go down the left side to the bottom Property or Percept binon
while (// While we have an Action
BinonTypeOf(LeftBinon) == ActBin) {
// 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() + 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) {
LeftBinon = TheBinon;
// Go down the left side to the bottom property binon
while (// While we have a Percept
BinonTypeOf(LeftBinon) > NumProperties) {
// 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)
// '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) {
// 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
// XXX World.SenseInfo.Text = "";
for (Sns = 1; Sns <= NumSenses; Sns++) {
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];
// 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 Len(DisplayStimuli) for every iteration:
int tempVar = DisplayStimuli == null ? 0 : DisplayStimuli.length();
for (// blank out the NoMoveOrTurn$ "z" symbols
var I = 1; // blank out the NoMoveOrTurn$ "z" symbols
I <= tempVar; // blank out the NoMoveOrTurn$ "z" symbols
I++) {
if (DisplayStimuli.substring(I - 1, I - 1 + 1).equals(NoMoveOrTurn)) {
DisplayStimuli = replaceOneCharInString(DisplayStimuli, I - 1, ASpace);
}
}
}
}
// XXX World.SenseInfo.Text = World.SenseInfo.Text + ((String)(Sense[Sns] + ": ")).substring(0, 8) + " " + DisplayStimuli + " " + SymbOrMagn(IsSense, Sns) + "\r\n";
// & Senses[Sns][NumberOfSensors] & " "
}
}
// End of SetupSense()
private static void Stop() {
throw new RuntimeException("STOP");
}
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 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++) {
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 static // 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 static 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++) {
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++) {
for (SecondPtr = FirstPtr + 1; SecondPtr <= NumProperties; SecondPtr++) {
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) {
// populate next level up
ThisLevel = ThisLevel + 1;
for (FirstPtr = StartPercept; FirstPtr < EndPercept; FirstPtr++) {
for (SecondPtr = FirstPtr + 1; SecondPtr <= EndPercept; SecondPtr++) {
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++) {
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();
}
// 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();
} else if (// else is it higher than the next one available
DeviceNum > NumDevices + 1) {
Stop();
} 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();
}
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
// XXX World.DeviceInfo.Text = "";
for (int Dvc = 1; Dvc <= NumDevices; Dvc++) {
if (Devices[Dvc][SymbolicOrMagnitude] == Magnitude) {
DisplayResponses = Devices[Dvc][LowerRangeLimit] + " to" + Devices[Dvc][UpperRangeLimit];
} else // symbolic values
{
DisplayResponses = DeviceResponses[Dvc];
// 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 Len(DisplayResponses) for every iteration:
int tempVar = DisplayResponses == null ? 0 : DisplayResponses.length();
for (// blank out the NoMoveOrTurn$ "z" symbols
var I = 1; // blank out the NoMoveOrTurn$ "z" symbols
I <= tempVar; // blank out the NoMoveOrTurn$ "z" symbols
I++) {
if (DisplayResponses.substring(I - 1, I - 1 + 1).equals(NoMoveOrTurn)) {
DisplayResponses = replaceOneCharInString(DisplayResponses, I - 1, ASpace);
}
}
}
// XXX World.DeviceInfo.Text = World.DeviceInfo.Text + ((String)(Device[Dvc] + ": ")).substring(0, 8) + DisplayResponses + " " + SymbOrMagn(IsDevice, Dvc) + "\r\n";
}
}
// End of SetupDevice()
public static // 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;
// 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++) {
// 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++) {
if (I > 0) {
}
for (String = 1; String <= MaxSenses; String++) {
INPUTS[I][String] = "";
}
for (D = 1; D <= MaxDevices; D++) {
OUTPUTS[I][D] = "";
}
}
Adapt.IO.Text = "";
Adapt.LTMem.Text = "";
// UNUSED TriggerObj = NullObject;
// set true if last response was reflexive.
DoingReaction = false;
DoingRepeat = false;
// no subconscious acton active
ActiveActon = NullAct;
// UNUSED ExploreObj = NullObject; //will be set if reflexive response done.
// will be set if reflexive response done.
DoingAct1 = NullAct;
// 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;
}
}
// End of Reset-Adaptron()
private static void ResetRnd(int i) {
// TODO
}
public static void ClearMemory() {
// Called by Reset_Adaptron()
int Lk;
int T;
int I;
for (I = 1; I <= MaxBinons; I++) {
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++) {
// 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++) {
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++) {
Targets[Lk][NLnk] = NullTarget;
Targets[Lk][TargetBinon] = NullObject;
}
NumTargets = 0;
ClearExpectations();
BinonDisplay.ObjList.Text = "";
BinonDisplay.ChngResults.Text = "";
// Percent
JND = 20;
// SizeBase# = 1.2 for a 20% just noticeable difference
AssignBases();
}
// End of ClearMemory()
public static // Called by ClearMemory()
void ZeroTheCounts(// Called by ClearMemory()
int Habit) {
Binons[Habit][TQ] = 0;
Binons[Habit][GQ] = 0;
}
// End ZeroTheCounts()
public static // Called by ClearMemory()
void ClearSenses() {
for (int Sens = 1; Sens <= MaxSenses; Sens++) {
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 static // 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;
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + " ** Clearing Perceptions " + "\r\n";
for (Lvl = 1; Lvl <= MaxLevels; Lvl++) {
for (Percpt = Fired; Percpt <= MaxLevels; Percpt++) {
EmptySTM(Lvl, Percpt);
}
}
}
// End of ClearPerceptions()
public static // 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 || Obj2 == 0) {
Stop();
}
if (// if can not find the exact match
NumBinons >= MaxBinons) {
ObjId.set(NullObject);
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + "\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++) {
// 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
BinonDisplay.ChngResults.Text = "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++) {
// 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) {
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0/ Processing percepts at level" + 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;
}
}
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0a/ Pass" + 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++) {
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;
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + 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++) {
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--) {
// 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--) {
// 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: ";
}
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + 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++) {
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++) {
// 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++) {
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(), ' '));
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + " 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
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + DisplaySTM();
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + "\r\n";
}
// End of ReportPerceptions()
public final void DisplayPercepts(int CurrOrFired) {
int BinType;
// Report on Percept recognitions
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + " Percepts = ";
for (// All binon types except Actions
BinType = 1; // All binon types except Actions
BinType <= NumPercepts; // All binon types except Actions
BinType++) {
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + DisplayPercept(BinType, CurrOrFired);
}
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + "\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++) {
// 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--) {
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((VL.get().substring(0, 20) + " ").substring(0, 7));
return "#" + StringHelper.trim(String.valueOf(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) + " " + VL.get().substring(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 static 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 static // 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) + Binons[TheBinon][TriggerCount] + Binons[TheBinon][GoalCount] + " " + DisplayPattern(TheBinon) + " NEW" + "\r\n";
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + "\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) {
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) {
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) {
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) {
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + 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++) {
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--) {
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 static 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;
}
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + "\r\n" + " # EObj Pattern - Fired Binon List" + "\r\n";
Res = "";
for (var J = 1; J <= HighestPerceptLvl; J++) {
ExprObj = STM[J][BinId][Current];
if (ExprObj != NullObject) {
Ptrn = "";
if (// If we have an expected binon at this level then
ExprObj == PerceivedBinon) {
Ptrn = Ptrn + " This is the Perceived or Performed Binon";
}
Res = Res + (" " + J).substring((" " + J).length() - 5) + Binons[ExprObj][TriggerCount] + Binons[ExprObj][GoalCount] + " " + DisplayPattern(ExprObj) + " " + Ptrn + "\r\n";
}
}
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + 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++) {
// 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++) {
Res1 = new StringBuilder();
for (// For all binons
Objct = 1; // For all binons
Objct <= NumBinons; // For all binons
Objct++) {
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 = VL.get().substring(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((" " + Objct).substring((" " + Objct).length() - 3)).append((" " + Binons[Objct][OLv]).substring((" " + Binons[Objct][OLv]).length() - 3)).append(AESR(Objct)).append(" ").append(Ty1.get().substring(0, 2)).append((" " + Binons[Objct][O1]).substring((" " + Binons[Objct][O1]).length() - 3)).append(" ").append(Ty2.get().substring(0, 2)).append((" " + Binons[Objct][O2]).substring((" " + Binons[Objct][O2]).length() - 3)).append((" " + Binons[Objct][IDL]).substring((" " + Binons[Objct][IDL]).length() - 4)).append(String.valueOf(Binons[Objct][TriggerCount]).substring(String.valueOf(Binons[Objct][TriggerCount]).length() - 2)).append(String.valueOf(Binons[Objct][GoalCount]).substring(String.valueOf(Binons[Objct][GoalCount]).length() - 2)).append((" " + IntInfo).substring((" " + IntInfo).length() - 3)).append((" " + Binons[Objct][TQ]).substring((" " + Binons[Objct][TQ]).length() - 3)).append((" " + Binons[Objct][GQ]).substring((" " + 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
BinonDisplay.ObjList.Text = 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) {
// 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) {
// 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++) {
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) {
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) {
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + " * Practicing " + DisplayPattern(PracticingBinon.get()) + Reason + "\r\n";
} else {
Stop();
BinonDisplay.ChngResults.Text = BinonDisplay.ChngResults.Text + " * 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++) {
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;
// dump all the history and LTMem()
Adapt.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++) {
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++) {
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--) {
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++) {
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++) {
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++) {
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) {
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) {
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++) {
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);
}
}
static boolean showHelpOnStart = false;
static int spacing = 20;
static JFrame mainFrame;
static List> gridComponents;
static JComponent mainGrid;
static JCheckBoxMenuItem miShowLocations;
static SingleComponentPanel scpMainGrid, scpVisionConfig, scpWheelsConfig, scpCurrentSmarty;
static JFrame historyFrame, memoryFrame;
static JSpinner worldSizeSpinner;
// AI instance
static Smarty smarty = new Smarty();
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 = basicUnicodeSmiley();
static int smartyFontSize = 40;
static String windowsFontID = "#1400468";
static String frameIconID = "#1102983";
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");
static boolean showTabs = true;
static int defaultWorldSize = 7, maxWorldSize = 8;
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";
String name = "Smarty0";
Set cameraDirections = new HashSet();
// see VisionMode
String visionMode = VisionMode.nextSquare;
Set wheels = new HashSet();
// for saving
String wheelsFlag(String flag) {
return wheels.contains(flag) ? "1" : "0";
}
}
static class State extends Concept {
static final String _fieldOrder = "fontScale worldName gridRows gridCols showLocations smartyX smartyY selection cursorDirection obstacles body";
float fontScale = 1.25f;
String worldName = "empty";
// actually these are always identical, could merge into one
int gridRows = defaultWorldSize, gridCols = defaultWorldSize;
boolean showLocations = true;
int smartyX, smartyY;
Rect selection = rect(1, 1, 1, 1);
Pt cursorDirection = pt(1, 0);
BitSet obstacles = new BitSet();
Ref body = new Ref();
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));
repaint(mainGrid);
}
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)) 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(this, "smartyX", selection.x, "smartyY", selection.y);
moveCursor();
}
}
// 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 __13 = tempSetFont(g, loadFont_cached(windowsFontID));
try {
drawTextWithTopLeftCornerAt(g, str(letter), new Pt(2, 0), Color.black);
} finally {
_close(__13);
}
}
if (state.smartyX == x && state.smartyY == y) {
AutoCloseable __14 = tempSetFontSize(g, smartyFontSize);
try {
drawCenteredText(g, smartyUnicode, 0, 0, w, h, Color.black);
} finally {
_close(__14);
}
}
}
int index() {
return y * state.gridCols + x;
}
boolean obstacle() {
return main.contains(state.obstacles, index());
}
void setObstacle(boolean b) {
setBit(state.obstacles, index(), b);
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: " + ((JCell) 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 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();
}
static void setWorldSize(int size) {
state.obstacles.clear();
state.gridCols = state.gridRows = size;
setSpinnerValue(worldSizeSpinner, size);
state.selection = rect(1, 1);
state.smartyX = state.smartyY = 0;
state.change();
makeMainGrid();
}
public static void main(final String[] args) throws Exception {
autoRestart(2.0);
setProgramDir(print("Using directory: ", mainDir()));
db();
// make at least one instance
uniq(SmartyBody.class);
state = uniq(State.class);
// default body
if (!state.body.has())
cset(state, "body", conceptWhere(SmartyBody.class));
jtattoo_mcWin();
// XXX
state.fontScale = 1.5f;
// set swingFontScale_debug;
swingFontScale(state.fontScale);
loadLibrary(windowsFontID);
defaultFrameIcon(frameIconID);
mainFrame = showFrame("Smarty");
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();";
}
}, "---", "Exit", runnableThread(new Runnable() {
public void run() {
try {
killVM();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "killVM();";
}
}));
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, "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();";
}
}, "---", "Exit", runnableThread(new Runnable() {
public void run() {
try {
killVM();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "killVM();";
}
}));
addMenu(mainFrame, "View", miShowLocations = jCheckBoxMenuItem("Locations (Ctrl+L)", state.showLocations, b -> {
cset(state, "showLocations", b);
repaint(mainGrid);
}));
registerCtrlKey(mainFrame, KeyEvent.VK_L, "Locations", new Runnable() {
public void run() {
try {
cset(state, "showLocations", !state.showLocations);
setChecked(miShowLocations, state.showLocations);
repaint(mainGrid);
} 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)";
}
});
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)
setWorldSize(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("Sensors Values are", jTextArea()), withTitle("Devices Values are", jTextArea())));
JComponent controlArea = northCenterAndSouthWithMargin(spacing, fontSizePlus(2, setForeground(Color.blue, jlabel("Design the World - Read the Help F1"))), middleArea, jCenteredSection("Run Smarty", jflow(jbutton("Go / Continue"), jButton("See History", new Runnable() {
public void run() {
try {
showHistory();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showHistory();";
}
}), jbutton("Reset"), jbutton("See Memory", new Runnable() {
public void run() {
try {
showMemory();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "showMemory();";
}
}), 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), jhgridWithSpacing(spacing, jlabel("VisionD:"), jlabel("Wheels:"))), controlArea);
if (showTabs) {
scpVisionConfig = singleComponentPanel();
scpWheelsConfig = singleComponentPanel();
updateTabs();
setFrameContents(mainFrame, jtabs("Smarty", mainPanel, "Vision", scpVisionConfig, "Wheels", scpWheelsConfig));
} else
setFrameContents(mainFrame, mainPanel);
centerPackFrame(mainFrame);
if (showHelpOnStart)
showHelp();
// hideConsole();
}
static void updateTabs() {
scpVisionConfig.setComponent(visionConfigPanel(state.body.get()));
scpWheelsConfig.setComponent(wheelsConfigPanel(state.body.get()));
scpCurrentSmarty.setComponent(disableTextField(jLiveValueTextField(conceptFieldLiveValue("name", state.body.get()))));
}
static void showHelp() {
String text = loadSnippet("#1031105");
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 = typeWriterFont(12), helpFont = sansSerifFont(13);
if (historyFrame == null)
historyFrame = getFrame(showCenterFrame(scalePt(600, 350, swingFontScale()), "Stimulus/Response, Percept/Action History", withMargin(centerAndSouthWithMargin(spacing, jvsplit(0.5, 100, jTextArea(), westAndCenterWithMargin(spacing, setFont(ttFont, topAlignLabel(jMultiLineLabel(linesLL("Step #", "Percept", "Binon #", "", "Expect", "Binon #", "", "Action", "Binon #", "", "Action", "Binon #", "")))), setFont(ttFont, jTextArea()))), 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);
}
// run in Swing thread
static void showMemory() {
Font ttFont = typeWriterFont(12), helpFont = sansSerifFont(13);
if (memoryFrame == null)
memoryFrame = getFrame(showCenterFrame(scalePt(600, 350, swingFontScale()), "Smarty's Memory", jvsplit(0.5, 100, centerAndEastWithMargins(northAndCenterWithMargin(setFont(ttFont, jLabel("bla bla bla")), setFont(ttFont, jTextArea())), 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();";
}
}))), jTextArea())));
else
frameToFront(memoryFrame);
}
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);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "if (isChecked(rb)) cset(body, +visionMode);";
}
});
return rb;
}
static JComponent bodyNamePanel(SmartyBody body) {
return westAndCenter(jMinWidth(swingScale(250), withLabel("Body name:", jLiveValueTextField_bothWays(conceptFieldLiveValue("name", body)))), jpanel());
}
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.change();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "addOrRemove(body.cameraDirections, direction, isChecked(cb)); body.change();";
}
});
return cb;
}))))), jCenteredSection("Vision mode", jvstackWithSpacing(spacing, visionModeRadioButton(body, buttonGroup, VisionMode.nextSquare, "Looking at the next square (symbolic values = letter in square)"), 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.distanceToWall, "Distance to wall (magnitude values = number of squares)"), 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.wallOrNot, replaceSymbols("Wall or not (symbolic values = $wallSymbol for a wall and $noWallSymbol for no wall)")), withLeftMargin(spacing * 2, jMultiLineLabel(unindentMLS("\r\n Looking at the next square will either see a wall or an empty square\r\n ")))))));
}
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.change();
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "addOrRemove(body.wheels, symbol, isChecked(cb)); body.change();";
}
});
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(jMultiLineLabel(unindentMLS("\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 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 "))))), westAndCenterWithMargin(spacing, jCenteredSection("Turning", withLeftMargin(spacing, vstackWithSpacing(wheelsConfigCheckBox(body, "TurnRight", "Turn to the right = Rotate clockwise 90 degrees = X"), wheelsConfigCheckBox(body, "TurnLeft", "Turn to the left = Rotate anti-clockwise 90 degrees = X"), wheelsConfigCheckBox(body, "TurnAround", "Turn around = Rotate 180 degrees = X")))), jCenteredSection("Help", withLeftMargin(jMultiLineLabel(unindentMLS("\r\n Turning will stay on the same square. If Smarty is able to turn then it will appear as < , > , ^ or v to indicate the direction it is facing.\r\n "))))), 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 void saveWorld(File f) {
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() ? "#" : " ");
}
saveTextFile(f, lines(lines));
infoBox("World saved: " + fileName(f));
cset(state, "worldName", fileNameWithoutExtension(f));
}
static void loadWorld(File f) {
try {
List lines = linesFromFile_list(f);
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"))
cset(state, "smartyX", x, "smartyY", y);
}
rearrangeLetters();
repaint(mainGrid);
cset(state, "worldName", fileNameWithoutExtension(f));
infoBox("World loaded: " + fileName(f));
} catch (Throwable __e) {
messageBox(__e);
}
}
static void saveWorldDialog() {
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());
}
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "JFileChooser fileChooser = new(mainDir());\r\n fileChooser.setFileFilter(new F...";
}
});
}
static void loadWorldDialog() {
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() {
setWorldSize(defaultWorldSize);
cset(state, "worldName", "empty");
}
static File mainDir() {
return mkdirs(userDir("Adaptron/Smarty"));
}
static void saveBody(File f) {
String[] Body = new String[22];
SmartyBody b = state.body.get();
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";
saveTextFile(f, lines(dropFirst(Body)));
}
static void newBody() {
cdelete(state.body.get());
cset(state, "body", cnew(SmartyBody.class));
updateTabs();
}
static void loadBody(File f) {
try {
List lines = linesFromFile_list(f);
String[] Body = asStringArray(itemPlusList("", lines));
newBody();
var b = state.body.get();
// TODO: remaining values
cset(state.body, "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;
b.change();
updateTabs();
infoBox("Body loaded: " + fileName(f));
} catch (Throwable __e) {
messageBox(__e);
}
}
static void saveBodyDialog() {
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());
saveBody(f);
infoBox("Body saved as " + f.getName());
}
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "new JFileChooser fileChooser;\r\n fileChooser.setSelectedFile(newFile(mainDir(...";
}
});
}
static void loadBodyDialog() {
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 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 String replaceOneCharInString(String a, int idx, String b) {
return spliceString(a, idx, idx + 1, b);
}
static String replaceOneCharInString(String a, int idx, char b) {
return replaceOneCharInString(a, idx, str(b));
}
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 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 basicUnicodeSmiley() {
return codePointToString(0x1F600);
}
static String unindent_mls(String s) {
return autoUnindent_mls(s);
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null)
for (A x : a) l.add(x);
return l;
}
static Rect rect(int x, int y, int w, int h) {
return new Rect(x, y, w, h);
}
static Rect rect(Pt p, int w, int h) {
return new Rect(p.x, p.y, w, h);
}
static Rect rect(int w, int h) {
return new Rect(0, 0, w, h);
}
static Pt pt(int x, int y) {
return new Pt(x, y);
}
static Pt pt(int x) {
return new Pt(x, x);
}
static boolean cset_trueIfChanged(Concept c, Object... values) {
try {
return cset(c, values) != 0;
} catch (Exception __e) {
throw rethrow(__e);
}
}
static A repaint(A c) {
if (c != null)
c.repaint();
return c;
}
static List pointsInRect(int w, int h) {
return allPointsInRect(w, h);
}
static List pointsInRect(Rect r) {
return allPointsInRect(r);
}
// better modulo that gives positive numbers always
static int mod(int n, int m) {
return (n % m + m) % m;
}
static long mod(long n, long m) {
return (n % m + m) % m;
}
static BigInteger mod(BigInteger n, int m) {
return n.mod(bigint(m));
}
static double mod(double n, double m) {
return (n % m + m) % m;
}
// returns number of changes
static int cset(Concept c, Object... values) {
try {
if (c == null)
return 0;
warnIfOddCount(values = expandParams(c.getClass(), values));
int changes = 0;
for (int i = 0; i + 1 < l(values); i += 2) if (_csetField(c, (String) values[i], values[i + 1]))
++changes;
return changes;
} catch (Exception __e) {
throw rethrow(__e);
}
}
static int cset(Iterable extends Concept> l, Object... values) {
int changes = 0;
for (Concept c : unnull(l)) changes += cset(c, values);
return changes;
}
static int cset(Concept.Ref c, Object... values) {
return cset(getVar(c), values);
}
static int getWidth(Component c) {
return c == null ? 0 : (int) swingCall(c, "getWidth");
}
static int getHeight(Component c) {
return c == null ? 0 : (int) swingCall(c, "getHeight");
}
static void fillRect(BufferedImage image, int x, int y, int w, int h, Color color) {
Graphics2D g = imageGraphics(image);
fillRect(g, x, y, w, h, color);
g.dispose();
}
static void fillRect(Graphics g, int x, int y, int w, int h, Color color) {
g.setColor(color);
g.fillRect(x, y, w, h);
}
// draw on currentImage()
static void fillRect(int x, int y, int w, int h, Color color) {
fillRect(currentImage(), x, y, w, h, color);
}
static void fillRect(Rect r, Color color) {
fillRect(r.x, r.y, r.w, r.h, color);
}
static void fillRect(BufferedImage image, Rect r, Color c) {
if (r != null)
fillRect(image, r.x, r.y, r.w, r.h, c);
}
static void fillRect(Graphics g, Rect r, Color c) {
if (r != null)
fillRect(g, r.x, r.y, r.w, r.h, c);
}
static AutoCloseable tempSetFont(Graphics g, Font font) {
Font oldFont = g.getFont();
g.setFont(font);
return new AutoCloseable() {
public String toString() {
return "g.setFont(oldFont);";
}
public void close() throws Exception {
g.setFont(oldFont);
}
};
}
static Map loadFont_cached_cache = new HashMap();
static synchronized Font loadFont_cached(String snippetID) {
try {
snippetID = formatSnippetID(snippetID);
Font f = loadFont_cached_cache.get(snippetID);
if (f == null)
loadFont_cached_cache.put(snippetID, f = loadFont(snippetID, 12f));
return f;
} catch (Exception __e) {
throw rethrow(__e);
}
}
static synchronized Font loadFont_cached(String snippetID, float size) {
try {
return loadFont_cached(snippetID).deriveFont(size);
} catch (Exception __e) {
throw rethrow(__e);
}
}
static void drawTextWithTopLeftCornerAt(Graphics2D g, String text, Pt p, Color color) {
g.setColor(color);
FontMetrics fm = g.getFontMetrics();
int h = fm.getHeight();
g.drawString(text, p.x, p.y + h);
}
static void _close(AutoCloseable c) {
if (c != null)
try {
c.close();
} catch (Throwable e) {
// Some classes stupidly throw an exception on double-closing
if (c instanceof javax.imageio.stream.ImageOutputStream)
return;
else
throw rethrow(e);
}
}
static AutoCloseable tempSetFontSize(Graphics g, float size) {
Font font = g.getFont();
g.setFont(font.deriveFont(size));
return new AutoCloseable() {
public String toString() {
return "g.setFont(font);";
}
public void close() throws Exception {
g.setFont(font);
}
};
}
static void drawCenteredText(Graphics2D g, String text, int x, int y, int w, int h, Color color) {
g.setColor(color);
FontMetrics fm = g.getFontMetrics();
Pt p = centerTextInRect(fm, text, rect(x, y, w, h));
g.drawString(text, p.x, p.y);
}
static boolean contains(Collection c, Object o) {
return c != null && c.contains(o);
}
static boolean contains(Object[] x, Object o) {
if (x != null)
for (Object a : x) if (eq(a, o))
return true;
return false;
}
static boolean contains(String s, char c) {
return s != null && s.indexOf(c) >= 0;
}
static boolean contains(String s, String b) {
return s != null && s.indexOf(b) >= 0;
}
static boolean contains(BitSet bs, int i) {
return bs != null && bs.get(i);
}
static boolean contains(Producer p, A a) {
if (p != null && a != null)
while (true) {
A x = p.next();
if (x == null)
break;
if (eq(x, a))
return true;
}
return false;
}
static void setBit(BitSet b, int bit) {
{
if (b != null)
b.set(bit);
}
}
static void setBit(BitSet b, int bit, boolean value) {
{
if (b != null)
b.set(bit, value);
}
}
static void addMouseListener(final JComponent c, final MouseListener l) {
if (c != null) {
swing(new Runnable() {
public void run() {
try {
c.addMouseListener(l);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "c.addMouseListener(l);";
}
});
}
}
static void requestFocus(final JComponent c) {
focus(c);
}
static boolean isLeftButton(MouseEvent e) {
return e.getButton() == MouseEvent.BUTTON1;
}
static void addMouseMotionListener(final JComponent c, final MouseMotionListener l) {
if (c != null) {
swing(new Runnable() {
public void run() {
try {
c.addMouseMotionListener(l);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "c.addMouseMotionListener(l);";
}
});
}
}
static A _print(String s, A a) {
return print(s, a);
}
static A _print(A a) {
return print(a);
}
static void _print() {
print();
}
static Component componentAtScreenLocationInWindow(Window window, int x, int y) {
if (window == null)
return null;
return swing(new F0() {
public Component get() {
try {
Point p = new Point(x, y);
SwingUtilities.convertPointFromScreen(p, window);
return SwingUtilities.getDeepestComponentAt(window, p.x, p.y);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "Point p = new(x, y);\r\n SwingUtilities.convertPointFromScreen(p, window);\r\n...";
}
});
}
static Component componentAtScreenLocationInWindow(Window window, MouseEvent e) {
Point p = e.getLocationOnScreen();
return componentAtScreenLocationInWindow(window, p.x, p.y);
}
static Rect rectFromPointsInclusiveSorted(int x1, int y1, int x2, int y2) {
return rectFromPoints(min(x1, x2), min(y1, y2), max(x1, x2) + 1, max(y1, y2) + 1);
}
static List map(Iterable l, Object f) {
return map(f, l);
}
static List map(Object f, Iterable l) {
List x = emptyList(l);
if (l != null)
for (Object o : l) x.add(callF(f, o));
return x;
}
static List map(Iterable l, F1 f) {
return map(f, l);
}
static List map(F1 f, Iterable l) {
List x = emptyList(l);
if (l != null)
for (A o : l) x.add(callF(f, o));
return x;
}
static List map(IF1 f, Iterable l) {
return map(l, f);
}
static List map(Iterable l, IF1 f) {
List x = emptyList(l);
if (l != null)
for (A o : l) x.add(f.get(o));
return x;
}
static List map(IF1 f, A[] l) {
return map(l, f);
}
static List map(A[] l, IF1 f) {
List x = emptyList(l);
if (l != null)
for (A o : l) x.add(f.get(o));
return x;
}
static List map(Object f, Object[] l) {
return map(f, asList(l));
}
static List map(Object[] l, Object f) {
return map(f, l);
}
static List map(Object f, Map map) {
return map(map, f);
}
// map: func(key, value) -> list element
static List map(Map map, Object f) {
List x = new ArrayList();
if (map != null)
for (Object _e : map.entrySet()) {
Map.Entry e = (Map.Entry) _e;
x.add(callF(f, e.getKey(), e.getValue()));
}
return x;
}
static List map(Map map, IF2 f) {
return map(map, (Object) f);
}
static List iotaZeroList(int n) {
return intRangeList(0, n);
}
static A setFocusable(A c) {
return setFocusable(c, true);
}
static A setFocusable(A c, boolean b) {
if (c != null) {
swing(new Runnable() {
public void run() {
try {
c.setFocusable(b);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "c.setFocusable(b);";
}
});
}
return c;
}
static A setFocusable(boolean b, A c) {
return setFocusable(c, b);
}
static A setBackground(final Color color, final A a) {
if (a != null) {
swing(new Runnable() {
public void run() {
try {
a.setBackground(color);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "a.setBackground(color);";
}
});
}
return a;
}
static A setBackground(A a, Color color) {
return setBackground(color, a);
}
// TODO: all the fringe cases (?)
static JPanel hvgrid(List> components) {
if (empty(components))
return new JPanel();
int h = l(components), w = l(first(components));
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(h, w));
for (List row : components) smartAdd(panel, row);
return panel;
}
static JPanel hvgrid(List> components, int gap) {
JPanel panel = hvgrid(components);
GridLayout g = (GridLayout) (panel.getLayout());
g.setHgap(gap);
g.setVgap(gap);
return panel;
}
static void setSpinnerValue(final JSpinner s, final int value) {
if (s != null) {
swing(new Runnable() {
public void run() {
try {
s.setValue(value);
} catch (Exception __e) {
throw rethrow(__e);
}
}
public String toString() {
return "s.setValue(value);";
}
});
}
}
static double autoRestart_interval = 10;
static boolean autoRestart_on, autoRestart_debug, autoRestart_simulate;
static java.util.Timer autoRestart_timer;
static void autoRestart(double interval) {
autoRestart_interval = interval;
autoRestart();
}
static void autoRestart() {
if (!isMain() || autoRestart_on)
return;
autoRestart_on = true;
autoRestart_schedule();
preloadProgramTitle();
}
static void autoRestart_off() {
if (!autoRestart_on)
return;
stopTimer(autoRestart_timer);
autoRestart_timer = null;
}
static void autoRestart_schedule() {
autoRestart_timer = doLater_daemon(toMS(autoRestart_interval), "autoRestart_check");
}
static void autoRestart_check() {
try {
String newMD5;
try {
newMD5 = serverAutoRestartMD5(programID());
} catch (Throwable e) {
return;
}
if (!isMD5(newMD5)) {
if (autoRestart_debug)
print("autoRestart: no server transpilation");
return;
}
if (autoRestart_localMD5 == null)
autoRestart_localMD5 = md5(loadCachedTranspilation(programID()));
String localMD5 = autoRestart_localMD5();
if (neq(localMD5, newMD5)) {
if (autoRestart_simulate)
print("Would upgrade now. " + localMD5 + " -> " + newMD5);
else {
infoBox("Upgrading " + programTitle());
restartWithDelay(500);
sleep();
}
}
} finally {
if (autoRestart_debug)
print("autoRestart: Done");
autoRestart_schedule();
}
}
static void setProgramDir(File dir) {
programDir_mine = dir;
}
// 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