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.*; // AI begins here class main { 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 { int IntensityRange; String[] Sense = new String[10+1]; boolean Processing50 = false; int MaxBodies; transient TheWorld World; Bodies bodies = new Bodies(); static class TheWorld { public String LookUnder() { return ""; } public void MoveWest() { } public void MoveSouth() { } public void MoveEast() { } public void MoveNorth() { } public void PointUnder() { } public void PointNorth() { } public void PointSouth() { } public void PointWest() { } public void PointEast() { } public void DisplayStimuliAndResponse(int[][][] sensorValues, char resp) { } public int RangeSouth() { return 0; } public int RangeNorth() { return 0; } public int RangeEast() { return 0; } public int RangeWest() { return 0; } public String LookSouth() { return ""; } public String LookNorth() { return ""; } public String LookEast() { return ""; } public String LookWest() { return ""; } public void Update_View() {} public void setBinonDisplayObjList(String text) {} public void setBinonDisplayChngResults(String text) {} public void appendBinonDisplayChngResults(String text) {} } // end of TheWorld String VB_Name = "Adaptron"; // Originally was a TEST VERSION WHICH PRODUCES RANDOM INPUT AND //CHECKS MEMORY TO SEE IF IT CONTAINS THE SAME STUFF //Obviously must have spun it off of Think 5 // Adaptron/Cognitron Algorithm - Program - Feb. 2003 test // (C) Copyright 2007, Adaptron Inc. // //THINK3 IS NOT HANDLING CONSCIOUS HABITS PROPERLY //THINK4 IS EXPERIMENT IN EXPECTATIONS BEING SAVED //THINK5 DOES A PROPER JOB OF HANDLING R-HABITS //11 July 2002 - attempting to get the 2 bugs out of pattern matching //13th July 2002 - put back the stimulus matching mem location use for // habit continuation checking in the right order - resulting stimulus // first then is it an expected trigger. //pattern4 - July 28, format display better //pattern5 - July 29 week - trace display improvements -got out bug in // habit collapsing //pattern6 - Aug 3 - test some more //pattern7 - Aug 9 - more tests with manual input, THEN AUTOMATED AGAIN //pattern8 - Aug 13 - I did top and bottom expected stimuli in habit in // previous version - now I need to introduce expected stimuli // in the habit stack fixed up Context saving too - but I think // some context could be put in LTM for pattern matching on // context so it doesn't get too long or do pattern matching on // context while in STM. //Pattern9 - incorporate thinking changes from Think8 and turn on responses //Went back to the THINK versions and incorporated results from Pattern9 //THINK7 DOES A PROPER JOB OF HANDLING R-HABITS //THINK8 Well documented version // Fixed up some stuff and comments and made it into ACTIONS8.BAS Aug 16th 2002 //ACTIONS8 - Work on comments and then responses -Then went back to Pattern //versions and worked on Pattern0 -Active Habits that fail attract attention //and then incorporated these results into Actions8. //Actions9 - Started to investigate response habits - fixed up // NOADDSHABITS and removed NOADDHABITS. //ACTION10 - Make no distinction between doing nothing and doing something // until the last minute when go to do it. // - Refine priority of what attracts attention especially for // familiar input. //EXPLORE1 - Test it out //EXPLORE2 - Improve context saving. Use 16 bit memory locations. // - HAVING PROBLEM WITH HABIT MATCHING - CREATE NEW VERSION //EXPLORE3 - Change habit stack so current one is on top and any ADDSHABITS // are below it. Stopped it using context in habits being done. //EXPLORE4 - Removed code for context saving. //Explore5 - Visual Basic 6 Version with different windows for LTM, STM etc. // Boredom turned on for current stimulus and result // habitualized and this habit has a familiar or novel result // based on InterestLevel. Old Boredom code commented out. //Explore6 13th July 2003 Try to make feelings of novel, familiar etc. // into a new stimulus type which result in information about // success or failure. // 12th Aug 2003 Decided not to do this. Instead am // going to add R-Habits. Decided R-Habits already taken care // of. Added continuous stimuli from both senses. Investigate // looping behaviour and subconscious habit execution. Haven't // done looping but it seems pretty stable. //Explore7 11th Sept 2003 Now work on subconscious habit execution. // Add loop execution in subconscious habits // 24th Sept Allow multiple stimuli on S-List - 1 external & // 1 internal stimulus. Then fix bugs / features //Explore8 1st Oct 2003 Now work on R-habits and their execution. //Explore9 6th Nov 2003 Major change required in how memory stored and // used - less emphasis on efficiency and episodic accuracy. // Added multiple S-habit recognition and context of S-habit // Added conscious looping of permanent S-habits //Happy1 25th Nov 2003 Add in pain and pleasure. 11th Dec Added // expectation of Novel as Interesting - exploration is better. //Happy2 17th Dec 2003 First attempt at adding thinking // 7th Jan 2004 small changes //Happy3 10th Jan 2004 turn off separate Trigger and Result stimuli, // add control flags for it and DoingReflex. //Happy4 13th Jan,Seperate permanence property from feeling for stimuli // Add Response Habits containing Response-Stimulus-Response // Get looping (repeating same stimulus) working properly //Happy5 20th Jan, getting permanent working, remove stimulus roles //Happy6 21st Jan, handle dynamic environments //Happy7 23rd Jan, Try handling S-Habits as R-Habits-no go. //Happy8 27th Jan, Try to get R-habits as R-S-R working. Feb 12th. Add // subconscious processes. //Happy9 23rd Feb, Novel stimulus becomes interesting, then familiar // Enhance thinking, strategies for handling Interesting //Works1 6th Mar, 2004, Attend to stimuli //Works2 30th March, Expectation processing //Works3 31st March, Stimulus context in LTM for S-Habits too. //Works4 8th Apr, Recognize loops in R-Habits, Good/Bad testing //Works5 15th Apr, turn on Kinesthetics, do subconscious habits //Works6 work on repetition / loops //Works7 18th July 2004, new learning strategy, Test Cases //Works8 29th July, Good and Bad processing //Works9 7th Sept, Generalization & Discrimination - 2 or more senses // and subconscious habit processing //Learn1 18th Sept, Conscious versus subconscious behaviour, added // levels and context at end of LTM //Learn2 3rd Nov, Kinesthetic stimuli, loops, action habits //Learn3 23rd Nov, Rename things, subconscious A-Habits, A-sequences //Learn4 6th Dec, Chained A-Habits, Concentration, A-Sequences //Learn5 6th Jan, 2005, A&B sequence, thinking refined, kinesthtics, // order of For's, Separate world //Learn6 World front-end, ABC repeating pattern & permanent S-Habits //Learn7 Body info, still working on S-Habits, R-Habits, separate body //Learn8 11 May 05, separate body & Test Cases, R-Habits, P-Stimuli, // Difference in R-Habits //Learn9 21 June 05, 31st Dec 05, removed linked habits, novelty/familarity // stored as feeling, work on 2nd sense and R-Habits //Habit1 3rd March 06, New attention algorithm, only collapse permanent // triggers of S-Habits, practice non-permanent S-Habits //Habit2 March - Interestlevel based on A & S-Habit feelings //Habit3 March - Good & Bad, Reward & Punishment, Feelings //Habit4 Jan 2007 reworking interest levels //Habit5 29th Jan 07, S-habits collapse when both stimuli are permanent // A-habits interest propagate back to trigger, S-Habits interest // propagates up the heirarchy. //Habit6 16th Feb 07, Rearrange attention algorithm //Habit7 14th March 07, Add graduated stimuli //Habit8 25th March 07, New attention algorithm //Habit9 3rd April 07, Sort out permanent stimuli, attention algorithm //Cogni1 18th April 07, Work on thinking part, replace feature with sensor // Recog1, Recog2 Recognition of objects from graduated senses. // Add discrete Sensor Array, discrete and graduated sensors //Cogni2 New interest derivation for experiences, new expected interest //Cogni3 27th July 07, Each Habit has its own expected interest //In here I worked on lines //Cogni5 Sept 07, Reworking multiple sensors with graduated values //Cogni6 Oct 12, 07, New S-Habit matching and find difference, multi-sensors //Cogni7 Oct 28, 07, Multi-sensors //Cogni8 Nov 16, 07, Use recency to solve which S-Habit to attend to. Change // action selection strategy, use FindInstead, not FindDifference //Cogni9 Nov 25, 07, Bucket stimuli readings, Change as a stimulus //Grad1 Dec 14, 07, Graduated sensors, S-Habits use LTM pointers //Grad2 Feb 4, 2008, sequences of graduated stimuli - C-Habits, generalization //Grad3 Feb 14, 2008, Change as stimulus, new S-Habit structure //Grad4 Feb 26, 2008, new S-Habit structure //Grad5 Mar 9, 2008, new S-Habit structure //Grad6 April 2008, Remove Change as a stimulus - objects represent the changes experienced //In here I worked on lines and developed course 447 //Grad7 Jan 2009, Subconscious action habits, Interest levels //Grad8 Feb 2009, new S-Habit structure changes //Grad9 Mar 20, 2009, Overlapping parts of S-habits, add line recognition from Sense1 //Ideas1 April 18, 2009, Add change objects, get thinking working and upto testcase #25 //Ideas2 May 19, 2009, Use tree of sense stimuli and P-habits - not on S-List //Ideas3 June 17, 2009, Finish conversion of S-List, Conscious Habit rework, attention alg. //Ideas4 July 8, P-Habits //Ideas5 July 10, Remove context processing, ignore repeating S-Habits, //Ideas6 Aug 2, Incorporate new line recognition, Where and Order processing //Ideas7 Sept 1st, Partial trigger matching - generalization //Ideas8 Sept 15th, Graduated readings, 8th Dec new recognition routines, Change Reading Object //Ideas9 Dec 15th, Separation object //Change1 Dec 31st, Save Change objects in LTM, Add STM for sequences //Change2 Jan 10th, 2010 create SepRdgObj, remove LTM Separs(), move STM process //Change3 Feb 2nd, STM processing, new line recognition, sequence recognition //Change4 May 2nd, New LTM episodic memory representation, new STM //Change5 May 26th, Sequence and Action LTM separated //Change6 Jun 13th, new Where obj, STM per Sense & Sensor if independent //Change7 Jun 23rd, Interest on sequences in STM, T-List //Change8 Jul 4th, P-Habits in STM, Body and World changes //Change9 Jul 20th, A_Sequences implemented, Fix STM S-habit recognition / distraction //Active1 Jul 31st, Boredom and sub-conscious A-Habits //Active2 Aug 12th, Conscious STM and/or A-Habits //Active3 Sept 21st, New Sequence recognition, Conscious STM //Active4 Oct 7th, Action Habits(practicing & doing), remove partial sequential match, // Convert interest into a property of all binons //Active5 Nov 4th, New binon structure, thinking //Active6 Dec 7th, Another new binon structure, fix partial match, remove reset interest //Active7 Dec 17th, Separate Change and Interest, reduce interest upon repetition, no concentration //Active8 Jan 22nd, 2011 remove permanent, remove current habit, separate S-habit and A-Habits //Active9 Feb 12th, New binon structure, P-habits before Sequences, better attention //Expect1 Mar 6th, Expect Interesting, new A-Habit structure, remove dependence concept //Expect2 Mar 23rd, Changed DoIt structure, Experiences in STM, Conscious Seq's in STM //Expect3 Apr 9th, New Acton structure, sequential trigger and goal recognition, removed // Novel and Fresh concepts //Expect4 May 3rd, Add device stimuli, Unexpected, New Acton structure //Expect5 Aug 2nd, Action habits, STM changes //Expect6 Sept 4th, STM just recognizes (no expectations), remove orient actons, directed // attention on expected goal //Expect7 Sept 20th,Added UnInteresting //Expect8 Oct 4th, New acton structure //Expect9 Oct 16th, P-Habits, kinesthetic sense fixed, formation of combo by A-Habit? //Practic1 Nov 7th, Sequences and Action Habits //Practic2 Nov 15th, STM processing and Permanent //Practic3 Dec 12th, Before and after conscious STMs, S-Level 1 stimuli familiar //Practic4 Jan 10th, STMs do not create A-Habits, Practice mode - redo-interest //Practic5 Jan 31st, Practice and Goal Actons, STM processing conscious sequences //Practic6 Feb 15th, P-Habit processing, Directed Attention, sequences of permanent stimuli //Practic7 Mar 14th, brought in new pattern recognition //Practic8 Apr 7th, new novel/familiar combinations and STM processing, P-Habits working //Practic9 Apr 24th, generalization for 2 senses //General1 May 23rd, Incorporate new Object Recognition (twice) //General2 July 1st, Practice and Thinking, Redo versus goal interest, Random next responses //General3 July 11th, A-habits at lowest level first, Unexpected sequential interest //General4 July 23rd, Expectation inhibits familiar from attention, should binons come with // habituation of a repeat sequence built in? //General5 12th Jan 2017 - started to document it - going to insert PerceptionAction from Act2 //15th Jan 2017 'Inserted PerceptionAction() and got Inpu_KeyPress(0 and TestCases working with no babbling output. //22nd Jan 'adding motor babbling when known action habits are familiar //23rd Jan 'thinking and bodies starting to work //24th Jan 'adding body #6 with two senses - vision and motion //28th Jan 'Got Thinking Approach #1 working //29th Jan 'Make Binon type one of the Binon properties //30th Jan 'Create P-Habit combinations for any number of senses = properties //2018 Aug 29th 'Clean up code before sending to Jianyong //31st Aug 'Renamed it Smarty. Continue to clean up the code //25th August 2019 // 'renaming percpts, actions etc. to conform with the perception-action hierarchy paper //DefInt A - Z; //16 bits / 2 bytes int JND; //set to 20% String Smarty; //an "S" String LeftArrow; // "<" String RightArrow; // ">" String UpArrow; // "^" String DownArrow; // "v" String FourWay; // "+" String Smarty0; // "Smarty0" The initial / default Body name String[] BodySetting = new String[22]; //Contains the current body being used //Bodysetting$(0) contains the number of settings in use String BodyConfig; //The values in the configure forms when go to Design or Select //For determining if a change has been made. String[] BodyValue; //Contain the values read and written to the .BDY file //The values on the body configuration forms int BodyPointing; //direction body is pointing, 0=East, 1=South, 2=West, 3=North //direction body is pointing, 0=East, 1=South, 2=West, 3=North transient final int North = 3; transient final int East = 0; transient final int South = 1; transient final int West = 2; //direction body is pointing, 0=East, 1=South, 2=West, 3=North // -------------------------- Senses and Sensors -------------------------- int NumSenses; //The number of physical senses, Max of 10, dynamically set in SetUpSense() //Currently equals the NumProperties since each sense currently = 1 property type int MaxSenses; //Maximum number of senses = max 10 physical senses int IsSense; //1, Flag for Senses versus Devices //unused String StringSense; //Names of senses, up to 10 physical senses - assigned in SetupSense() int[][] Senses = new int[10 + 1][8 + 1]; //Properties of the different senses //1st index = Sense number //2nd index = Sense property String[] SensorStimuli = new String[10 + 1]; //A string of the possible symbolic stimuli for the sensor //---- Senses() - 2nd index values - Sense Properties - same used for Devices below int PropertyBinonType; //1, Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin int SymbolicOrMagnitude; //2, Symbolic or Magnitude indicator int LowerRangeLimit; //3, Lower limit of range of values, zero is minimum (65 = "A") int UpperRangeLimit; //4, Upper limit of range of values, 255 is maximum (90 ="Z") int LinearOrCircular; //5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360) int IntegersOrLogs; //6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs int NumberOfSensors; //7 Number of sensors in sensor array int SensorsDependentOrIndependent; //8 are sensors adjacent (dependent) or independent int Symbolic; //1, Indicates that the values from this sense are symbolic, range A -> Z int Magnitude; //2, Indicates that the values from this sense are numeric, integers, range 0 -> Limit int Linear; //1, Indicates that the values go from the lower limit to upper limit int Circular; //2, Indicates that the values rap around from the upper limit to 0 int IntegerValues; //1, Indicates that the values are integer readings int LogValues; //2, Indicates that the values are already logs - orders of magnitude int Dependent; //1, Sensors in array are beside each other (adjacent) int Independent; //2, Sensors are not associated with each other //-------------------- Values of stimuli from senses / sensors ------------------------------ int[][][] SensorValues = new int[10 + 1][2 + 1][1+1]; //Stimulus values from senses/sensors //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() int Valu; //=1, the value for the stimulus, if symbolic then value = Asc(Symbol$) int XQCnt; //=2, the count of times the value has repeated, also used below String NoName; //"_", The character used when no letter provided for the IDL value of a TextBin binon String Motion; //World.MoveDown() etc set this to indicate the direction the robot moved String NoMove; //"-" to indicate there was no motion in the Motion$ stimulus value String WheelMovement; //"-flrb..." 'will contains the possible wheel motions //WheelMovement$ = "-flrb" & TurnRght$ & TurnLft$ & TurnArnd$ ' rotate right, left and around 180 degrees String ABlock; String Wall; String EmptySquare; //---- SensorValues 3rd index values - which past stimulus it is - also used below int Fired; //=0 'stimulus put in this level upon firing before being processed int Current; //=1 'The Fired one becomes the Current one after processing //-------------------- Devices ------------------------------------------------ int NumDevices; //Number of output devices - max 4 - dynamically set in SetupDevice() int MaxDevices; //Maximum number of devices = max 4 devices String[] Device = new String[4 + 1]; //Names of device, up to 4 devices - assigned in SetupDevice() int IsDevice; //2, Flag for Devices versus Senses int[][] Devices = new int[4 + 1][6 + 1]; //Properties of the output / response devices //1st index = Device number //2nd index = Device property String[] DeviceResponses = new String[4 + 1]; //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 //-------------------- Values of responses to devices ------------------------------ int[][] DeviceValues = new int[4 + 1][2 + 1]; //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 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 transient final char NoResp = '-'; //"-", The character representing no response for a LetrBin binon //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 boolean WheelsTurn = false; //If it is false then Smarty displays as an O else it displays as ^>1 means it has more than one goal // Used for prediction reliability, may be set >1 if needs to be combined with previous int 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) int 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 int AE; //14, Action (Percept - Act) or Attention (Act - Percept) level 1 Sequential binon int NullObject; //-1, Indicates the O1 or O2 pointer is not pointing to another binon //---- 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 final int NOVEL = 3; //3 New - 1st time experienced - attention paid to it // To indicate it has been experienced for the second time final int INTERESTING = 2; //2 To indicate it has been experienced for the second time // Neutral, experienced 2 or 3 or more times final int FAMILIAR = 1; //1 Neutral, experienced 2 or 3 or more times int NoInterest; //-1 Interest not known yet int InterestLevels; //2 or 3 - number of interest levels, 2= Novel and Familiar, 3= Novel, Interesting, and Familiar //---- Sequential or Parallel property values for Binons(x, SP) int Sequential; //-1 int Parallel; //+1 //---- Action or Attention property values for Binons(x, AE) - value = 0 for Parallel Percepts int Action; //1 int Attention; //2 //---- BinonType property values for Binons(x, BType) int MaxBinonTypes; //with 2 senses and 1 device this is =6, 4 senses & 4 devices = 33 int NumBinonTypes; //= 2^N+1, number of property binons, Percept combination binon types, Action type and //the D-Habit response types - set dynamically based on SetupSense() and SetupDevice() String[][] BinonTypeName = new String[68 + 1][2 + 1]; //The names and abbreviations for the various binon types //---- BinonTypeName$() 2nd index values int BinName; //1 int 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 D-Habit binons and/or Action binons. int[][] BinonTypes = new int[68 + 1][1 + 2]; //The binon types for stimuli (Percepts 15), ActBin (1) and responses (D-Habits 15) //1st index = the type of binon (dimension = NumBinonTypes) //2nd index = binon type property //---- BinonTypes() - 1st Index values - stimulus and response binon types int ActBin; //Binon type for Actions, Expectations, percepts, and action binons = NumPercepts + 1. Dynamically set int NumProperties; //N=4, The number of stimulus property binon types - currently one property per sense final int NullType = 0; //0, Indicates the type not set, binon will be NullObject //---- BinonTypes() 2nd index values int SensOrDevNum; //1, Pointer points back to sense or device // Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator - defined above //-------------------- Percept Stimuli Perceived --------------------------------------- int[] SensedBinons = new int[1 + 10]; //the source binons for the Percepts() tree (only uses = Numsenses=NumProperties) int NumPercepts; //N=63, The number of property binons and Percept combinations of them 2^NumProperties-1 int MaxPercepts; //=63 currently = (2^6)-1 would need to be (2^10) if 10 sensors int[][][] Percepts = new int[1 + 63][1 + 2][2]; //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() int BinId; //=1, the 2nd index value for the binon ID - defined / used below //Public XQCnt '=2, the count of times the fired binon has been recognized / fired - DEFINED ABOVE int[][] PerceptSources = new int[1 + 63][1 + 3]; //pointers to the lower level Percepts that are used in forming this Percept //---- PerceptSources() 2nd index values int FirstSource; //=1, the first / left source Percept binon int SecondSource; //=2, the second / right source Percept binon int PerceptLevel; //=3, The level in the Percept tree //-------------------- Left and Right Targets --------------------------------------- //--- Linked List of Target Binons - for all binons ------------- int NumTargets; //The number of Target binon entries created so far int MaxTargets; //10000 = the max number of Target binon entries possible int[][] Targets = new int[1 + 10000][1 + 2]; //pointed to by Binons(ID, TriggerList) or by Binons(ID, GoalList) //---- Targets' 2nd index property values int NLnk; //1 = The pointer to the next Targets() entry in this linked list, // may be a NullTarget at end of linked list int TargetBinon; //2 = a left or right Target binon int NullTarget; //=0, an NLnk pointer at end of linked list //-------------------- D-Habit Response Produced --------------------------------------- //unused int[] RespondedBinons = new int[1 + 2]; //the response binons for the DHabits() tree (only uses = NumDevices=NumResponses) int NumDHabits; //N=15, The number of response binons and D-Habit combinations of them 2^NumDevices-1 //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 --------------------------------------- int TopLevel; //The highest level with any binons in it in STM int HighestPerceptLvl; //The highest STM() entry produced / fired per cycle int MaxLevels; //=25, The highest level of complexity to which the tree can grow int[][][] STM = new int[25+1][3+1][25+1]; //STM current history of Patterns - a tree with parts at level 1 //1st index is the stimulus object level //2nd index =1 for binon type, =2 for binon ID, =3 for XQCnt, =4 for TQCnt //3rd index = Fired = 0 for the just fired stimulus // = Current = 1 for the Current perceived stimuli //They can all be expecting a repeat or a changed / different value // = Last one whose position is the last STM entry that has something in it //---- STM 2nd index values - type of information in STM() //Public BinId '=1, the binon ID - DEFINED ABOVE //Public XQCnt '=2, the count of times the fired binon has been recognized / fired / repeated - Defined above int TQCnt; //=3, the count of times its trigger fired for repeat size comparison //---- 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 int MoveAmount; //Move right amount to eliminate previous pattern - set in ProcessSTMLevel() //--------------------- Conscious Binons ----------------------------------------- int PerceivedBinon; //predicting/expecting the next binon as the goal. May have 0, 1 or more associating binons. //-------------------- Long Term Memory (LTM) - Monitoring Info. ------------------------- //For Display purposes only by Adapt.DUMPLTM in Adapt.LTMem //Long term memory contains a list of the stimuli that have been paid attention to. //It stores Perceptual sequences as a pair of sequential memory locations. int[][] LTMEMORY = new int[2000+1][8+1]; //1st index is StoreAt cycle number //2nd index is what type of information is in the LTM //---- LTMEMORY() 2nd index values - type of information in LTMEMORY() int LtmPerceptTyp; //1 Percept binon type int LtmPerceptBin; //2 Percept binon int LtmESType; //3 Type of ES Binon - may be an S int LtmESActBin; //4 ES Actbin int LtmARType; //5 Type of AR Binon - may be an R int LtmARActBin; //6 AR ActBin int LtmActionTyp; //7 Action binon type int LtmActionBin; //8 Action binon int StoreAt; //LTM POSITION OF LAST STIMULUS - location in LTMEMORY() - incremented by PerceptionAction() int MaxMemory; //2000 //----------------------Input/Output History ---------------------------------------- //For display by Adapt.HISTORYDISPLAY in Adapt.IO String[][] INPUTS = new String[2000][10+1]; //INPUT history - List of sense stimuli for each sense (1 to 10) String[][] OUTPUTS = new String[2000][4+1]; //OUTPUT history - List of Responses for each device (1 to 4) //-------------------- Other Variables ------------------------------------------ double SizeBase; //1.2 for a 20% just noticeable difference double IntensityBase; //If it is 2.0 then that is a 100% just noticeable difference //-------------------- Operational Values - Adaptron -------------------- String ASpace; char SequentialSign; //Chr$(16) ">" String ParallelSign; // "+" was Chr$(186) two vertical lines was "/" boolean CreateAll = false; //True if create all combinations //False if use only familiar parts // ********* Counters, Temporary values, Flags and Pointers ****** //---------------------- Operational Values ------------------------------- int Normal; int Happy; int Unhappy; int PartMatch; //Used as ActTypes for body display //unused boolean PracticeMode; //Practicing the PracticeActon. Still performing it. //When finished in PracticeMode then we switch to GoalMode. //unused Public PracticeActon; //The acton that is being practiced //static Public ActiveActon; //The highest level active acton being done subconsciously //If set then this is being done subconsciously (not being practiced) //static Public DoingAct1; //The Act is being done even though it is not being practiced //This does not include the do Relax act //unused Public GoalExpected; //Goal expected by Action started - to measure success or failure //= 0 if no expectation because doing reflexive response //unused Public GoalSoFar; //Keeps track of the part of the expected goal obtained so far //unused boolean GoalMode; //Concentrating on the goal of the action being practiced. //We have finished the acton execution. //If set it will cause directed attention to the GoalExpected //unused Public ExpectedGoal; //Goal expected for thinking about //unused Public TraceGoal; //Used for Trace - The goal we are either trying to achieve or avoid //unused Public MATCHUSE; //Trigger match Action in Actons() that is interesting to do //unused Public ActionDesire; //Interest in the MATCHUSE entry for AttendTo //unused Public PartialMATCHUSE; //same as MATCHUSE but for partial matches //unused Public PartialActionDesire; //unused Public PartialTrigger; //set to the partial trigger object if partial trigger true //unused boolean ThoughtUsed; boolean DoingReaction = false; //set true if last response was reactive / reflex boolean DoingRepeat = false; //set true if repeating a known response as a reflexive reaction int LastAct; //Last reflexive response used from Acts list //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() int LIN; //Count of how many stimuli have been input/output in INPUTS$() and OUTPUTS$() //unused boolean FreezeSList; //When true don't do the DUMPSTIMS any more int COUNTIN; //Count of inputs for display of history String[] RecentWorld = new String[4]; //The list of recent .WLD files created - kept in RecentWldList.TXT String[] RecentBody = new String[4]; //The list of recent .BDY files created - kept in RecentBdyList.TXT int OperatingMode; //Either, Running World or just Started int Running; int Started; // ********* Counters, Temporary values, Flags and Pointers ****** //unused Public I, J, T, M, H, N, K, P, F, S, Hab; //unused Public ThoughtDesire; char vbDblQuote; // --------------- Colours -------------- int Black; int White; int LightBlue; int DarkBlue; // End of (Declarations) public void Initialize_Adaptron() { //Called only once from World form when it loads, World.Form_Load() //Initialize all values that don't change Smarty = "J"; // J = wingdings happy face "+" '"S" LeftArrow = chr(239); RightArrow = chr(240); UpArrow = chr(241); DownArrow = chr(242); FourWay = chr(170); Smarty0 = "Smarty0"; //The initial / default Body name InitBodySettingsToSmarty0(); //sets the inital values in BodySetting$() // -------------------------- Senses and Sensors -------------------------- MaxSenses = 10; //max no. of physical senses possible in Values$ arrays IsSense = 1; // Flag for Senses versus Devices //---- Senses() and Devices() - 2nd index values - Sense and device Properties PropertyBinonType = 1; // Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin SymbolicOrMagnitude = 2; // Symbolic or Magnitude indicator LowerRangeLimit = 3; // Lower limit of range of values, zero is minimum (65 = "A") UpperRangeLimit = 4; // Upper limit of range of values, 255 is maximum (90 ="Z") LinearOrCircular = 5; // Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360) IntegersOrLogs = 6; // Integer Values or Log Values, Temperatures are Integers while Decibels are Logs NumberOfSensors = 7; // Number of sensors in sensor array SensorsDependentOrIndependent = 8; // Are sensors adjacent (dependent) or independent Symbolic = 1; // Indicates that the values from this sense are symbolic, range A -> Z Magnitude = 2; // Indicates that the values from this sense are numeric, integers, range 0 -> Limit Linear = 1; // Indicates that the values go from the lower limit to upper limit Circular = 2; // Indicates that the values rap around from the upper limit to 0 IntegerValues = 1; // Indicates that the values are integer readings LogValues = 2; // Indicates that the values are already logs - orders of magnitude Dependent = 1; // Sensors in array are beside each other (adjacent) Independent = 2; // Sensors are not associated with each other //-------------------- Values of stimuli from senses / sensors ------------------------------ //---- SensorValues 2nd index values - type of information in SensorValues() Valu = 1; // the value for the stimulus, if symbolic then value = Asc(Symbol$) XQCnt = 2; // the count of times the value has repeated, also used below NoName = "_"; // The character used when no letter provided for the IDL value of a TextBin binon ABlock = "#"; //a # for internal use to indicate a block at the location Wall = chr(219); //a block, Chr$(219) is a black square in Terminal font EmptySquare = chr(177); //Chr$(177) is a fuzzy square in Terminal font //---- SensorValues 3rd index values - which past stimulus it is - also used below Fired = 0; //stimulus put in this level upon firing before being processed Current = 1; //The Fired one becomes the Current one after processing //-------------------- Devices ------------------------------------------------ MaxDevices = 4; //Maximum number of devices = max 4 devices IsDevice = 2; // Flag for Devices versus Senses NoMoveOrTurn = "z"; //"z" indicates Smarty does not have this move ability WheelMovement = "-flrb" + TurnRght + TurnLft + TurnArnd; // rotate right, left and around 180 degrees NoMove = WheelMovement.substring(0, 1); //"-" to indicate there was no motion in the Motion$ stimulus value //-------------------- The Stimulus Objects (Binons) ------------------------- MaxBinons = 5000; // Max number of binons per type MaxBinonTypes = 68; //with 2 senses and 1 device this is =5 //---- BinonTypeName$() 2nd index values BinName = 1; BinAbbreviation = 2; //---- BinonTypes() 2nd index values SensOrDevNum = 1; // Pointer points back to sense or device // SymbolicOrMagnitude = 2 ' Symbolic or Magnitude indicator - initialized above //-------------------- Percept Stimuli Perceived --------------------------------------- MaxPercepts = 63; // currently based on maxsenses=5 senses=number of property types //---- Percepts() 2nd index values - type of information in Percepts() BinId = 1; // the 2nd index value for the binon ID - defined / used below //XQCnt = 2 ' the count of times the fired binon has been recognized / fired - DEFINED ABOVE //---- PerceptSources() 2nd index values FirstSource = 1; // the first / left source Percept binon SecondSource = 2; // the second / right source Percept binon PerceptLevel = 3; // The level in the Percept tree //---- Binons() Properties - 2nd index values BType = 1; // The type of binon O1 = 2; // Left source binon pointer TQ = 3; // the count of times the trigger has fired O2 = 4; // Right source binon pointer GQ = 5; // the number of times the goal has fired IDL = 6; // The ratio value of the binon IntVl = 7; // Interest Value (NOVEL, INTERESTING, or Familiar) OLv = 8; // Level of object = number of lowest level parts involved SP = 9; // Sequential or Parallel property TriggerList = 10; // points to the linked list of right target binons [Targets()] TriggerCount = 11; // Count of its sequential right targets, >1 means it has more than one goal GoalList = 12; // points to the linked list of left target binons [Targets()] GoalCount = 13; // Count of its sequential left targets, >1 means can not predict its trigger AE = 14; // Action (Stimulus - Response) or Attention (Response - Stimulus) level 1 Sequential binon NullObject = -1; // Indicates the O1 or O2 pointer is not pointing to another binon NoInterest = -1; // Interest not known yet InterestLevels = 2; //2 or 3 - number of interest levels, 2= Novel and Familiar, 3= Novel, Interesting, and Familiar //---- 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 ------------- MaxTargets = 10000; // = the max number of Target binon entries possible //---- Targets' 2nd index property values NLnk = 1; // = The pointer to the next Targets() entry in this linked list, TargetBinon = 2; // = a left or right Target binon NullTarget = 0; // an NLnk pointer at end of linked list //-------------------- Stimuli Perceived STM() --------------------------------------- MaxLevels = 25; // The highest level of complexity to which the tree can grow //---- 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 TQCnt = 3; // the count of times its trigger fired for repeat size comparison //-------------------- 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; //">" ParallelSign = "+"; //Was Chr$(186), 'was "/" Normal = 0; //Used as ActTypes for body display Happy = 1; PartMatch = 2; Unhappy = 3; vbDblQuote = (char) 34; // = " Running = 2; Started = 1; OperatingMode = Started; //Just started so WorldHelp is displayed 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 (tempVar == ActBin) //Public ActBin = sequential - action = NumPercepts+1 { TheBinon = OOO; while (BinonTypeOf(TheBinon) == ActBin) //While we have an Action { ping(); LeftBinon = TheBinon; //Go down the left side to the bottom Property or Percept binon while (BinonTypeOf(LeftBinon) == ActBin) //While we have an Action { ping(); LeftBinon = Binons[LeftBinon][O1]; //Get the left source part } GetValue(LeftBinon, v); //get the property and/or Percept binon v.set(v.get() + SequentialSign); //Go to the right side and repeat going down its left side TheBinon = Binons[TheBinon][O2]; } GetValue(TheBinon, v); //get the last Property or Percept binon on the right side } //ORIGINAL LINE: Case 1 To NumProperties //Senses / property binon else if (tempVar >= 1 && tempVar <= NumProperties) //Senses / property binon { Readng = Binons[OOO][IDL]; //The binons value if (BinonTypes[BinonTypeOf(OOO)][SymbolicOrMagnitude] == Symbolic) { if (Readng < 32) { v.set(v.get() + "~"); } else { v.set(v.get() + chr(Readng)); //text } } else //Else the property is Magnitude { v.set(v.get() + vbToStr(Readng)); //a number } } //ORIGINAL LINE: Case NumProperties + 1 To NumPercepts //Percept binons else if (tempVar >= NumProperties + 1 && tempVar <= NumPercepts) //Percept binons { TheBinon = OOO; while (BinonTypeOf(TheBinon) > NumProperties) //While we have a Percept { ping(); LeftBinon = TheBinon; //Go down the left side to the bottom property binon while (BinonTypeOf(LeftBinon) > NumProperties) //While we have a Percept { ping(); LeftBinon = Binons[LeftBinon][O1]; //Get the left source part } GetValue(LeftBinon, v); //get the property binon v.set(v.get() + ParallelSign); //Go to the right side and repeat going down its left side TheBinon = Binons[TheBinon][O2]; } GetValue(TheBinon, v); //get the last Property binon on the right side } //ORIGINAL LINE: Case ActBin + 1 To NumBinonTypes //A response / device binon else if (tempVar >= ActBin + 1 && tempVar <= NumBinonTypes) //A response / device binon { Readng = Binons[OOO][IDL]; if (Readng < 32) { v.set(v.get() + "~"); } else { v.set(v.get() + chr(Readng)); //symbolic } } } //End of GetValue() public final void RememberResponse(int RespBin, int StoreAtPlace) { //Save the last response for LTM display // Public LTMEMORY&(1 To 2000, 1 To 6) -- comment stefan: not really - it's going to 8 // '1st index is StoreAt cycle number // '2nd index is what type of information is in the LTM // // '---- LTMEMORY() 2nd index values - type of information in LTMEMORY() // Public LtmPerceptTyp '1 Percept binon type // Public LtmPerceptBin '2 Percept binon // Public LtmESType '3 Type of ES Binon - may be an S // Public LtmESActBin '4 ES Actbin // Public LtmARType '5 Type of AR Binon - may be an R // Public LtmARActBin '6 AR ActBin // Public LtmActionTyp '7 Action binon type // Public LtmActionBin '8 Action binon LTMEMORY[StoreAtPlace][LtmActionTyp] = BinonTypeOf(RespBin); LTMEMORY[StoreAtPlace][LtmActionBin] = RespBin; } //End of RememberResponse() public final void RememberStimulus(int TrigObj, int StoreAtPlace) { //Save the given relationship / association in LTM for display // Public LTMEMORY&(1 To 2000, 1 To 6) // '1st index is StoreAt cycle number // '2nd index is what type of information is in the LTM // // '---- LTMEMORY() 2nd index values - type of information in LTMEMORY() // Public LtmPerceptTyp '1 Percept binon type // Public LtmPerceptBin '2 Percept binon // Public LtmESType '3 Type of ES Binon - may be an S // Public LtmESActBin '4 ES Actbin // Public LtmARType '5 Type of AR Binon - may be an R // Public LtmARActBin '6 AR ActBin // Public LtmActionTyp '7 Action binon type // Public LtmActionBin '8 Action binon LTMEMORY[StoreAtPlace][LtmPerceptTyp] = BinonTypeOf(TrigObj); LTMEMORY[StoreAtPlace][LtmPerceptBin] = TrigObj; } //End of RememberStimulus() public final void SetupSense(int SenseNum, String Sense_Name, String BinonName, String BinonAbbrev, int MagnOrSymb, int LowerLimit, int UpperLimit, String Stimuli, int LinOrCirc, int IntOrLog, int NumSensrs, int SensorDependency) { printVars_str("SetupSense","SenseNum", SenseNum, "Sense_Name", Sense_Name, "NumSensrs", NumSensrs); //If the SenseNum passed in is zero this routine returns the Sense number (SenseNum) //for the given Sense, else it modifies the given SenseNum //The range or number of sensors is NumSensrs - max 256 //IntensityRange: is the range or number of intensity values for the sensors //Stimuli$: is a string of possible stimuli for this sensor - saved in SensorStimuli$() //Sense_Name$: is the name of the sense //MagnOrSymb: = Magnitude if each sensor measures a Magnitude range of intensity // = Symbolic if each sensor provides readings that are symbolic. //LinOrCirc: = Linear // = Circular //unused String Ssr = null; int UseSense; //unused String SG = null; int Sns; var BinTypNum = new Var<>(0); String DisplayStimuli; // Public NumSenses 'The number of physical senses, Max of 8 // 'Currently equals the NumProperties since each sense currently = 1 property type // Public MaxSenses 'Maximum number of senses = max 8 physical senses // Public Sense$(1 To 8) 'Names of senses, up to 8 physical senses // // Public Senses[1 To 8][1 To 6] 'Properties of the different senses // '1st index = Sense number // '2nd index = Sense property // Public SensorStimuli$(1 To 10) 'A string of the possible symbolic stimuli for the sensor // // '---- Senses() - 2nd index values - Sense Properties // Public PropertyBinonType '1, Stimulus property binon type e.g. 1 = TextBin or 2 = ContBin // Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator // Public LowerRangeLimit '3, Lower limit of range of values, zero is minimum (65 = "A") // Public UpperRangeLimit '4, Upper limit of range of values, 255 is maximum (90 ="Z") // Public LinearOrCircular '5, Linear list or Ring/Circular of values for Magnitude sense, Distance is Linear, Compass degrees are Circular (0 to 360) // Public IntegersOrLogs '6, Integer Values or Log Values, Temperatures are Integers while Decibels are Logs // Public NumberOfSensors '7 Number of sensors in sensor array // Public SensorsDependentOrIndependent '8 are sensors adjacent (dependent) or independent // // Public Symbolic '1, Indicates that the values from this sense are symbolic, range A -> Z // Public Magnitude '2, Indicates that the values from this sense are numeric, integers, range 0 -> Limit // // Public Linear '1, Indicates that the values go from the lower limit to upper limit // Public Circular '2, Indicates that the values rap around from the upper limit to 0 // // Public IntegerValues '1, Indicates that the values are integer readings // Public LogValues '2, Indicates that the values are already logs - orders of magnitude // if (NumSenses == MaxSenses) //Can't assign another new sense number { Stop(); } //There are only so many senses in SensorValues array //currently set to 8 in Adaptron.Initialize_Adaptron() if (SenseNum == 0) //don't have a sense number yet so assign and return it { NumSenses = NumSenses + 1; //The new sense number for this sense SenseNum = NumSenses; //The returned sense number } else if (SenseNum > MaxSenses) //else it is more than allowed { Stop(); } else if (SenseNum > NumSenses + 1) //else is it higher than the next one available { Stop(); } else if (SenseNum <= NumSenses) //else use the one passed in - overriding an existing sense { } else if (SenseNum == NumSenses + 1) //else is it equal to the next one available { NumSenses = SenseNum; //which equals NumSenses + 1 } UseSense = SenseNum; if (NumSensrs > 8) //only 8 sensors allowed per sense for now - maybe only { Stop(); } //need this limit if independent sensors if (IntensityRange > 256) //only 256 values allowed for intensity { Stop(); } Sense[UseSense] = Sense_Name; Senses[UseSense][SymbolicOrMagnitude] = MagnOrSymb; Senses[UseSense][LowerRangeLimit] = LowerLimit; Senses[UseSense][UpperRangeLimit] = UpperLimit; SensorStimuli[UseSense] = Stimuli; //If not "" these take preference over the upper and lower limit if (Senses[UseSense][SymbolicOrMagnitude] == Magnitude) //Magnitude READINGS { Senses[UseSense][LinearOrCircular] = LinOrCirc; //can be circular or linear SensorStimuli[UseSense] = ""; //can not have symbolic list } else //Symbolic readings can not be circular { Senses[UseSense][LinearOrCircular] = Linear; //non circular } Senses[UseSense][IntegersOrLogs] = IntOrLog; Senses[UseSense][NumberOfSensors] = NumSensrs; Senses[UseSense][SensorsDependentOrIndependent] = SensorDependency; //SetupBinonTypes(SenseOrDeviceNum, BinNam$, BinAbb$, IsASense, BinonTypReturned) SetupBinonTypes(UseSense, BinonName, BinonAbbrev, IsSense, BinTypNum); Senses[UseSense][PropertyBinonType] = BinTypNum.get(); //Currently BinonType = Sense = property binon //and fill in sense info on world page // XXX World.SenseInfo.Text = ""; for (Sns = 1; Sns <= NumSenses; Sns++) { ping(); if (Senses[Sns][SymbolicOrMagnitude] == Magnitude) { DisplayStimuli = StringHelper.trim(String.valueOf(Senses[Sns][LowerRangeLimit]), ' ') + " to" + Senses[Sns][UpperRangeLimit]; } else //symbolic values { if (SensorStimuli[Sns].equals("")) //If no symbolic list then use upper and lower limit { 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 (var I = 1; I <= tempVar; I++) //blank out the NoMoveOrTurn$ "z" symbols { ping(); 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() { Stop("STOP"); } private static void Stop(String msg) { throw new RuntimeException(msg); } public final void SetupVision() //Called from DesignBody.UseThisBody_Click() { int VisionSense; int MS = 0; int ll = 0; // renamed because of clash with JavaX's LL 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) VisionSense = 0; //so a new sense number assigned automatically by SetupSense() // 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 (isTrue(BodySetting[12])) //radio button VisionSymbolicOrMagnitude(0) selected { MS = Symbolic; ll = 65; //"A" 1st cell location UL = 122; //"z" last possible cell location - actually if 8 x 8 then it is Chr$(129) } if (isTrue(BodySetting[13])) //radio button VisionSymbolicOrMagnitude(1) selected { MS = Magnitude; ll = 1; UL = 8; //max 8 cells in any direction } if (isTrue(BodySetting[21])) //radio button VisionSymbolicOrMagnitude(2) selected { MS = Symbolic; ll = asc(Wall); //Wall$ = Chr$(20) Terminal font UL = asc(EmptySquare); //empty square beside it } if (eq(BodySetting[7], "1")) //Looking down box is checked { //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 (eq(BodySetting[8], "1")) //Looking left box is checked { SetupSense(VisionSense, "VisionL", "VisionL", "Vl", MS, ll, UL, "", Linear, IntegerValues, 1, Independent); } VisionSense = 0; if (eq(BodySetting[9], "1")) //Looking right box is checked { SetupSense(VisionSense, "VisionR", "VisionR", "Vr", MS, ll, UL, "", Linear, IntegerValues, 1, Independent); } VisionSense = 0; if (eq(BodySetting[10], "1")) //Looking InFront box is checked { SetupSense(VisionSense, "VisionF", "VisionF", "Vf", MS, ll, UL, "", Linear, IntegerValues, 1, Independent); } VisionSense = 0; if (eq(BodySetting[11], "1")) //Looking Behind box is checked { SetupSense(VisionSense, "VisionB", "VisionB", "Vb", MS, ll, UL, "", Linear, IntegerValues, 1, Independent); } } //End of SetupVision() private int asc(String s) { return empty(s) ? 0 : s.charAt(0); } private boolean isTrue(String s) { return "True".equals(s); } public final void SetupTouch() { } //End of SetupTouch() public final void SetupWheels() { int WheelsDevice; int MS; //unused String LL = null; //unused String UL = null; StringBuilder WheelResponses; int MotionSense; // BodySetting$(14) = WheelsConfig.MoveForward // BodySetting$(15) = WheelsConfig.MoveLeft // BodySetting$(16) = WheelsConfig.MoveRight // BodySetting$(17) = WheelsConfig.MoveBackward // BodySetting$(18) = WheelsConfig.TurnRight // BodySetting$(19) = WheelsConfig.TurnLeft // BodySetting$(20) = WheelsConfig.TurnAround // BodySetting$(4) = WheelsConfig.AddAWheelSensor // Body 1 'Sense #1 looks down at square, Device #1 moves Left, Right, Up, Down // 'set up Sense #1, 1 sensor // 'SetupSense(SenseNum, Sense_Name$, BinonName$, BinonAbbrev$, MagnOrSymb, LowerLimit, UpperLimit, _ // LinOrCirc, IntOrLog, NumSensrs, SensorDependency) // Call SetupSense(InputSense, "Input", "Text", "Tx", Symbolic, 65, 113, Linear, IntegerValues, 1, Independent) // // Call SetupDevice(DevNum, "Output", "Letter", "Lt", Symbolic, 97, 100, "", Linear, IntegerValues) // // Body 2 'Looks forward at next cell, Turns left, right & moves forward // 'set up Sense #1, 1 Sensor // Call SetupSense(InputSense, "Input", "Text", "Tx", Symbolic, 65, 113, Linear, IntegerValues, 1, Independent) // Call SetupDevice(DevNum, "Output", "Letter", "Lt", Symbolic, 97, 99, "", Linear, IntegerValues) WheelsDevice = 0; //The device number assigned to the device by SetupDevice() MS = Symbolic; WheelResponses = new StringBuilder("-"); //will be filled in with move symbols "-flrb" and turn symbols, //a "z" for an invalid movement, the "-" for do nothing WheelsTurn = false; //Assume no turning capability, display Smarty as Happy face if (MS == Symbolic) { for (var I = 14; I <= 20; I++) { ping(); if (eq(BodySetting[I], "1")) //if it is checked then { switch (I) { case 14: //Forward WheelResponses.append(MoveForward); break; case 15: //Left WheelResponses.append(MoveToLeft); break; case 16: //Right WheelResponses.append(MoveToRight); break; case 17: //Backward WheelResponses.append(MoveBackward); break; case 18: //Turn right 90 degrees WheelResponses.append(TurnRght); //right angle symbol WheelsTurn = true; break; case 19: //Turn left 90 degrees WheelResponses.append(TurnLft); //left angle symbol WheelsTurn = true; break; case 20: //Turn around 180 degrees WheelResponses.append(TurnArnd); //double arrow symbol WheelsTurn = true; break; } } else { WheelResponses.append(NoMoveOrTurn); } } } WheelMovement = WheelResponses.toString(); //the same movements should be recognizable //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 void InitBodyToSmarty0(String[] Body) //Initialize the BodySetting$() or BodyValue$() to Smarty0 values { Body[0] = "21"; //Count of Body$() values Body[1] = Smarty0; Body[2] = "1"; //Vision.Value = 1 - checked Body[3] = "0"; //Touch.Value Body[4] = "0"; //WheelsConfig.AddAWheelSensor Body[5] = "1"; //Wheels.Value Body[6] = "0"; //Arms.Value Body[7] = "1"; //VisionConfig.VisionDown Body[8] = "0"; //VisionConfig.VisionLeft Body[9] = "0"; //VisionConfig.VisionRight Body[10] = "0"; //VisionConfig.VisionInFront Body[11] = "0"; //VisionConfig.VisionBehind Body[12] = "True"; //VisionConfig.VisionSymbolicOrMagnitude(0) Body[13] = "False"; //VisionConfig.VisionSymbolicOrMagnitude(1) Body[14] = "1"; //WheelsConfig.MoveForward Body[15] = "1"; //WheelsConfig.MoveLeft Body[16] = "1"; //WheelsConfig.MoveRight Body[17] = "1"; //WheelsConfig.MoveBackward Body[18] = "0"; //WheelsConfig.TurnRight Body[19] = "0"; //WheelsConfig.TurnLeft Body[20] = "0"; //WheelsConfig.TurnAround Body[21] = "False"; //VisionConfig.VisionSymbolicOrMagnitude(2) } //End of InitBodyToSmarty0() public void InitBodySettingsToSmarty0() { InitBodyToSmarty0(BodySetting); } public final void InitBodyValuesToSmarty0() { InitBodyToSmarty0(BodyValue); } public final String SymbOrMagn(int SensOrDevc, int SensOrDevcNumber) { String tempSymbOrMagn; //called from SetupSense() & SetupDevice() int SorG; if (SensOrDevc == IsSense) { SorG = Senses[SensOrDevcNumber][SymbolicOrMagnitude]; } else //Else SensOrDevc = IsDevice { SorG = Devices[SensOrDevcNumber][SymbolicOrMagnitude]; } if (SorG == Symbolic) { tempSymbOrMagn = "Symbolic"; } else { tempSymbOrMagn = "Magnitude"; } return tempSymbOrMagn; } //End of SymbOrMagn$() public final void SetupBinonTypes(int SenseOrDeviceNum, String BinNam, String BinAbb, int IsASense, Var BinonTypReturned) { //Called by SetUpSense() and SetupDevice() //After setting up a sense or device the binontypes() information must be updated correctly //SenseOrDeviceNum could be one that already exists and is being reset int BinTypNum = 0; int PerceptBinTyp; int DHabitBinTyp; int FirstPtr; int SecondPtr; int ThisPercept; int StartPercept; int EndPercept; int ThisLevel; // '---- Binons[x][BType] - stimulus and response binon types // TextBin = 1 ' = A letter (symbolic) // ContBin = 2 ' = Contrast pattern - intensity (Magnitude) // 'Parallel combinations should be put in the binons above the property type ones. // NCBin = 3 ' = TextBin & ContBin combination // ActBin = 4 ' = 2^N = NumPercepts+1, holds sequential binons. // LetrBin = 5 ' = Response binon = letters //------------------ Property and Percept combinations -------------------------- //The number of combinations at each level of complexity when combining independent senses. //# of Sensors // or Senses // Stimuli @ P-Level 1 2 3 4 5 6 7 8 Total // 1 1 1 // 2 2 1 3 // 3 3 3 1 7 // 4 4 6 4 1 15 // 5 5 10 10 5 1 31 // 6 6 15 20 15 6 1 63 // 7 7 21 35 35 21 7 1 127 // 8 8 28 56 70 56 28 8 1 255 // N 2^N - 1 // Public NumProperties 'N=2, The number of stimulus property binon types // Public NumPercepts 'N=3, The number of property binons and Percept combinations of them // Public NumBinonTypes '= 2^N+1, number of property binons, Percept combination binon types, Action type and // ' the response type // Public MaxBinonTypes 'with 2 senses and 1 device this is =5 // Public BinonTypeName$(1 To 31, 1 To 2) 'The names and abbreviations for the various binon types // '---- BinonTypeName$() 2nd index values // Public BinName '1 // Public BinAbbreviation '2 // 'The source types of property binons are 1=TextBin, 2=ContBin. There are N of these // 'and all other Percept combinations such as Name&Cont. // 'There are 2^N-1 Property plus Percept types // 'There is just the one Action type - a sequential combination of the // 'Property binons, Percept binons, response binon and/or Action binons. // 'Added responses as LetrBin binons so NumBinonTypes = 2^N + 1 // Public BinonTypes[1 To 31][1 To 4] 'The binon types for stimuli, ActBin and responses // '1st index = the type of binon (dimension = NumBinonTypes) // '2nd index = binon type property // //---- BinonTypes() 2nd index values // Public SensOrDevNum '1, Pointer points back to sense or device // Public SymbolicOrMagnitude '2, Symbolic or Magnitude indicator if (IsASense == IsSense) //If setting up a sense then { if (SenseOrDeviceNum <= NumProperties) //if it is an existing sense then resetting it { BinTypNum = SenseOrDeviceNum; } else if (SenseOrDeviceNum == NumProperties + 1) //else if it is the next new sense then { NumProperties = SenseOrDeviceNum; //N=2, The number of stimulus property binon types BinTypNum = NumProperties; NumPercepts = (2 << (NumProperties - 1)) - 1; //N=3, The number of property binons and Percept combinations of them for (PerceptBinTyp = NumProperties + 1; PerceptBinTyp <= NumPercepts; PerceptBinTyp++) { ping(); BinonTypeName[PerceptBinTyp][BinName] = "Percept"; BinonTypeName[PerceptBinTyp][BinAbbreviation] = "Pc"; } //Setup the PerceptSources() to point at the correct source entries at the level below ThisLevel = 2; //Filling in level 2 Percept information ThisPercept = NumProperties + 1; //Position of 1st Percept combination of sense/property binons StartPercept = ThisPercept; //Start of range of pairs - level-2 Percepts, level-1 Percepts=property binons for (FirstPtr = 1; FirstPtr < NumProperties; FirstPtr++) //Create all the 2nd level pair pointers { ping(); for (SecondPtr = FirstPtr + 1; SecondPtr <= NumProperties; SecondPtr++) { ping(); PerceptSources[ThisPercept][FirstSource] = FirstPtr; PerceptSources[ThisPercept][SecondSource] = SecondPtr; PerceptSources[ThisPercept][PerceptLevel] = ThisLevel; ThisPercept = ThisPercept + 1; //Next combination Percept will go in here } } EndPercept = ThisPercept - 1; //End of range of level-2 Percepts - pairs of property binons //Setup the level-3+ PerceptSources() while (EndPercept - StartPercept > 0) { ping(); ThisLevel = ThisLevel + 1; //populate next level up for (FirstPtr = StartPercept; FirstPtr < EndPercept; FirstPtr++) { ping(); for (SecondPtr = FirstPtr + 1; SecondPtr <= EndPercept; SecondPtr++) { ping(); if (PerceptSources[FirstPtr][SecondSource] == PerceptSources[SecondPtr][FirstSource]) //if share a common sub Percept { PerceptSources[ThisPercept][FirstSource] = FirstPtr; PerceptSources[ThisPercept][SecondSource] = SecondPtr; PerceptSources[ThisPercept][PerceptLevel] = ThisLevel; ThisPercept = ThisPercept + 1; //Next combination Percept will go in here } } } StartPercept = EndPercept + 1; //Start next range after end of previous range EndPercept = ThisPercept - 1; //End of range of this level Percepts } ActBin = NumPercepts + 1; //ActBin holds action and expectation binons = 2^N = NumPercepts + 1 BinonTypeName[ActBin][BinName] = "Action"; BinonTypeName[ActBin][BinAbbreviation] = "Ac"; NumBinonTypes = ActBin; //The number of types so far = 2^N } else { Stop(); //no other value allowed } } else //Else setting up a device { if (SenseOrDeviceNum + ActBin <= NumBinonTypes) //If it is an existing device then restting it { BinTypNum = SenseOrDeviceNum; } else if (SenseOrDeviceNum + ActBin == NumBinonTypes + 1) //else if it is the next new device number then { NumBinonTypes = NumBinonTypes + 1; //= 2^N+x, number of property binons, Percept combination binon types, BinTypNum = NumBinonTypes; NumDHabits = (2 << (SenseOrDeviceNum - 1)) - 1; //N=3, The number of device response binons and D-Habit combinations of them //VB TO JAVA CONVERTER NOTE: The ending condition of VB 'For' loops is tested only on entry to the loop. VB to Java Converter has created a temporary variable in order to use the initial value of ActBin + NumDHabits for every iteration: var tempVar = ActBin + NumDHabits; for (DHabitBinTyp = ActBin + 1 + SenseOrDeviceNum; DHabitBinTyp <= tempVar; DHabitBinTyp++) { ping(); BinonTypeName[DHabitBinTyp][BinName] = "D-Habit"; BinonTypeName[DHabitBinTyp][BinAbbreviation] = "DH"; } NumBinonTypes = ActBin + NumDHabits; } else { Stop(); //no other value allowed } } BinonTypeName[BinTypNum][BinName] = BinNam; BinonTypeName[BinTypNum][BinAbbreviation] = BinAbb; BinonTypes[BinTypNum][SensOrDevNum] = SenseOrDeviceNum; //points back to the device number 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 (NumDevices == MaxDevices) //Can't assign another new device number { Stop("NumDevices == MaxDevices (" + NumDevices + ")"); } //There are only so many device types in DeviceValues array //currently set to 8 in Adaptron.Initialize_Adaptron() if (DeviceNum == 0) //don't have a device number yet so assign and return it { NumDevices = NumDevices + 1; //The new device number for this device DeviceNum = NumDevices; //The returned device number } else if (DeviceNum > MaxDevices) //else it is more than allowed { Stop("DeviceNum > MaxDevices (" + DeviceNum + "/" + MaxDevices + ")"); } else if (DeviceNum > NumDevices + 1) //else is it higher than the next one available { Stop("DeviceNum > NumDevices+1 (" + DeviceNum + "/" + (NumDevices+1) + ")"); } else if (DeviceNum <= NumDevices) //else use the one passed in - overriding an existing device { } else if (DeviceNum == NumDevices + 1) //next device number provided { NumDevices = DeviceNum; //The new device type number for this device = DeviceNum } UseDevice = DeviceNum; if (IntensityRange > 256) //only 256 values allowed for response intensity { Stop("IntensityRange > 256 (" + IntensityRange + ")"); } Device[UseDevice] = DName; Devices[UseDevice][SymbolicOrMagnitude] = MagnOrSymb; Devices[UseDevice][LowerRangeLimit] = LowerLimit; //lower limit number / range of response values Devices[UseDevice][UpperRangeLimit] = UpperLimit; //upper limit number / range of response values DeviceResponses[UseDevice] = Responses; //the symbolic responses if (Devices[UseDevice][SymbolicOrMagnitude] == Magnitude) //Magnitude READINGS { Devices[UseDevice][LinearOrCircular] = LinOrCirc; //can be circular or linear DeviceResponses[UseDevice] = ""; //no symbolic responses are possible } else //Symbolic readings can not be circular { Devices[UseDevice][LinearOrCircular] = Linear; //non circular } Devices[UseDevice][IntegersOrLogs] = IntOrLog; //SetupBinonTypes(SenseOrDeviceNum, BinNam$, BinAbb$, IsASense, BinonTypReturned) SetupBinonTypes(UseDevice, BinonName, BinonAbbrev, IsDevice, BinTypNum); Devices[UseDevice][PropertyBinonType] = BinTypNum.get(); //The binon number usually = highest number so far //Fill in device info. on world page //XXX World.DeviceInfo.Text = ""; for (int Dvc = 1; Dvc <= NumDevices; Dvc++) { ping(); if (Devices[Dvc][SymbolicOrMagnitude] == Magnitude) { DisplayResponses = Devices[Dvc][LowerRangeLimit] + " to" + Devices[Dvc][UpperRangeLimit]; } else //symbolic values { DisplayResponses = DeviceResponses[Dvc]; //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 (var I = 1; I <= tempVar; I++) //blank out the NoMoveOrTurn$ "z" symbols { ping(); 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 void Reset_Adaptron() //Called from DesignBody.FinalSetup(), & ResetWld_Click() { //Resets all changing info. to starting places. //Must be called before setting up any senses/sensors. int String; int D; int I; ResetRnd(-1); //necessary to reset the sequence OverLimit = false; CreateAll = false; //True if create all combinations, False if use only familiar parts // CreateAll = True ' BodyPointing = North; //always starts with body pointing North NumSenses = 0; //start with no senses NumDevices = 0; //start with no devices Motion = NoMove; //World.MoveDown() etc set this to indicate the direction the robot moved //and it is used as the stimulus input of the Motion sense for (I = 1; I <= MaxSenses; I++) //+1 so it covers the Percept sense too { ping(); Sense[I] = ""; //Names of sense } StoreAt = 0; //Initially the long term memory history is empty //Initialize STMs LIN = 0; //clear out memory display stuff - index into INPUTS$() and OUTPUTS$() COUNTIN = 0; //Count of inputs ClearMemory(); //This clears BinonDisplay.ChngResults.Text and LTM for (I = 0; I <= 500; I++) { ping(); if (I > 0) { } for (String = 1; String <= MaxSenses; String++) { ping(); INPUTS[I][String] = ""; } for (D = 1; D <= MaxDevices; D++) { ping(); OUTPUTS[I][D] = ""; } } //Adapt.IO.Text = ""; //Adapt.LTMem.Text = ""; //UNUSED TriggerObj = NullObject; DoingReaction = false; //set true if last response was reflexive. DoingRepeat = false; //ActiveActon = NullAct; //no subconscious acton active //UNUSED ExploreObj = NullObject; //will be set if reflexive response done. //DoingAct1 = NullAct; //will be set if reflexive response done. //UNUSED NumTrigLinks = 0; //Number of LTM episodic action links //UNUSED NumActons = 0; NumActs = 0; //The number of Acts entries in use RotateActs = false; //Rotate through all reflexive acts LastAct = 1; //initialized so next one will be #2 - not the Relax response = #1 if (RotateActs) //Rotation through acts starts with Relax { LastAct = 0; } } //End of Reset-Adaptron() private void ResetRnd(int i) { // TODO } public void ClearMemory() { //Called by Reset_Adaptron() int Lk; int T; int I; for (I = 1; I <= MaxBinons; I++) { ping(); Binons[I][OLv] = 0; Binons[I][O1] = NullObject; Binons[I][O2] = NullObject; ZeroTheCounts(I); } NumBinons = 0; //there are no binons for (T = 1; T <= MaxBinonTypes; T++) //For all property binons and their Percept combinations and Actions { ping(); BinonTypeName[T][BinName] = ""; //The names and abbreviations for the various binon types BinonTypeName[T][BinAbbreviation] = ""; BinonTypes[T][SymbolicOrMagnitude] = Symbolic; BinonTypes[T][SensOrDevNum] = 0; // Pointer points back to sense or device } ClearSenses(); //clear SensorValues() and SensedBinons() ClearPerceptions(); //clear out all the perceptions in STM() TopLevel = 0; for (T = 1; T <= MaxPercepts; T++) //Clear perceived Parallel Percept and property binon entries { ping(); Percepts[T][BinId][Current] = NullObject; Percepts[T][BinId][Fired] = NullObject; Percepts[T][XQCnt][Current] = 0; Percepts[T][XQCnt][Fired] = 0; } for (Lk = 1; Lk <= MaxTargets; Lk++) //Clear out all targets { ping(); Targets[Lk][NLnk] = NullTarget; Targets[Lk][TargetBinon] = NullObject; } NumTargets = 0; ClearExpectations(); World.setBinonDisplayObjList(""); World.setBinonDisplayChngResults(""); JND = 20; //Percent AssignBases(); // SizeBase# = 1.2 for a 20% just noticeable difference } //End of ClearMemory() public void ZeroTheCounts(int Habit) //Called by ClearMemory() { Binons[Habit][TQ] = 0; Binons[Habit][GQ] = 0; } //End ZeroTheCounts() public void ClearSenses() //Called by ClearMemory() { for (int Sens = 1; Sens <= MaxSenses; Sens++) { ping(); SensorValues[Sens][XQCnt][Fired] = 0; SensorValues[Sens][Valu][Fired] = 0; SensorValues[Sens][XQCnt][Current] = 0; SensorValues[Sens][Valu][Current] = 0; SensedBinons[Sens] = NullObject; } NumProperties = 0; } //End of ClearSenses() public void ClearPerceptions() //Used by ClearMemory() and processing STM perceptions in PerceptionAction() { //Clear out all the Current and previous perceptions that are sources for Habits in the STM() int Percpt; int Lvl; World.appendBinonDisplayChngResults(" ** Clearing Perceptions " + "\r\n"); for (Lvl = 1; Lvl <= MaxLevels; Lvl++) { ping(); for (Percpt = Fired; Percpt <= MaxLevels; Percpt++) { ping(); EmptySTM(Lvl, Percpt); } } } //End of ClearPerceptions() public void AssignBases() //Called by ClearMemory() { double Percnt; Percnt = /*Microsoft.VisualBasic.Conversion.Val*/(JND) / 100.0; SizeBase = 1 + Percnt; //1.2 for a 20% just noticeable difference IntensityBase = 1 + Percnt; //If it is 2.0 then that is a 100% just noticeable difference } //End of AssignBases() public final int Buckit(double Valuu, double Base) { // Base# = 1.2 'Ln(1.3) = 0.26, Ln(1.2) = 0.18 return (int) Math.round(100 * Math.log(Valuu) / Math.log(Base)); // XXX } //End of Buckit() public final void IdBinons(int OLvl, int Prt, int Obj1, int TQNum, int Obj2, int GQNum, int IDLRatio, int SeqOrPar, int ExpectIt, Var ObjId, Var NewOne) { //OLvl = Level of the binon, 1 stimulus property binons and response binons, 2+ Percepts or Action patterns //PrT = Property Type value //Obj1 = The left source binon //Obj2 = The right source binon //IDLRatio = The IDL ratio value //SeqOrPar = whether it is an Action sequence or a parallel Percept //ObjId = The object / binon identifier returned, = NullObject if over the limit //NewOne = Returned True if object newly created, False if it already existed. //If a new binon is created it is Active but Idle - waiting to repeat //---- Binon Properties - 2nd index values // Public BType '1, The type of binon // Public O1 '2, Left source binon pointer // Public TQ '3, the count of times the trigger has fired // Public O2 '4, Right source binon pointer // Public GQ '5, the number of times the goal has fired // Public IDL '6, The ratio value of the binon // Public IntVl '7, Interest Value (NOVEL, INTERESTING, or Familiar) // Public OLv '8, Level of object = number of lowest level parts involved // Public SP '9, Sequential or Parallel property // Public TriggerList '10, points to the linked list of target binons [Targets()] // ' for which this binon is the left source binon (not the right source binon). // Public TriggerCount '11, Count of its sequential right targets, >1 means it has more than one goal // ' Used for prediction reliability, may be set >1 if needs to be combined with previous // Public GoalList '12, points to the linked list of target binons [Targets()] // ' for which this binon is the right source binon (not the left source binon) // Public GoalCount '13, Count of its sequential left targets, >1 means can not predict its trigger // ' Used for reliability of determining the cause, may be set >1 if needs to be combined with next // Public AE '14, Action (Percept - Act) or Attention (Act - Percept) level 1 Sequential binon //Given two objects/parts Obj1 and Obj2 //see if we have an object ObjId with the same values and the same Obj1 and Obj2. //Return the found or newly created binon if (Obj1 == 0) throw fail("obj1 = 0"); if (Obj2 == 0) throw fail("obj2 = 0"); if (NumBinons >= MaxBinons) //if can not find the exact match { ObjId.set(NullObject); World.appendBinonDisplayChngResults("\r\n" + "Binon limit of " + MaxBinons + " reached!"); Stop(); return; } ObjId.set(NullObject); //Return no binon - none created by default NewOne.set(true); //Assume we will not find it already exists and will create a new one //First determine if we have any binons of the given type with the given ratio if (NumBinons > 0) //if none then do not check if ExistBinon { //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 (ObjId.get() == NullObject) //If it does not already exist then create it { ObjId.set(NumBinons + 1); //it was not found - so add it as a new one Binons[ObjId.get()][BType] = Prt; Binons[ObjId.get()][O1] = Obj1; //The left source binon Binons[ObjId.get()][TQ] = TQNum; Binons[ObjId.get()][O2] = Obj2; //The right source binon Binons[ObjId.get()][GQ] = GQNum; Binons[ObjId.get()][IDL] = IDLRatio; //stored object ratio values //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 (SeqOrPar == Parallel) //If it is a Property or Percept binon then { if (Prt <= NumProperties) //if it is a Property binon then { SetInterest(ObjId.get(), NOVEL); //Property binons start out Novel SetInterest(ObjId.get(), FAMILIAR); //Familiar for testing purposes } else //else it is a Percept binon { SetInterest(ObjId.get(), NOVEL); //Percept binons start out Novel SetInterest(ObjId.get(), FAMILIAR); //Familiar for testing purposes } } else { SetInterest(ObjId.get(), NOVEL); //Sequential binons start out Novel //tmp Call SetInterest(ObjId, FAMILIAR) 'Familiar - for testing } Binons[ObjId.get()][OLv] = OLvl; Binons[ObjId.get()][SP] = SeqOrPar; //Sequential or ParallelPrt, if (SeqOrPar == Parallel && ExpectIt != 0) //AE value should be 0 { Stop(); } Binons[ObjId.get()][AE] = ExpectIt; //only used if SP=Sequential and OLvl=1, Action=1, Attention=2 Binons[ObjId.get()][TriggerList] = NullTarget; //=0, an NLnk pointer at end of linked list Binons[ObjId.get()][TriggerCount] = 0; //Count of its sequential right targets, >1 means can not predict its goal Binons[ObjId.get()][GoalList] = NullTarget; //=0, an NLnk pointer at end of linked list Binons[ObjId.get()][GoalCount] = 0; //Count of its sequential left targets, >1 means can not predict its trigger // '--- 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 (Obj1 != NullObject) //cannot be property binon { NumTargets = NumTargets + 1; //create a new target if (NumTargets > MaxTargets) //have we exeeded the maximum { Stop(); } Targets[NumTargets][TargetBinon] = ObjId.get(); //The right target is the newly created binon Targets[NumTargets][NLnk] = Binons[Obj1][TriggerList]; //It should point to the 1st one on existing list Binons[Obj1][TriggerList] = NumTargets; //ObjId becomes the 1st one on the right target list of Obj1 if (SeqOrPar == Sequential) { Binons[Obj1][TriggerCount] = Binons[Obj1][TriggerCount] + 1; //Count of right targets for Obj1 } } //The source binon Obj2 is the goal of this target binon ObjId so add it to the left target list of Obj2 if (Obj2 != NullObject) //cannot be property binon { NumTargets = NumTargets + 1; //create a new target if (NumTargets > MaxTargets) //have we exeeded the maximum { Stop(); } Targets[NumTargets][TargetBinon] = ObjId.get(); //The left target is the newly created binon Targets[NumTargets][NLnk] = Binons[Obj2][GoalList]; //It should point to the 1st one on existing list Binons[Obj2][GoalList] = NumTargets; //ObjId becomes the 1st one on the left target list of Obj2 if (SeqOrPar == Sequential) { Binons[Obj2][GoalCount] = Binons[Obj2][GoalCount] + 1; //Count of left targets for Obj2 } } 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) { SetInterest(Bino, INTERESTING); //Novel -> Interesting } else //Interestlevels=2 { SetInterest(Bino, FAMILIAR); //Novel -> Familiar } break; case INTERESTING: SetInterest(Bino, FAMILIAR); //Interesting -> 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; int StartAt; //range of binons to search int EndAt; tempExistBinon = false; //assume it does not exist ObjId.set(NullObject); //return NullObject if not found StartAt = 1; EndAt = NumBinons; for (OO = StartAt; OO <= EndAt; OO++) //For all the known objects of this type { ping(); //Object level is an identifying property of a binon if (Binons[OO][OLv] == OLvl) //If it is at the same level then { if (Binons[OO][BType] == PrTyp) //if it is the same binon type then { //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 (V1 == Binons[OO][IDL]) //If it has the same quantity IDL Ratio? { ObjId.set(OO); tempExistBinon = true; OO = NumBinons; //terminate FindIt loop } } } } } 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; int AEorEA = 0; //Action-Expectation (Response-Stimulus) or Expectation-Action (Stimulus-Response) 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 (StoreAt == MaxMemory) //stop further Go / Continue stepping { //XXX World.Go.Enabled = false; } World.setBinonDisplayChngResults("Step = " + StoreAt + "\r\n"); //display the cycle count // 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 ProcessStimuli(SensorValues); //Process the 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 (Pass = 1; Pass <= 2; Pass++) //For 1/ R-S & A-E combinations then 2/ S-R & E-A combinations { ping(); ObjtLvl = 1; //Start by processing level 1 perceptions - always assigned NovelLvl = 0; //set to the level at which the fired STM is novel MoveAmount = 0; //Move right amount to eliminate previous pattern SourceBinon = STM[ObjtLvl][BinId][Fired]; //It may be a right source binon for some target binons while (SourceBinon != NullObject) //While there is a Fired familiar binon in STM { ping(); World.appendBinonDisplayChngResults(StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0/ Processing percepts at level" + vbToStr(ObjtLvl) + "\r\n"); //First move the STM entries right by the MoveAmount due to a repeater at a lower level if (MoveAmount > 0) { int Prcpt = 0; // declare undeclared variable MoveRight(ObjtLvl, Current + MoveAmount, Current, 2 * Prcpt); //eliminates binon created with previous goal from STM } if (InterestIn(SourceBinon) > FAMILIAR) //If the STM fired binon is novel then { NovelLvl = ObjtLvl; //It can not be combined with a current } else //else check for a repeat and combine with current in STM { CheckIt = false; //do not check for a repeat of an Action if (Pass == 1) //If the Stimulus / Expectation processing pass { AEorEA = Attention; HabitIt = "Percept"; if (ObjtLvl % 2 == 0) //Odd level = 1, Even level = 0 { HabitIt = "Action"; CheckIt = true; //Check to see if it repeats - both A and E - even levels } } else if (Pass == 2) //else if the Action / Response processing pass { AEorEA = Action; //assume it will be an Action HabitIt = "Action"; if (ObjtLvl % 2 == 0) //If fired entry is an Action then (Pass=2 and remainder =0) { HabitIt = "Expectation"; CheckIt = true; //Check to see if it repeats - both A and E - even levels } } World.appendBinonDisplayChngResults(StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0a/ Pass" + vbToStr(Pass) + " - " + HabitIt + " Processing" + "\r\n"); ProcessSTMLevel(ObjtLvl, SourceBinon, AEorEA, CheckIt); } //End if STM Fired binon is Novel MoveLeft(ObjtLvl); //Move all STM left, the fired entry into the current location HighestPerceptLvl = ObjtLvl; //Remember the highest not null fired level in STM if (HighestPerceptLvl > TopLevel) //track highest non-empty level { TopLevel = HighestPerceptLvl; } //Go up the pattern tree combining Fired and Currents if they are patterns and fired is not nullobject ObjtLvl = ObjtLvl + 1; //check out the next level for current and fired if (ObjtLvl <= MaxLevels) { SourceBinon = STM[ObjtLvl][BinId][Fired]; //It may be a right source binon for some target binons or Null } else { SourceBinon = NullObject; Stop(); } } //Move all higher levels left by one minus moveamount MoveAmount = 1 - MoveAmount; //move left one but right based on repeater found for (; ObjtLvl <= TopLevel; ObjtLvl++) //for all higher levels that have something in them { ping(); if (MoveAmount == 1) { MoveLeft(ObjtLvl); //processed one more level 1 stimulus } else if (MoveAmount < 0) { MoveRight(ObjtLvl, Current - MoveAmount, Current, 2 * ObjtLvl); } } ReportObjects1(); //Fill in the top part of BinonDisplay.ChngResults.Text SourceBinon = STM[HighestPerceptLvl][BinId][Current]; //It may be a right source binon for some target binons 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 DetermineResponse(); //determine what response to produce - do thinking //Keep a record of STM() binons for display of LTM LTMEMORY[StoreAt][LtmESType] = BinonTypeOf(SourceBinon); LTMEMORY[StoreAt][LtmESActBin] = SourceBinon; World.appendBinonDisplayChngResults(DisplaySTM()); } else //else Pass = 2 { //If finished pass 2/ STM processing then based on the recognized Action or Action sequence find any //predicted perception and use this highest level Expectation or Perceptual sequence found worth doing and //do its lowest level expected Percept and attend to it in ProcessStimuli(). //This effectively means DetermineStimulus() needs to determine what stimulus to attend to //The stimulus Percept obtained will be the Fired Perceptual sequence to start this process again. //Keep a record of STM() binons for display of LTM LTMEMORY[StoreAt][LtmARType] = BinonTypeOf(SourceBinon); LTMEMORY[StoreAt][LtmARActBin] = SourceBinon; //The level 1 perceived stimulus could be a familiar stimulus but unexpected. // It is unexpected because none of the active Perceptual sequences were expecting it. ReportPerceptions(); //Reports on Percepts() and STM() & expectation ReportObjects2(); //Report on Binons } //End if Pass =1 or Pass = 2 } } //End of PerceptionAction() public final void ProcessStimuli(int[][][] SensorValues) //Called from PerceptionAction() { //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; OL = 1; //Property binons and their combinations are at level 1 HaveAChange = false; //Assume no change will take place on any sense //The expectation is the previous stimulus will repeat ReportPerceptions(); //Report on all Percepts, Actions and expectations ProcessSenses(OL, SensorValues); //Obtain the SensedBinons() for all property types 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 (Sens = 1; Sens <= NumSenses; Sens++) //For each property type = sense { ping(); TheType = Sens; Percepts[TheType][XQCnt][Fired] = SensorValues[Sens][XQCnt][Fired]; Percepts[TheType][BinId][Fired] = SensedBinons[Sens]; //Property binons into Percepts Level 1 if (Percepts[TheType][BinId][Current] != NullObject) //use the previous SensedBinon { if (SensedBinons[Sens] != Percepts[TheType][BinId][Current]) { HaveAChange = true; //This property binon has changed } } else //Else the Current entry is empty the first time through { if (StoreAt != 1) { Stop(); } } } //end for each property binon CreatePerceptCombos(); //Create all the combinations of Percepts //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 TopBinon = NullObject; //Will be the highest complexity if no changed one found TopType = NullType; if (HaveAChange) { TopInterest = NoInterest; //The interest level of the highest changed binon for (PerceptType = NumPercepts; PerceptType >= 1; PerceptType--) //For all the Percept binon types from complex to property binons { ping(); FirstBinon = Percepts[PerceptType][BinId][Fired]; //The Percept that fired of this type - maybe NullObject SecondBinon = Percepts[PerceptType][BinId][Current]; //The previous or expected binon of this type - maybe NullObject if (FirstBinon != SecondBinon) //If the fired one is different / changed then { //If have a perceived binon and an expected one then if (FirstBinon != NullObject) { IntInF = InterestIn(FirstBinon); //Interest level of this Percept //If it is familiar and interest so far is also familiar then we use the largest changed combination if (IntInF == FAMILIAR) { if (TopInterest == NoInterest) //The first / highest familiar one { // subroutine UseThisOne TopType = PerceptType; TopBinon = FirstBinon; //Save the highest level changed interesting Percept TopInterest = IntInF; //will be familiar - only used if HaveAChange=True } //Else if it is novel then use the lowest level highest interest that has changed } else if (IntInF >= TopInterest) //If it is more or equal interest than the one so far then { // subroutine UseThisOne TopType = PerceptType; TopBinon = FirstBinon; //Save the highest level changed interesting Percept TopInterest = IntInF; //will be familiar - only used if HaveAChange=True } } 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 (PerceptType = NumPercepts; PerceptType >= 1; PerceptType--) //For all the Percept binon types from complex to property binons { ping(); FirstBinon = Percepts[PerceptType][BinId][Fired]; //The Percept that fired of this type - maybe NullObject if (FirstBinon != NullObject) { // subroutine UseThisOne TopType = PerceptType; TopBinon = FirstBinon; //Save the highest level changed interesting Percept TopInterest = IntInF; //will be familiar - only used if HaveAChange=True PerceptType = 1; //terminate loop } } } if (HaveAChange) //report about a different stimulus then - unexpected { GotWhat = "Got UNEXPECTED: "; } else //else we got what was expected { GotWhat = "Got EXPECTED: "; } World.appendBinonDisplayChngResults(rep(' ', 55) + GotWhat + DisplayPattern(TopBinon) + "\r\n"); ClearExpectations(); //Clears PracticingBinon, PerceivedBinon etc. //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) FireTheBinon(OL, TopBinon, 1, RepeatCount); //will set the XQ count and the Perceived etc. RememberStimulus(TopBinon, StoreAt); } //Move the fired Percepts() actually sensed into the current entries and clear the Fired entries for (PerceptType = 1; PerceptType <= NumPercepts; PerceptType++) //For all property and Percept binon types { ping(); Percepts[PerceptType][BinId][Current] = Percepts[PerceptType][BinId][Fired]; Percepts[PerceptType][BinId][Fired] = NullObject; //clear their entries Percepts[PerceptType][XQCnt][Current] = Percepts[PerceptType][XQCnt][Fired]; Percepts[PerceptType][XQCnt][Fired] = 0; } } //End of ProcessStimuli() public final void ProcessSenses(int OL, int[][][] SensorValues) //Called from ProcessStimuli() { //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 (int Sens = 1; Sens <= NumSenses; Sens++) //For each sense (TextBin and ContBin) = for each property type { ping(); PropBinonType = Sens; //In Morse code only one property per sense if (Senses[Sens][SymbolicOrMagnitude] == Symbolic) //If symbolic then { //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); SensedBinons[Sens] = SensedBinon.get(); //Fired Symbolic value changed } else //Else ValueType = Magnitude { FiredLogVal = Buckit(SensorValues[Sens][Valu][Fired], SizeBase); //Goal //The first time though we will not have a previous (Current) sensor reading (PrevLogVal) if (SensorValues[Sens][Valu][Current] == 0) //no previous value { ValuDiff = 1; //there is a change in the Magnitude reading } else { PrevLogVal = Buckit(SensorValues[Sens][Valu][Current], SizeBase); //Trigger //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 ValuDiff = (PrevLogVal - FiredLogVal) / 100; //Trigger minus Goal Logs } //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); SensedBinons[Sens] = SensedBinon.get(); //Fired Magnitude value changed by a JND } SensorValues[Sens][Valu][Current] = SensorValues[Sens][Valu][Fired]; //save the previous value SensorValues[Sens][XQCnt][Current] = SensorValues[Sens][XQCnt][Fired]; //save the previous repeat count } //End of loop for each property type = sense } //End of ProcessSenses() public final void CreatePerceptCombos() //Create all the combinations of Percepts { 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 = NumProperties + 1; PropBinonType <= NumPercepts; PropBinonType++) //PropBinonType used for position of the combination { ping(); FirstType = PerceptSources[PropBinonType][FirstSource]; SecondType = PerceptSources[PropBinonType][SecondSource]; OL = PerceptSources[PropBinonType][PerceptLevel]; // CombineThem; //Uses Percepts[TheType][BinId][Current] to determine change // CombineThem: FirstBinon = Percepts[FirstType][BinId][Fired]; SecondBinon = Percepts[SecondType][BinId][Fired]; Percepts[PropBinonType][BinId][Fired] = NullObject; //assume the combination will not be produced if (FirstBinon != NullObject && SecondBinon != NullObject) //if both sources are not null { 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 FirstChanged = false; //Percepts[TheType][BinId][Current] if (Percepts[FirstType][BinId][Current] != FirstBinon) { FirstChanged = true; } SecondChanged = false; if (Percepts[SecondType][BinId][Current] != SecondBinon) { SecondChanged = true; } if (FirstChanged == SecondChanged) //If both changed or both stayed the same then { //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 void ActivateAction(int DoBinon) //called from PerceptionAction() { //DoBinon& is the PracticingBinon Action that is to be done var DHabitBinon = new Var<>(0); //GetDHabit returns the Action or D-Habit Binon GetDHabit(DoBinon, DHabitBinon); //Get the level 1 D-Habit to perform PerformDHabit(DHabitBinon.get()); } //End of ActivateAction() public final void PerformDHabit(int DoBinon) //called from ActivateAction() { //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 (DoBinon == NullObject) //If there was no response in DoBinon then { Stop(); //should always have one selected by DetermineResponse() // 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); DeviceNum = BinonTypes[OutType][SensOrDevNum]; //the device number for this response type binon } //Output the response (if any) and setup the expectation Letter.set(""); //GetValue adds text to 3rd parameter = Letter$ so empty it GetValue(OutBinon, Letter); Letter.set(StringHelper.trim(Letter.get(), ' ')); World.appendBinonDisplayChngResults(" OUTPUT response = " + Letter + "\r\n"); DeviceValues[DeviceNum][XQCnt] = 1; DeviceValues[DeviceNum][Valu] = Binons[OutBinon][IDL]; ClearExpectations(); //Clears PerceivedBinon //FireTheBinon(PercptLvl, TheBinon&, TQCnt, XQCnt) FireTheBinon(1, OutBinon, 1, 1); //will set PerceivedBinon RememberResponse(OutBinon, StoreAt); } //End PerformDHabit() public final void ReportPerceptions() { //Display the Fired, Current and previous perceptions in Percepts() //unused String OLvl = null; //unused String Prcpt = null; //unused String Pcpts = null; DisplayPercepts(Current); //Report on Perceptual sequence perceptions World.appendBinonDisplayChngResults(DisplaySTM() + "\r\n"); } //End of ReportPerceptions() public final void DisplayPercepts(int CurrOrFired) { int BinType; //Report on Percept recognitions World.appendBinonDisplayChngResults(" Percepts = "); for (BinType = 1; BinType <= NumPercepts; BinType++) //All binon types except Actions { ping(); World.appendBinonDisplayChngResults(DisplayPercept(BinType, CurrOrFired)); } World.appendBinonDisplayChngResults("\r\n"); } //End of DisplayPercepts() public final String DisplayPercept(int BType, int CurrOrFired) { return StringHelper.trim(String.valueOf(Percepts[BType][XQCnt][CurrOrFired]), ' ') + "x" + DisplayPattern(Percepts[BType][BinId][CurrOrFired]) + " "; } //End of DisplayPercept$() public final String DisplaySTM() { String tempDisplaySTM = ""; int OLvl; int Prcpt; String Pcpts; //Report on perceptions in STM() if (STM[1][BinId][Current] == NullObject) //No STM entries then { tempDisplaySTM = "STM is empty" + "\r\n"; } else { for (OLvl = 1; OLvl <= MaxLevels; OLvl++) { ping(); //printVars_str DisplaySTM(+OLvl, +MaxLevels); Pcpts = ""; //empty this line for (Prcpt = OLvl + 2; Prcpt >= Fired; Prcpt--) //find out if any are not null at this level { ping(); if (STM[OLvl][BinId][Prcpt] != NullObject) { Pcpts = Pcpts + DisplaySTMEntry(OLvl, Prcpt) + " "; } } if (!Pcpts.equals("")) //Only if there was a fired entry { Pcpts = " " + "Lvl=" + StringHelper.trim(String.valueOf(OLvl), ' ') + " " + Pcpts; //Put level # at start of line tempDisplaySTM = tempDisplaySTM + Pcpts + "\r\n"; } else //else no current entry at this level { OLvl = MaxLevels; //terminate the loop } } 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); VL.set(substring(substring(VL.get(), 0, 20) + " ", 0, 7)); //display 6 chars of pattern return "#" + StringHelper.trim(vbToStr(CurrFired), ' ') + "=" + StringHelper.trim(String.valueOf(STM[Percpt][XQCnt][CurrFired]), ' ') + "x" + StringHelper.trim(String.valueOf(STM[Percpt][TQCnt][CurrFired]), ' ') + DisplayStimulu(BinonId) + " " + VL; } //End of DisplaySTMEntry$() public final String DisplayPattern(int StimBin) { String tempDisplayPattern; var BinonTyp = new Var<>(""); var VL = new Var<>(""); int NumChr; int StimTyp; StimTyp = BinonTypeOf(StimBin); if (StimTyp == NullType) { tempDisplayPattern = " ~ "; } else if (StimBin == NullObject) //Have a type but no binon { GetTypeInfo(StimTyp, BinonTyp, VL); tempDisplayPattern = VL.get().substring(0, 2) + " ~"; } else { NumChr = 5 + 6 * (StimTyp - 1); //Level 2 is 11 characters, level 3 is 17 characters GetValue(StimBin, VL); tempDisplayPattern = DisplayStimulu(StimBin) + " " + substring(VL.get(), 0, NumChr); } return tempDisplayPattern; } //End of DisplayPattern$() public final String DisplayStimulu(int StimBin) { String tempDisplayStimulu; var BTyp = new Var<>(""); var Rdg = new Var<>(""); String Inf; String Gl; int StimTyp; StimTyp = BinonTypeOf(StimBin); if (StimBin == NullObject || StimTyp == NullType) { tempDisplayStimulu = "-00"; } else { GetTypeInfo(StimTyp, BTyp, Rdg); Gl = StringHelper.trim(Rdg.get().substring(0, 2), ' ') + StringHelper.trim(String.valueOf(StimBin), ' '); Inf = IntSymb(InterestIn(StimBin)); tempDisplayStimulu = Inf + Gl + AESR(StimBin); } return tempDisplayStimulu; } //End of DisplayStimulu$() public final String InterestSymbol(int BinNum) { int IntIn; IntIn = InterestIn(BinNum); return IntSymb(IntIn); } //End of InterestSymbol$() public String IntSymb(Object Intrst) { String tempIntSymb; tempIntSymb = ASpace; switch ((Integer) Intrst) { case NOVEL: tempIntSymb = chr(254); break; case INTERESTING: tempIntSymb = "!"; break; case FAMILIAR: tempIntSymb = "-"; break; } return tempIntSymb; } //End of IntSymb$() public void ClearExpectations() //Called by ClearMemory(), ProcessStimuli() and PerformAction() { 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 (TheBinon != NullObject) //If a valid binon has fired { STM[PercptLvl][BinId][Fired] = TheBinon; if (STM[PercptLvl][XQCnt][Fired] != 0) //should be zero { Stop(); } STM[PercptLvl][XQCnt][Fired] = XQCount; //It has fired this many times STM[PercptLvl][TQCnt][Fired] = TQCount; //trigger firing count for comparison of size of repeaters // 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 (PercptLvl == 1) //If at level-1 start with the S or R { PerceivedBinon = TheBinon; //Track the trigger of expected goal for the Action } else { if (isSorR(TheBinon)) //If on an odd level - Perceptual - or Action sequence then { Uselink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(TheBinon)); //determine its first associating binon, if any if (Uselink != NullTarget) //If the fired binon has at least one associating binon { PerceivedBinon = TheBinon; //Track the trigger of expected goal for the Action } else //else use the previously assigned PerceivedBinon { } } else //else we are on an even level - A- or Expectation { // Stop } } } else { Stop(); //The fired binon should never be null } } else //else it is novel and can not be put on STM() { String Res = (" " + PercptLvl).substring((" " + PercptLvl).length() - 5) + vbToStr(Binons[TheBinon][TriggerCount]) + vbToStr(Binons[TheBinon][GoalCount]) + " " + DisplayPattern(TheBinon) + " NEW" + "\r\n"; World.appendBinonDisplayChngResults("\r\n" + Res); } //End If TheBinon is not novel } //End of FireTheBinon() public final void ImYourMostRecent(int HabBinon, int TriggerOrGoal) { int SourceBinon; int TgtLink; int TgtBinon; int PrevLink; int FirstLink; boolean FoundIt = false; if (TriggerOrGoal == TriggerList) { SourceBinon = Binons[HabBinon][O1]; //Left source binon - trigger } else { SourceBinon = Binons[HabBinon][O2]; //Right source binon - goal } if (SourceBinon != NullObject) { //Find the target binon on the trigger or goal list of the source binon and move it to the front of the list TgtLink = Binons[SourceBinon][TriggerOrGoal]; FirstLink = TgtLink; FoundIt = false; PrevLink = NullTarget; while (!FoundIt) { ping(); if (TgtLink == NullTarget) //should have been on the list { Stop(); } TgtBinon = Targets[TgtLink][TargetBinon]; //The target binon if (TgtBinon == HabBinon) //If it matches the HabBinon then found the entry { FoundIt = true; if (PrevLink != NullTarget) //If not at the start of the list already { Targets[PrevLink][NLnk] = Targets[TgtLink][NLnk]; //remove the TgtLink Targets() entry from linked list Targets[TgtLink][NLnk] = FirstLink; //TgtLink Targets() entry points to old first one on list Binons[SourceBinon][TriggerOrGoal] = TgtLink; //It is now the 1st one / most recent target of source binon } } else { PrevLink = TgtLink; //Link for the previous Targets() entry TgtLink = Targets[TgtLink][NLnk]; //go to the next link in Targets list } } } } //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 TgtLink = Binons[TheBinon][TriggerList]; //The list of all targets for which it is the trigger tempMostRecentTriggerTargetLink = NullTarget; if (Binons[TheBinon][TriggerCount] > 0) //If TheBinon has any sequential right targets then { while (TgtLink != NullTarget) { ping(); if (BinonTypeOf(Targets[TgtLink][TargetBinon]) == ActBin) //The type of right target binon of the the given stimulus { tempMostRecentTriggerTargetLink = TgtLink; TgtLink = NullTarget; //found the first useful Perceptual sequence - terminate the loop } else //else some of the right targets could be Percepts? { TgtLink = Targets[TgtLink][NLnk]; //skip Percepts } } } 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; FoundBinon.set(TheBinon); //If it is the NullObject then that is returned while (BinonTypeOf(FoundBinon.get()) == ActBin) { ping(); FoundBinon.set(Binons[FoundBinon.get()][O2]); } //Now the Found binon type is a D-Habit binon } //End of GetDHabit() public final void ProcessSTMLevel(int ObjtLvl, int SourceBinon, int AorE, boolean CheckRepeat) //called by PerceptionAction() { //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 Prcpt = ObjtLvl; //Repeater at this level will be in this entry position TrgtLvl = ObjtLvl + 1; if (CheckRepeat) //If need to check if an Action or Expectation repeats then { World.appendBinonDisplayChngResults(StringHelper.trim(String.valueOf(ObjtLvl), ' ') + "-0c/ Check for repeater Action" + "\r\n"); OldPercBin = STM[ObjtLvl][BinId][Prcpt]; //Any repeater should be in the correct position = ObjtLvl if (OldPercBin == SourceBinon) //If the old = Fired it is a repeat binon { TQFired = STM[ObjtLvl][TQCnt][Fired]; //Trigger quantity (size) of the SourceBinon just fired TQRepeat = STM[ObjtLvl][TQCnt][Prcpt]; //Trigger quantity (size) for the older Prcpt binon if (TQRepeat == TQFired) //If the repeater is the same size as the fired one then { //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) MoveRight(ObjtLvl, Prcpt, Fired, 2 * Prcpt); //repeater ends up in Fired entry EmptySTM(TrgtLvl, Fired); //clear the fired next level up } 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 (STM[ObjtLvl][BinId][Current] != NullObject) //If there is a trigger previous to the fired location { if (STM[ObjtLvl][BinId][Fired] != NullObject) //and there is a goal at the repeater position { if (ObjtLvl > 1 || STM[ObjtLvl][XQCnt][Current] != 0) //set to 0 if already used { CreateCombo(ObjtLvl, Current, AorE); //Place the result in Fired of level above } else { Stop(); // why? } if (Prcpt + 2 <= MaxLevels) { EmptySTM(ObjtLvl, Prcpt + 2); //Remove used trigger binon } } 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; Distance = FromEntry - ToEntry; //how far they have to move if (UpTo > MaxLevels) { UpTo = MaxLevels; } for (Prcpt = FromEntry; Prcpt <= UpTo; Prcpt++) { ping(); NewPrcpt = Prcpt - Distance; MoveOnePerception(ObLvl, Prcpt, NewPrcpt); EmptySTM(ObLvl, Prcpt); //Nullify where it came from } } //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; HaveAPercept = false; //assume this level is empty ToPrcpt = ObLvl + 2; if (ToPrcpt >= MaxLevels) { ToPrcpt = MaxLevels - 1; } for (Prcpt = ToPrcpt; Prcpt >= Fired; Prcpt--) { ping(); if (STM[ObLvl][BinId][Prcpt] != NullObject) { HaveAPercept = true; } MoveOnePerception(ObLvl, Prcpt, Prcpt + 1); //Move it left one position } EmptySTM(ObLvl, Fired); //and clear the fired entry if (!HaveAPercept) { TopLevel = TopLevel - 1; } } //End MoveLeft() public final void MoveOnePerception(int ObLvl, int FromEntry, int ToEntry) { STM[ObLvl][BinId][ToEntry] = STM[ObLvl][BinId][FromEntry]; STM[ObLvl][XQCnt][ToEntry] = STM[ObLvl][XQCnt][FromEntry]; STM[ObLvl][TQCnt][ToEntry] = STM[ObLvl][TQCnt][FromEntry]; } //End of MoveOnePerception() public void EmptySTM(int OLvl, int PrevCurrFired) { STM[OLvl][BinId][PrevCurrFired] = NullObject; STM[OLvl][XQCnt][PrevCurrFired] = 0; STM[OLvl][TQCnt][PrevCurrFired] = 0; } //End of EmptySTM() public final void CreateCombo(int ObjtLvl, int TrigPrcpt, int AorE) { //If it is possible, Combine the trigger (Current) and goal (Fired) binons in the STM() int TriggerBinon; int TQNum; int IntInTrig; int Bin12; int TQCount; int GoalBinon; int GQNum; int IntInGoal; int Bin21; int Prev1LogRpts; int Prev2LogRpts; int RptsDiff; var ResultBinon = new Var<>(0); int TgtLvl; var NewBee = new Var<>(false); int Bin11; int Bin22; boolean CombineThem = false; ResultBinon.set(NullObject); //Returned NullObject if not found or created TriggerBinon = STM[ObjtLvl][BinId][TrigPrcpt]; if (ObjtLvl == 1) { STM[ObjtLvl][TQCnt][TrigPrcpt] = STM[ObjtLvl][XQCnt][TrigPrcpt]; //wait until it has stopped repeating } if (TriggerBinon != NullObject) //If have a trigger pattern then { GoalBinon = STM[ObjtLvl][BinId][TrigPrcpt - 1]; if (GoalBinon != NullObject) //and if have a goal pattern then { IntInTrig = InterestIn(TriggerBinon); IntInGoal = InterestIn(GoalBinon); if (IntInTrig == FAMILIAR && IntInGoal == FAMILIAR) //if both familiar then { 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 (Binons[Bin11][TriggerCount] != 1 || Binons[Bin22][GoalCount] != 1 || Binons[Bin21][TriggerCount] != 1 || Binons[Bin21][GoalCount] != 1) //****** NOTE add True to the condition to turn off { CombineThem = true; } } if (CombineThem) { TQNum = STM[ObjtLvl][XQCnt][TrigPrcpt]; //the repeat value of the trigger - XQ count GQNum = STM[ObjtLvl][XQCnt][TrigPrcpt - 1]; //the repeat value of the goal - XQ count //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; Prev1LogRpts = Buckit(TQNum, SizeBase); //Trigger Prev2LogRpts = Buckit(GQNum, SizeBase); //Goal //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 RptsDiff = (Prev1LogRpts - Prev2LogRpts) / 100; //Trigger minus Goal Logs //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. TQCount = STM[ObjtLvl][TQCnt][TrigPrcpt]; //The size of the lowest level left part //Add the fired stimulus to the Perceived STM(). //FireTheBinon will set the XQ count and the PerceivedBinon. //FireTheBinon(PercptLvl, TheBinon&, TQCnt, XQCnt) FireTheBinon(TgtLvl, ResultBinon.get(), TQCount, 1); //will set the XQ count } } //End if they overlap properly } //End if they are both familiar } else //Else the fired one is Nullobject { Stop(); //It should not be possible for fired one to be NullObject ' } //End if the goal binon exists } else //Else the trigger is NullObject { Stop(); //It should be not NullObject - already checked in ProcessSTMLevel() } //End if the trigger binon exists } //End of CreateCombo() public final void ReportObjects1() { //Report information after perception and attention - before practice //Reports only the objects perceived in BinonDisplay.ChngResults String Res; String Ptrn; int ExprObj; // -------------------------- Status of perception before attending to the stimuli -------------- if (Processing50) { return; } World.appendBinonDisplayChngResults("\r\n" + " # EObj Pattern - Fired Binon List" + "\r\n"); Res = ""; for (var J = 1; J <= HighestPerceptLvl; J++) { ping(); ExprObj = STM[J][BinId][Current]; if (ExprObj != NullObject) { Ptrn = ""; if (ExprObj == PerceivedBinon) //If we have an expected binon at this level then { Ptrn += " This is the Perceived or Performed Binon"; } Res = Res + (" " + J).substring((" " + J).length() - 5) + vbToStr(Binons[ExprObj][TriggerCount]) + vbToStr(Binons[ExprObj][GoalCount]) + " " + DisplayPattern(ExprObj) + " " + Ptrn + "\r\n"; } } World.appendBinonDisplayChngResults(Res + "\r\n"); } //End ReportObjects1() public final void ReportObjects2() { //Report after Pass 2 - after prerceiving stimulus, doing response and expecting a stimulus //Reports on Objects in ObjList textbox StringBuilder Res2 = new StringBuilder(); var Rdgs = new Var<>(""); StringBuilder Res1; String Ptrn; String IntInfo; var VL = new Var<>(""); var Ty1 = new Var<>(""); var Ty2 = new Var<>(""); //unused String BN = null; //unused String Brand = null; int BnTyp; int Objct; var BinTyp = new Var<>(""); int ObjLvl; //unused int Prcpt; int TypInteger; String Inf = null; // -------------------- The binon list after being processed ------------ if (Processing50) { return; } //Fill in Binon list in BinonDisplay.ObjList.Text int NumChr; for (BnTyp = 1; BnTyp <= NumBinonTypes; BnTyp++) //Property binons and Percept combinations, Perceptual sequences and Responses { ping(); GetTypeInfo(BnTyp, BinTyp, Rdgs); //Rdgs$ = abbreviation - not used - use BinTyp$ only Res2.append(BnTyp).append(", ").append(Rdgs).append(BinTyp).append("\r\n"); for (ObjLvl = 1; ObjLvl <= MaxLevels; ObjLvl++) //For each level of binons { ping(); Res1 = new StringBuilder(); for (Objct = 1; Objct <= NumBinons; Objct++) //For all binons { ping(); Ptrn = ""; if (Binons[Objct][OLv] == ObjLvl) //if have a binon at this level then { if (BinonTypeOf(Objct) == BnTyp) { Inf = ""; VL.set(""); GetValue(Objct, VL); NumChr = 5 + 6 * (Binons[Objct][OLv] - 1); //Level 2 is 11 characters, level 3 is 17 characters Ptrn = substring(VL.get(), 0, NumChr); //display 14 chars of pattern if ((Ptrn == null ? 0 : Ptrn.length()) == 1) { Ptrn = " " + Ptrn; } TypInteger = BinonTypeOf(Binons[Objct][O1]); GetTypeInfo(TypInteger, Ty1, Ty1); TypInteger = BinonTypeOf(Binons[Objct][O2]); GetTypeInfo(TypInteger, Ty2, Ty2); IntInfo = InterestSymbol(Objct); Res1.append(substring(" " + Objct, (" " + Objct).length() - 3)) .append(substring((" " + Binons[Objct][OLv]), (" " + Binons[Objct][OLv]).length() - 3)) .append(AESR(Objct)).append(" ") .append(substring(Ty1.get(), 0, 2)) .append(substring(" " + Binons[Objct][O1], (" " + Binons[Objct][O1]).length() - 3)) .append(" ").append(substring(Ty2.get(), 0, 2)) .append(substring(" " + Binons[Objct][O2], (" " + Binons[Objct][O2]).length() - 3)) .append(substring(" " + Binons[Objct][IDL], (" " + Binons[Objct][IDL]).length() - 4)) .append(takeLast(2, vbToStr(Binons[Objct][TriggerCount]))) .append(takeLast(2, vbToStr(Binons[Objct][GoalCount]))) .append(substring(" " + IntInfo, (" " + IntInfo).length() - 3)) .append(substring(" " + Binons[Objct][TQ], (" " + Binons[Objct][TQ]).length() - 3)) .append(substring(" " + Binons[Objct][GQ], (" " + Binons[Objct][GQ]).length() - 3)) //.append("*X*") .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"); } World.setBinonDisplayObjList(Res2.toString()); //value set above } //End of ReportObjects2() public final String AESR(int Objct) { String tempAESR; if (BinonTypeOf(Objct) <= NumPercepts) //AE property is 0 for parallel binons { tempAESR = " P"; //Level 1 Percept or property binon } else { tempAESR = " A"; //level 1 Response binon = LetrBin } if (Binons[Objct][AE] == Action) //AE not assigned for level 1 Stimuli or Responses { if (!isSorR(Objct)) //two letters refer to types/roles of source binons { tempAESR = " A"; //Action binon } else { tempAESR = " AA"; //Action sequence } } else if (Binons[Objct][AE] == Attention) { if (!isSorR(Objct)) { tempAESR = " E"; //Expectation binon } else { tempAESR = " PP"; //Perceptual sequence } } 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 Link = Binons[ObjBin][TriggerList]; //does the binon trigger at least one target binon while (Link != NullTarget) { ping(); //add target binon type and objID tempDisplayHabit.append("l").append(DisplayStimulu(Targets[Link][TargetBinon])); Link = Targets[Link][NLnk]; //go to the next one on the list if (Link != NullTarget) { tempDisplayHabit.append(", "); } } Link = Binons[ObjBin][GoalList]; //does the binon goal at least one target binon if (Link != NullObject && !StringHelper.isNullOrEmpty(tempDisplayHabit.toString())) { tempDisplayHabit.append(", "); } while (Link != NullTarget) { ping(); //add target binon type and objID tempDisplayHabit.append("r").append(DisplayStimulu(Targets[Link][TargetBinon])); Link = Targets[Link][NLnk]; //go to the next one on the list if (Link != NullTarget) { tempDisplayHabit.append(", "); } } return tempDisplayHabit.toString(); } //End of DisplayHabit() public final void DetermineResponse() //Called from PerceptionAction() { //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; var PracticingBinon = new Var<>(0); //The binon being practiced. Concentration Level is based upon it. 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 PracticingBinon.set(NullObject); //even after thinking then babble //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 FirstLink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(PerceivedBinon)); //The right target binon link - if any if (FirstLink != NullTarget) //If have a link to a recent right target Action binon then { PracticingBinon.set(Targets[FirstLink][TargetBinon]); //This must be an Action if (InterestIn(PracticingBinon.get()) > FAMILIAR) //If it is worth doing then { 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. Thinklink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(PracticingBinon.get())); //The right target binon link - if any //This will be an Perceptual sequence - but we need to go up one more level to the Action - if any if (Thinklink != NullTarget) //If there is a right target link to an associating binon then { ThinkBinon = Targets[Thinklink][TargetBinon]; Thinklink = FloatingPointToInteger.ToInt32(MostRecentTriggerTargetLink(ThinkBinon)); //The right target Action binon link - if any } 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 (Thinklink != NullTarget) //If there is a right target link to an associating binon then { ThinkBinon = Targets[Thinklink][TargetBinon]; //The Approach#1 Action or Approach#2 Expectation to practice if (InterestIn(ThinkBinon) > FAMILIAR) //if the next A- or Expectation is worth expecting then { //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 { PracticingBinon.set(NullObject); //do not do the practicing binon - it is familiar / learnt } //End if the next binon was worth doing } else //else there is no next possible stimulus - no associating Expectation so { PracticingBinon.set(NullObject); //do not do the practicing binon - it is familiar / learnt } //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 (PracticingBinon.get() == NullObject) //If the PracticingBinon is still a NullObject then { 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 (FirstLink == NullTarget) //If there is no associating binons for the perception { //so use the 1st device and its first symbolic or range response, PracticingBinon must be set DeviceNum = 1; //Letters = LetrBin OutType = Devices[DeviceNum][PropertyBinonType]; //Currently = Wheels for device #1 if (Devices[DeviceNum][SymbolicOrMagnitude] == Magnitude) //Use Range of values { 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 { String Letter = DeviceResponses[DeviceNum].substring(0, 1); //Will be a NoResp$ // 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 DoneBinon = Targets[FirstLink][TargetBinon]; //The Action most recently practiced at the next level up //GetDHabit returns the lowest level response binon in ResponseBinon GetDHabit(DoneBinon, ResponseBinon); //Get the level 1 most recent response done DeviceNum = BinonTypes[BinonTypeOf(ResponseBinon.get())][SensOrDevNum]; //the device number for this response type binon if (Devices[DeviceNum][SymbolicOrMagnitude] == Magnitude) //Use Range of values { ll = Devices[DeviceNum][LowerRangeLimit]; UL = Devices[DeviceNum][UpperRangeLimit]; if (Binons[ResponseBinon.get()][IDL] == NoResp) //If it is the no response then { NextResponse = ll; } else { NextResponse = Binons[ResponseBinon.get()][IDL] + 1; if (NextResponse > UL) //if off end of valid values then { NextResponse = ll; //wrap around to start again } } //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 (I = 1; I <= NumberOfResponses; I++) //go through the response string { ping(); if (Binons[ResponseBinon.get()][IDL] == asc(DeviceResponses[DeviceNum].substring(I - 1, I - 1 + 1))) { CurrentResponse = I; I = NumberOfResponses; //terminate the loop } } //Find the next non "z" entry UseResponse = CurrentResponse; HaveResponse = 0; //will be set to the next response entry position // 'A random response generator // While HaveResponse = 0 // UseResponse = Int(NumberOfResponses * Rnd + 1) 'generate a number between 1 and and NumberofResponses // ThisResponse$ = Mid$(DeviceResponses$(DeviceNum), UseResponse, 1) // 'if it is a response that can be done and not a repeat of the last one chosen then // If ThisResponse$ <> NoMoveOrTurn$ And UseResponse <> CurrentResponse Then // HaveResponse = UseResponse 'a non-zero value will terminate the loop // End If // Wend //Sequentially go through the available responses while (HaveResponse == 0) { ping(); UseResponse = UseResponse + 1; if (UseResponse > NumberOfResponses) //if off the end of the string then { UseResponse = 1; //start at the beginning again } ThisResponse = DeviceResponses[DeviceNum].substring(UseResponse - 1, UseResponse - 1 + 1); if (!ThisResponse.equals(NoMoveOrTurn)) //if it is a response that can be done then { HaveResponse = UseResponse; //a non-zero value will terminate the loop } } //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 (PracticingBinon.get() != NullObject) //If practicing then { World.appendBinonDisplayChngResults(" * Practicing " + DisplayPattern(PracticingBinon.get()) + Reason + "\r\n"); } else { Stop(); World.appendBinonDisplayChngResults(" * Not Practicing anything" + "\r\n"); } //If have no action to practice at this point then PerformAction() will respond with nothing ActivateAction(PracticingBinon.get()); //Perform the response and fire the binon to STM(1, Fired) //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 String[][] WP = new String[40 + 1][40 + 1]; //The positions of the world as appearing //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 (Sens = 1; Sens <= NumSenses; Sens++) //For each sense { ping(); if (Senses[Sens][SymbolicOrMagnitude] == Magnitude) { GetStimuli(Sens, Stimuli); //get the stimuli from body senses //Stimuli$ = Chr$(of the range to far wall) SensorValues[Sens][XQCnt][Fired] = 1; SensorValues[Sens][Valu][Fired] = asc(Stimuli.get()); //one character per sense INPUTS[LIN][Sens] = chr(SensorValues[Sens][Valu][Fired] + 48); //convert to "1" to "8" } else //Else Symbolic input { //Setup a motion sense if WheelsConfig.AddAWheelSensor = 1 is checked if (Sense[Sens].equals("Motion")) //If its name is the sense of motion then { SensorValues[Sens][XQCnt][Fired] = 1; SensorValues[Sens][Valu][Fired] = asc(Motion); } else //else it is some other symbolic sense { GetStimuli(Sens, Stimuli); //get the stimuli from body senses SensorValues[Sens][XQCnt][Fired] = 1; SensorValues[Sens][Valu][Fired] = asc(Stimuli.get()); //one character per sense } INPUTS[LIN][Sens] = chr(SensorValues[Sens][Valu][Fired]); } } } //End of BodyAssignStimuli() public final void BodyFunction2() //called from World.Go to perform a cycle { //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 BodyAssignStimuli(); //fills in the Values$() from the senses and //the Motion$ from last response if turned on PerceptionAction(SensorValues, DeviceValues); if (NumDevices > 1) { Stop(); } Resp = (char) DeviceValues[1][Valu]; Kn = Resp; switch (Resp) //Motion$ will be set by the World.Move routines { case NoResp: Motion = NoMove; //= Mid$(WheelMovement$, 1, 1) 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 TurnRght: //rotate right 90 degrees BodyPointing = BodyPointing + 1; if (BodyPointing == 4) { BodyPointing = 0; } Motion = WheelMovement.substring(5, 6); //a rotate always happens break; case TurnLft: //rotate left 90 dgrees BodyPointing = BodyPointing - 1; if (BodyPointing == -1) { BodyPointing = 3; } Motion = WheelMovement.substring(6, 7); //a rotate always happens break; case TurnArnd: //rotate around 180 degrees BodyPointing = BodyPointing + 2; if (BodyPointing == 4) { BodyPointing = 0; } if (BodyPointing == 5) { BodyPointing = 1; } Motion = WheelMovement.substring(7, 8); //a rotate always happens break; } //Case Resp$ //Orient body pointer on world view if wheels turn if (WheelsTurn) { switch (BodyPointing) //direction body is pointing, 0=East, 1=South, 2=West, 3=North { case East: World.PointEast(); // > break; case South: World.PointSouth(); // v 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 { World.PointUnder(); //"A" = Adaptron pointing North } OUTPUTS[LIN][1] = OUTPUTS[LIN][1] + Kn; //for HistoryDisplay of outputs World.Update_View(); //dump all the history and LTMem() //do this for each sense World.DisplayStimuliAndResponse(SensorValues, Resp); //fillin the World.VB() value } //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 (Sense[Sens]) //Based on the name of the sense { case "VisionD": //Looking down at cell - distance 1 cell away ReturnedStimuli.set(ReturnedStimuli.get() + (char) 1); break; case "VisionL": //looking left based on body direction 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 "VisionR": //looking right 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 "VisionF": //looking forward 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 "VisionB": //looking behind 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 (Senses[Sens][LowerRangeLimit] == asc(Wall)) //If vision just looking at next square then { switch (Sense[Sens]) //Based on the name of the sense { case "VisionD": //Looking down at cell floor ReturnedStimuli.set(Wall); break; case "VisionL": //looking left based on body direction 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 "VisionR": //looking right 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 "VisionF": //looking forward 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 "VisionB": //looking behind 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 (!ReturnedStimuli.get().equals(Wall)) //if it's not a wall then the square is empty { ReturnedStimuli.set(EmptySquare); } } else //Else vision looking at symbolic location value in next square { switch (Sense[Sens]) //Based on the name of the sense { case "VisionD": //Looking down at cell ReturnedStimuli.set(ReturnedStimuli.get() + World.LookUnder()); break; case "VisionL": //looking left based on body direction 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 "VisionR": //looking right 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 "VisionF": //looking forward 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 "VisionB": //looking behind switch (BodyPointing) { case North: ReturnedStimuli.set(ReturnedStimuli.get() + World.LookSouth()); break; case East: ReturnedStimuli.set(ReturnedStimuli.get() + World.LookWest()); break; case South: ReturnedStimuli.set(ReturnedStimuli.get() + World.LookNorth()); break; case West: ReturnedStimuli.set(ReturnedStimuli.get() + World.LookEast()); break; } break; } } //end if its looking for wall or space or looking for square location letter } //end if sense is magnitude or symbolic } //End of GetStimuli() } } // end of Smarty static final class StringHelper { //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'Substring' when 'start' is a method // call or calculated value to ensure that 'start' is obtained just once. //------------------------------------------------------------------------------------ public static String substring(String string, int start, int length) { if (length < 0) throw new IndexOutOfBoundsException("Parameter length cannot be negative."); return string.substring(start, start + length); } //------------------------------------------------------------------------------------ // This method replaces the .NET static string method 'IsNullOrEmpty'. //------------------------------------------------------------------------------------ public static boolean isNullOrEmpty(String string) { return string == null || string.length() == 0; } //------------------------------------------------------------------------------------ // This method replaces the .NET static string method 'IsNullOrWhiteSpace'. //------------------------------------------------------------------------------------ public static boolean isNullOrWhiteSpace(String string) { if (string == null) return true; for (int index = 0; index < string.length(); index++) { ping(); if (!Character.isWhitespace(string.charAt(index))) return false; } return true; } //------------------------------------------------------------------------------------ // This method replaces the .NET static string method 'Join' (2 parameter version). //------------------------------------------------------------------------------------ public static String join(String separator, String[] stringArray) { if (stringArray == null) return null; else return join(separator, stringArray, 0, stringArray.length); } //------------------------------------------------------------------------------------ // This method replaces the .NET static string method 'Join' (4 parameter version). //------------------------------------------------------------------------------------ public static String join(String separator, String[] stringArray, int startIndex, int count) { if (stringArray == null) return null; StringBuilder sb = new StringBuilder(); for (int index = startIndex; index < stringArray.length && index - startIndex < count; index++) { ping(); if (separator != null && index > startIndex) sb.append(separator); if (stringArray[index] != null) sb.append(stringArray[index]); } return sb.toString(); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'Remove' (1 parameter version). //------------------------------------------------------------------------------------ public static String remove(String string, int start) { return string.substring(0, start); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'Remove' (2 parameter version). //------------------------------------------------------------------------------------ public static String remove(String string, int start, int count) { return string.substring(0, start) + string.substring(start + count); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'TrimEnd'. //------------------------------------------------------------------------------------ public static String trimEnd(String string, Character... charsToTrim) { if (string == null || charsToTrim == null) return string; int lengthToKeep = string.length(); for (int index = string.length() - 1; index >= 0; index--) { ping(); boolean removeChar = false; if (charsToTrim.length == 0) { if (Character.isWhitespace(string.charAt(index))) { lengthToKeep = index; removeChar = true; } } else { for (int trimCharIndex = 0; trimCharIndex < charsToTrim.length; trimCharIndex++) { ping(); if (string.charAt(index) == charsToTrim[trimCharIndex]) { lengthToKeep = index; removeChar = true; break; } } } if (!removeChar) break; } return string.substring(0, lengthToKeep); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'TrimStart'. //------------------------------------------------------------------------------------ public static String trimStart(String string, Character... charsToTrim) { if (string == null || charsToTrim == null) return string; int startingIndex = 0; for (int index = 0; index < string.length(); index++) { ping(); boolean removeChar = false; if (charsToTrim.length == 0) { if (Character.isWhitespace(string.charAt(index))) { startingIndex = index + 1; removeChar = true; } } else { for (int trimCharIndex = 0; trimCharIndex < charsToTrim.length; trimCharIndex++) { ping(); if (string.charAt(index) == charsToTrim[trimCharIndex]) { startingIndex = index + 1; removeChar = true; break; } } } if (!removeChar) break; } return string.substring(startingIndex); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'Trim' when arguments are used. //------------------------------------------------------------------------------------ public static String trim(String string, Character... charsToTrim) { return trimEnd(trimStart(string, charsToTrim), charsToTrim); } //------------------------------------------------------------------------------------ // This method is used for string equality comparisons when the option // 'Use helper 'stringsEqual' method to handle null strings' is selected // (The Java String 'equals' method can't be called on a null instance). //------------------------------------------------------------------------------------ public static boolean stringsEqual(String s1, String s2) { if (s1 == null && s2 == null) return true; else return s1 != null && s1.equals(s2); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'PadRight' (1 parameter version). //------------------------------------------------------------------------------------ public static String padRight(String string, int totalWidth) { return padRight(string, totalWidth, ' '); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'PadRight' (2 parameter version). //------------------------------------------------------------------------------------ public static String padRight(String string, int totalWidth, char paddingChar) { StringBuilder sb = new StringBuilder(string); while (sb.length() < totalWidth) { ping(); sb.append(paddingChar); } return sb.toString(); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'PadLeft' (1 parameter version). //------------------------------------------------------------------------------------ public static String padLeft(String string, int totalWidth) { return padLeft(string, totalWidth, ' '); } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'PadLeft' (2 parameter version). //------------------------------------------------------------------------------------ public static String padLeft(String string, int totalWidth, char paddingChar) { StringBuilder sb = new StringBuilder(); while (sb.length() + string.length() < totalWidth) { ping(); sb.append(paddingChar); } sb.append(string); return sb.toString(); } //------------------------------------------------------------------------------------ // This method replaces the .NET string constructor which repeats a character. //------------------------------------------------------------------------------------ public static String repeatChar(char charToRepeat, int count) { String newString = ""; for (int i = 1; i <= count; i++) { ping(); newString += charToRepeat; } return newString; } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'LastIndexOf' (char version). //------------------------------------------------------------------------------------ public static int lastIndexOf(String string, char value, int startIndex, int count) { int leftMost = startIndex + 1 - count; int rightMost = startIndex + 1; String substring = string.substring(leftMost, rightMost); int lastIndexInSubstring = substring.lastIndexOf(value); if (lastIndexInSubstring < 0) return -1; else return lastIndexInSubstring + leftMost; } //------------------------------------------------------------------------------------ // This method replaces the .NET string method 'LastIndexOf' (string version). //------------------------------------------------------------------------------------ public static int lastIndexOf(String string, String value, int startIndex, int count) { int leftMost = startIndex + 1 - count; int rightMost = startIndex + 1; String substring = string.substring(leftMost, rightMost); int lastIndexInSubstring = substring.lastIndexOf(value); if (lastIndexInSubstring < 0) return -1; else return lastIndexInSubstring + leftMost; } } static final class FloatingPointToInteger { public static byte ToSByte(double source) { byte floor = (byte) Math.floor(source); if (Math.abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (byte) Math.ceil(source); } else if (Math.abs(source - floor) < 0.5) return floor; else return (byte) Math.ceil(source); } public static short ToInt16(double source) { short floor = (short) Math.floor(source); if (Math.abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (short) Math.ceil(source); } else if (Math.abs(source - floor) < 0.5) return floor; else return (short) Math.ceil(source); } public static int ToInt32(double source) { int floor = (int) Math.floor(source); if (Math.abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (int) Math.ceil(source); } else if (Math.abs(source - floor) < 0.5) return floor; else return (int) Math.ceil(source); } public static long ToInt64(double source) { long floor = (long) Math.floor(source); if (Math.abs(source - floor) == 0.5) { if (floor % 2 == 0) return floor; else return (long) Math.ceil(source); } else if (Math.abs(source - floor) < 0.5) return floor; else return (long) Math.ceil(source); } } 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(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(); } static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible 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 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); } //sbool ping_actions_shareable = true; static volatile boolean ping_pauseAll = false; static int ping_sleep = 100; // poll pauseAll flag every 100 static volatile boolean ping_anyActions = false; static Map ping_actions = newWeakHashMap(); static ThreadLocal ping_isCleanUpThread = new ThreadLocal(); // always returns true static boolean ping() { if (ping_pauseAll || ping_anyActions) ping_impl(true /* XXX */); //ifndef LeanMode ping_impl(); endifndef return true; } // returns true when it slept static boolean ping_impl(boolean okInCleanUp) { try { if (ping_pauseAll && !isAWTThread()) { do Thread.sleep(ping_sleep); while (ping_pauseAll); return true; } if (ping_anyActions) { // don't allow sharing ping_actions if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get())) failIfUnlicensed(); Object action = null; synchronized(ping_actions) { if (!ping_actions.isEmpty()) { action = ping_actions.get(currentThread()); if (action instanceof Runnable) ping_actions.remove(currentThread()); if (ping_actions.isEmpty()) ping_anyActions = false; } } if (action instanceof Runnable) ((Runnable) action).run(); else if (eq(action, "cancelled")) throw fail("Thread cancelled."); } return false; } catch (Exception __e) { throw rethrow(__e); } } static String vbToStr(long l) { return l < 0 ? str(l) : " " + l; } // Use like this: printVars_str(+x, +y); // Or: printVars("bla", +x); // Or: printVars bla(+x); static void printVars_str(Object... params) { String s = ""; if (odd(l(params))) { s = str(first(params)); if (endsWithLetterOrDigit(s)) s += ": "; params = dropFirst(params); } print(s + renderVars_str(params)); } static 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 (o instanceof ThreadLocal) // TODO: remove this return isTrue(((ThreadLocal) o).get()); throw fail(getClassName(o)); } static boolean isTrue(Boolean b) { return b != null && b.booleanValue(); } static boolean empty(Collection c) { return c == null || c.isEmpty(); } static boolean empty(Iterable c) { return c == null || !c.iterator().hasNext(); } static boolean empty(CharSequence s) { return s == null || s.length() == 0; } static boolean empty(Map map) { return map == null || map.isEmpty(); } static boolean empty(Object[] o) { return o == null || o.length == 0; } static boolean empty(Object o) { if (o instanceof Collection) return empty((Collection) o); if (o instanceof String) return empty((String) o); if (o instanceof Map) return empty((Map) o); if (o instanceof Object[]) return empty((Object[]) o); if (o instanceof byte[]) return empty((byte[]) o); if (o == null) return true; throw fail("unknown type for 'empty': " + getType(o)); } static boolean empty(Iterator i) { return i == null || !i.hasNext(); } static boolean empty(double[] a) { return a == null || a.length == 0; } static boolean empty(float[] a) { return a == null || a.length == 0; } static boolean empty(int[] a) { return a == null || a.length == 0; } static boolean empty(long[] a) { return a == null || a.length == 0; } static boolean empty(byte[] a) { return a == null || a.length == 0; } static boolean empty(short[] a) { return a == null || a.length == 0; } static boolean empty(File f) { return getFileSize(f) == 0; } static RuntimeException fail() { throw new RuntimeException("fail"); } static RuntimeException fail(Throwable e) { throw asRuntimeException(e); } static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); } static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); } static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); } static List takeLast(List l, int n) { return newSubList(l, l(l)-n); } static List takeLast(int n, List l) { return takeLast(l, n); } static String takeLast(int n, String s) { return substring(s, l(s)-n); } static String takeLast(String s, int n) { return substring(s, l(s)-n); } static int iteratorCount_int_close(Iterator i) { try { int n = 0; if (i != null) while (i.hasNext()) { i.next(); ++n; } if (i instanceof AutoCloseable) ((AutoCloseable) i).close(); return n; } catch (Exception __e) { throw rethrow(__e); } } static Object call(Object o) { return callF(o); } // varargs assignment fixer for a single string array argument static Object call(Object o, String method, String[] arg) { return call(o, method, new Object[] {arg}); } static Object call(Object o, String method, Object... args) { //ret call_cached(o, method, args); return call_withVarargs(o, method, args); } static String repeat(char c, int n) { n = Math.max(n, 0); char[] chars = new char[n]; for (int i = 0; i < n; i++) chars[i] = c; return new String(chars); } static List repeat(A a, int n) { n = Math.max(n, 0); List l = new ArrayList(n); for (int i = 0; i < n; i++) l.add(a); return l; } static List repeat(int n, A a) { return repeat(a, n); } static Map newWeakHashMap() { return _registerWeakMap(synchroMap(new WeakHashMap())); } // TODO: test if android complains about this static boolean isAWTThread() { if (isAndroid()) return false; if (isHeadless()) return false; return isAWTThread_awt(); } static boolean isAWTThread_awt() { return SwingUtilities.isEventDispatchThread(); } static void failIfUnlicensed() { assertTrue("license off", licensed()); } static Thread currentThread() { return Thread.currentThread(); } static RuntimeException rethrow(Throwable t) { if (t instanceof Error) _handleError((Error) t); throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static RuntimeException rethrow(String msg, Throwable t) { throw new RuntimeException(msg, t); } static boolean odd(int i) { return (i & 1) != 0; } static boolean odd(long i) { return (i & 1) != 0; } static boolean odd(BigInteger i) { return odd(toInt(i)); } static boolean endsWithLetterOrDigit(String s) { return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length()-1)); } static String[] dropFirst(int n, String[] a) { return drop(n, a); } static String[] dropFirst(String[] a) { return drop(1, a); } static Object[] dropFirst(Object[] a) { return drop(1, a); } static List dropFirst(List l) { return dropFirst(1, l); } static List dropFirst(int n, Iterable i) { return dropFirst(n, toList(i)); } static List dropFirst(Iterable i) { return dropFirst(toList(i)); } static List dropFirst(int n, List l) { return n <= 0 ? l : new ArrayList(l.subList(Math.min(n, l.size()), l.size())); } static List dropFirst(List l, int n) { return dropFirst(n, l); } static String dropFirst(int n, String s) { return substring(s, n); } static String dropFirst(String s, int n) { return substring(s, n); } static String dropFirst(String s) { return substring(s, 1); } static volatile StringBuffer local_log = new StringBuffer(); // not redirected static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot // in bytes - will cut to half that static volatile int print_log_max = 1024*1024; static volatile int local_log_max = 100*1024; static boolean print_silent = false; // total mute if set static Object print_byThread_lock = new Object(); static volatile ThreadLocal print_byThread; // special handling by thread - prefers F1 static volatile Object print_allThreads; static volatile Object print_preprocess; static void print() { print(""); } static A print(String s, A o) { print((endsWithLetterOrDigit(s) ? s + ": " : s) + o); return o; } // slightly overblown signature to return original object... static A print(A o) { ping_okInCleanUp(); if (print_silent) return o; String s = o + "\n"; print_noNewLine(s); return o; } static void print_noNewLine(String s) { try { Object f = getThreadLocal(print_byThread_dontCreate()); if (f == null) f = print_allThreads; if (f != null) // We do need the general callF machinery here as print_byThread is sometimes shared between modules if (isFalse( f instanceof F1 ? ((F1) f).get(s) : callF(f, s))) return; } catch (Throwable e) { System.out.println(getStackTrace(e)); } print_raw(s); } static void print_raw(String s) { if (print_preprocess != null) s = (String) callF(print_preprocess, s); s = fixNewLines(s); Appendable loc = local_log; Appendable buf = print_log; int loc_max = print_log_max; if (buf != loc && buf != null) { print_append(buf, s, print_log_max); loc_max = local_log_max; } if (loc != null) print_append(loc, s, loc_max); System.out.print(s); vmBus_send("printed",mc(), s); } static void print_autoRotate() { } // Use like this: renderVars(+x, +y) static String renderVars_str(Object... params) { List l = new ArrayList(); for (int i = 0; i+1 < l(params); i += 2) l.add(params[i] + "=" + params[i+1]); return trim(joinWithComma(l)); } static String spliceString(String a, int from, int to, String b) { return substring(a, 0, from) + b + substring(a, Math.max(from, to)); } static String spliceString(String a, int from, int to, char b) { return spliceString(a, from, to, str(b)); } static String getClassName(Object o) { return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName(); } static String getType(Object o) { return getClassName(o); } static long getFileSize(String path) { return path == null ? 0 : new File(path).length(); } static long getFileSize(File f) { return f == null ? 0 : f.length(); } static RuntimeException asRuntimeException(Throwable t) { if (t instanceof Error) _handleError((Error) t); return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static List newSubList(List l, int startIndex, int endIndex) { return cloneList(subList(l, startIndex, endIndex)); } static List newSubList(List l, int startIndex) { return cloneList(subList(l, startIndex)); } static AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) { return print_byThread().get() == null ? tempInterceptPrint(f) : null; } static Map> callF_cache = newDangerousWeakHashMap(); static B callF(F1 f, A a) { return f == null ? null : f.get(a); } static A callF(IF0 f) { return f == null ? null : f.get(); } static B callF(IF1 f, A a) { return f == null ? null : f.get(a); } static void callF(VF1 f, A a) { if (f != null) f.get(a); } static Object callF(Object f, Object... args) { if (f instanceof String) return callMCWithVarArgs((String) f, args); // possible SLOWDOWN over callMC return safeCallF(f, args); } static Object safeCallF(Object f, Object... args) { if (f instanceof Runnable) { ((Runnable) f).run(); return null; } if (f == null) return null; Class c = f.getClass(); ArrayList methods; synchronized(callF_cache) { methods = callF_cache.get(c); if (methods == null) methods = callF_makeCache(c); } int n = l(methods); if (n == 0) { throw fail("No get method in " + getClassName(c)); } if (n == 1) return invokeMethod(methods.get(0), f, args); for (int i = 0; i < n; i++) { Method m = methods.get(i); if (call_checkArgs(m, args, false)) return invokeMethod(m, f, args); } throw fail("No matching get method in " + getClassName(c)); } // used internally static ArrayList callF_makeCache(Class c) { ArrayList l = new ArrayList(); Class _c = c; do { for (Method m : _c.getDeclaredMethods()) if (m.getName().equals("get")) { makeAccessible(m); l.add(m); } if (!l.isEmpty()) break; _c = _c.getSuperclass(); } while (_c != null); callF_cache.put(c, l); return l; } static Object call_withVarargs(Object o, String method, Object... args) { try { if (o == null) return null; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); Method me = cache.findStaticMethod(method, args); if (me != null) return invokeMethod(me, null, args); // try varargs List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } { if (!(isStaticMethod(m))) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return invokeMethod(m, null, newArgs); } throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found"); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(method, args); if (me != null) return invokeMethod(me, o, args); // try varargs List methods = cache.cache.get(method); if (methods != null) methodSearch: for (Method m : methods) { { if (!(m.isVarArgs())) continue; } Object[] newArgs = massageArgsForVarArgsCall(m, args); if (newArgs != null) return invokeMethod(m, o, newArgs); } throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found"); } } catch (Exception __e) { throw rethrow(__e); } } static List _registerWeakMap_preList; static A _registerWeakMap(A map) { if (javax() == null) { // We're in class init if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList(); _registerWeakMap_preList.add(map); return map; } try { call(javax(), "_registerWeakMap", map); } catch (Throwable e) { printException(e); print("Upgrade JavaX!!"); } return map; } static void _onLoad_registerWeakMap() { assertNotNull(javax()); if (_registerWeakMap_preList == null) return; for (Object o : _registerWeakMap_preList) _registerWeakMap(o); _registerWeakMap_preList = null; } static Map synchroMap() { return synchroHashMap(); } static Map synchroMap(Map map) { return Collections.synchronizedMap(map); } static int isAndroid_flag; static boolean isAndroid() { if (isAndroid_flag == 0) isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1; return isAndroid_flag > 0; } static Boolean isHeadless_cache; static boolean isHeadless() { if (isHeadless_cache != null) return isHeadless_cache; if (isAndroid()) return isHeadless_cache = true; if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true; // Also check if AWT actually works. // If DISPLAY variable is set but no X server up, this will notice. try { SwingUtilities.isEventDispatchThread(); return isHeadless_cache = false; } catch (Throwable e) { return isHeadless_cache = true; } } static void assertTrue(Object o) { if (!(eq(o, true) /*|| isTrue(pcallF(o))*/)) throw fail(str(o)); } static boolean assertTrue(String msg, boolean b) { if (!b) throw fail(msg); return b; } static boolean assertTrue(boolean b) { if (!b) throw fail("oops"); return b; } static volatile boolean licensed_yes = true; static boolean licensed() { if (!licensed_yes) return false; ping_okInCleanUp(); return true; } static void licensed_off() { licensed_yes = false; } static void _handleError(Error e) { call(javax(), "_handleError", e); } static int toInt(Object o) { if (o == null) return 0; if (o instanceof Number) return ((Number) o).intValue(); if (o instanceof String) return parseInt(((String) o)); if (o instanceof Boolean) return boolToInt(((Boolean) o)); throw fail("woot not int: " + getClassName(o)); } static int toInt(long l) { if (l != (int) l) throw fail("Too large for int: " + l); return (int) l; } static String[] drop(int n, String[] a) { n = Math.min(n, a.length); String[] b = new String[a.length-n]; System.arraycopy(a, n, b, 0, b.length); return b; } static Object[] drop(int n, Object[] a) { n = Math.min(n, a.length); Object[] b = new Object[a.length-n]; System.arraycopy(a, n, b, 0, b.length); return b; } static ArrayList toList(A[] a) { return asList(a); } static ArrayList toList(int[] a) { return asList(a); } static ArrayList toList(Set s) { return asList(s); } static ArrayList toList(Iterable s) { return asList(s); } static void ping_okInCleanUp() { if (ping_pauseAll || ping_anyActions) ping_impl(true); } // this syntax should be removed... static Object getThreadLocal(Object o, String name) { ThreadLocal t = (ThreadLocal) (getOpt(o, name)); return t != null ? t.get() : null; } static A getThreadLocal(ThreadLocal tl) { return tl == null ? null : tl.get(); } static A getThreadLocal(ThreadLocal tl, A defaultValue) { return or(getThreadLocal(tl), defaultValue); } static ThreadLocal print_byThread_dontCreate() { return print_byThread; } static boolean isFalse(Object o) { return eq(false, o); } static String getStackTrace(Throwable throwable) { lastException(throwable); return getStackTrace_noRecord(throwable); } static String getStackTrace_noRecord(Throwable throwable) { StringWriter writer = new StringWriter(); throwable.printStackTrace(new PrintWriter(writer)); return hideCredentials(writer.toString()); } static String getStackTrace() { return getStackTrace_noRecord(new Throwable()); } static String fixNewLines(String s) { int i = indexOf(s, '\r'); if (i < 0) return s; int l = s.length(); StringBuilder out = new StringBuilder(l); out.append(s, 0, i); for (; i < l; i++) { char c = s.charAt(i); if (c != '\r') out.append(c); else { out.append('\n'); if (i+1 < l && s.charAt(i+1) == '\n') ++i; } } return out.toString(); } static void print_append(Appendable buf, String s, int max) { try { synchronized(buf) { buf.append(s); if (buf instanceof StringBuffer) rotateStringBuffer(((StringBuffer) buf), max); else if (buf instanceof StringBuilder) rotateStringBuilder(((StringBuilder) buf), max); } } catch (Exception __e) { throw rethrow(__e); } } static void vmBus_send(String msg, Object... args) { Object arg = vmBus_wrapArgs(args); pcallFAll(vm_busListeners_live(), msg, arg); pcallFAll(vm_busListenersByMessage_live().get(msg), msg, arg); } static void vmBus_send(String msg) { vmBus_send(msg, (Object) null); } static Class mc() { return main.class; } static String joinWithComma(Collection c) { return join(", ", c); } static String joinWithComma(String... c) { return join(", ", c); } static String joinWithComma(Pair p) { return p == null ? "" : joinWithComma(str(p.a), str(p.b)); } static ArrayList cloneList(Iterable l) { return l instanceof Collection ? cloneList((Collection) l) : asList(l); } static ArrayList cloneList(Collection l) { if (l == null) return new ArrayList(); synchronized(collectionMutex(l)) { return new ArrayList(l); } } static List subList(List l, int startIndex) { return subList(l, startIndex, l(l)); } static List subList(int startIndex, int endIndex, List l) { return subList(l, startIndex, endIndex); } static List subList(List l, int startIndex, int endIndex) { if (l == null) return null; int n = l(l); startIndex = Math.max(0, startIndex); endIndex = Math.min(n, endIndex); if (startIndex >= endIndex) return ll(); if (startIndex == 0 && endIndex == n) return l; return l.subList(startIndex, endIndex); } static ThreadLocal print_byThread() { synchronized(print_byThread_lock) { if (print_byThread == null) print_byThread = new ThreadLocal(); } return print_byThread; } // f can return false to suppress regular printing // call print_raw within f to actually print something static AutoCloseable tempInterceptPrint(F1 f) { return tempSetThreadLocal(print_byThread(), f); } static Map newDangerousWeakHashMap() { return _registerDangerousWeakMap(synchroMap(new WeakHashMap())); } // initFunction: voidfunc(Map) - is called initially, and after clearing the map static Map newDangerousWeakHashMap(Object initFunction) { return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction); } static Object callMCWithVarArgs(String method, Object... args) { return call_withVarargs(mc(), method, args); } static Object invokeMethod(Method m, Object o, Object... args) { try { try { return m.invoke(o, args); } catch (InvocationTargetException e) { throw rethrow(getExceptionCause(e)); } catch (IllegalArgumentException e) { throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args))); } } catch (Exception __e) { throw rethrow(__e); } } static boolean call_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) print("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) { Object arg = args[i]; if (!(arg == null ? !types[i].isPrimitive() : isInstanceX(types[i], arg))) { if (debug) print("Bad parameter " + i + ": " + arg + " vs " + types[i]); return false; } } return true; } static Field makeAccessible(Field f) { try { f.setAccessible(true); } catch (Throwable e) { // Note: The error reporting only works with Java VM option --illegal-access=deny vmBus_send("makeAccessible_error",e, f); } return f; } static Method makeAccessible(Method m) { try { m.setAccessible(true); } catch (Throwable e) { vmBus_send("makeAccessible_error",e, m); } return m; } static Constructor makeAccessible(Constructor c) { try { c.setAccessible(true); } catch (Throwable e) { vmBus_send("makeAccessible_error",e, c); } return c; } static final Map callOpt_cache = newDangerousWeakHashMap(); static Object callOpt_cached(Object o, String methodName, Object... args) { try { if (o == null) return null; if (o instanceof Class) { Class c = (Class) o; _MethodCache cache = callOpt_getCache(c); // TODO: (super-rare) case where method exists static and non-static // with different args Method me = cache.findMethod(methodName, args); if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null; return invokeMethod(me, null, args); } else { Class c = o.getClass(); _MethodCache cache = callOpt_getCache(c); Method me = cache.findMethod(methodName, args); if (me == null) return null; return invokeMethod(me, o, args); } } catch (Exception __e) { throw rethrow(__e); } } static _MethodCache callOpt_getCache(Class c) { synchronized(callOpt_cache) { _MethodCache cache = callOpt_cache.get(c); if (cache == null) callOpt_cache.put(c, cache = new _MethodCache(c)); return cache; } } static boolean isStaticMethod(Method m) { return methodIsStatic(m); } static Object[] massageArgsForVarArgsCall(Method m, Object[] args) { Class[] types = m.getParameterTypes(); int n = types.length-1, nArgs = args.length; if (nArgs < n) return null; for (int i = 0; i < n; i++) if (!argumentCompatibleWithType(args[i], types[i])) return null; Class varArgType = types[n].getComponentType(); for (int i = n; i < nArgs; i++) if (!argumentCompatibleWithType(args[i], varArgType)) return null; Object[] newArgs = new Object[n+1]; arraycopy(args, 0, newArgs, 0, n); Object[] varArgs = arrayOfType(varArgType, nArgs-n); arraycopy(args, n, varArgs, 0, nArgs-n); newArgs[n] = varArgs; return newArgs; } static List classNames(Collection l) { return getClassNames(l); } static List classNames(Object[] l) { return getClassNames(Arrays.asList(l)); } static Class javax() { return getJavaX(); } static List synchroList() { return synchroList(new ArrayList()); } static List synchroList(List l) { return Collections.synchronizedList(l); } static A printException(A e) { printStackTrace(e); return e; } static A assertNotNull(A a) { assertTrue(a != null); return a; } static A assertNotNull(String msg, A a) { assertTrue(msg, a != null); return a; } static Map synchroHashMap() { return synchronizedMap(new HashMap()); } static int parseInt(String s) { return emptyString(s) ? 0 : Integer.parseInt(s); } static int parseInt(char c) { return Integer.parseInt(str(c)); } static int boolToInt(boolean b) { return b ? 1 : 0; } // unclear semantics as to whether return null on null static ArrayList asList(A[] a) { return a == null ? new ArrayList() : new ArrayList(Arrays.asList(a)); } static ArrayList asList(int[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (int i : a) l.add(i); return l; } static ArrayList asList(long[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (long i : a) l.add(i); return l; } static ArrayList asList(float[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (float i : a) l.add(i); return l; } static ArrayList asList(double[] a) { if (a == null) return null; ArrayList l = emptyList(a.length); for (double i : a) l.add(i); return l; } static ArrayList asList(Iterable s) { if (s instanceof ArrayList) return (ArrayList) s; ArrayList l = new ArrayList(); if (s != null) for (A a : s) l.add(a); return l; } static ArrayList asList(Enumeration e) { ArrayList l = new ArrayList(); if (e != null) while (e.hasMoreElements()) l.add(e.nextElement()); return l; } static Object getOpt(Object o, String field) { return getOpt_cached(o, field); } static Object getOpt(String field, Object o) { return getOpt_cached(o, field); } static Object getOpt_raw(Object o, String field) { try { Field f = getOpt_findField(o.getClass(), field); if (f == null) return null; makeAccessible(f); return f.get(o); } catch (Exception __e) { throw rethrow(__e); } } // access of static fields is not yet optimized static Object getOpt(Class c, String field) { try { if (c == null) return null; Field f = getOpt_findStaticField(c, field); if (f == null) return null; makeAccessible(f); return f.get(null); } catch (Exception __e) { throw rethrow(__e); } } static Field getOpt_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); return null; } static A or(A a, A b) { return a != null ? a : b; } // PersistableThrowable doesn't hold GC-disturbing class references in backtrace static volatile PersistableThrowable lastException_lastException; static PersistableThrowable lastException() { return lastException_lastException; } static void lastException(Throwable e) { lastException_lastException = persistableThrowable(e); } static String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); } static String hideCredentials(String url) { try { if (startsWithOneOf(url, "http://", "https://") && isAGIBlueDomain(hostNameFromURL(url))) return url; } catch (Throwable e) { print("HideCredentials", e); } return url.replaceAll("([&?])(_pass|key|cookie)=[^&\\s\"]*", "$1$2="); } static String hideCredentials(Object o) { return hideCredentials(str(o)); } static int indexOf(List l, A a, int startIndex) { if (l == null) return -1; int n = l(l); for (int i = startIndex; i < n; i++) if (eq(l.get(i), a)) return i; return -1; } static int indexOf(List l, int startIndex, A a) { return indexOf(l, a, startIndex); } static int indexOf(List l, A a) { if (l == null) return -1; return l.indexOf(a); } static int indexOf(String a, String b) { return a == null || b == null ? -1 : a.indexOf(b); } static int indexOf(String a, String b, int i) { return a == null || b == null ? -1 : a.indexOf(b, i); } static int indexOf(String a, char b) { return a == null ? -1 : a.indexOf(b); } static int indexOf(String a, int i, char b) { return indexOf(a, b, i); } static int indexOf(String a, char b, int i) { return a == null ? -1 : a.indexOf(b, i); } static int indexOf(String a, int i, String b) { return a == null || b == null ? -1 : a.indexOf(b, i); } static int indexOf(A[] x, A a) { int n = l(x); for (int i = 0; i < n; i++) if (eq(x[i], a)) return i; return -1; } static void rotateStringBuffer(StringBuffer buf, int max) { try { if (buf == null) return; synchronized(buf) { if (buf.length() <= max) return; try { int newLength = max/2; int ofs = buf.length()-newLength; String newString = buf.substring(ofs); buf.setLength(0); buf.append("[...] ").append(newString); } catch (Exception e) { buf.setLength(0); } buf.trimToSize(); } } catch (Exception __e) { throw rethrow(__e); } } static void rotateStringBuilder(StringBuilder buf, int max) { try { if (buf == null) return; synchronized(buf) { if (buf.length() <= max) return; try { int newLength = max/2; int ofs = buf.length()-newLength; String newString = buf.substring(ofs); buf.setLength(0); buf.append("[...] ").append(newString); } catch (Exception e) { buf.setLength(0); } buf.trimToSize(); } } catch (Exception __e) { throw rethrow(__e); } } static Object vmBus_wrapArgs(Object... args) { return empty(args) ? null : l(args) == 1 ? args[0] : args; } static void pcallFAll(Collection l, Object... args) { if (l != null) for (Object f : cloneList(l)) pcallF(f, args); } static void pcallFAll(Iterator it, Object... args) { while (it.hasNext()) pcallF(it.next(), args); } static Set vm_busListeners_live_cache; static Set vm_busListeners_live() { if (vm_busListeners_live_cache == null) vm_busListeners_live_cache = vm_busListeners_live_load(); return vm_busListeners_live_cache; } static Set vm_busListeners_live_load() { return vm_generalIdentityHashSet("busListeners"); } static Map vm_busListenersByMessage_live_cache; static Map vm_busListenersByMessage_live() { if (vm_busListenersByMessage_live_cache == null) vm_busListenersByMessage_live_cache = vm_busListenersByMessage_live_load(); return vm_busListenersByMessage_live_cache; } static Map vm_busListenersByMessage_live_load() { return vm_generalHashMap("busListenersByMessage"); } static Object collectionMutex(List l) { return l; } static Object collectionMutex(Object o) { if (o instanceof List) return o; String c = className(o); if (eq(c, "java.util.TreeMap$KeySet")) c = className(o = getOpt(o, "m")); else if (eq(c, "java.util.HashMap$KeySet")) c = className(o = get_raw(o, "this$0")); if (eqOneOf(c, "java.util.TreeMap$AscendingSubMap", "java.util.TreeMap$DescendingSubMap")) c = className(o = get_raw(o, "m")); return o; } static List ll(A... a) { ArrayList l = new ArrayList(a.length); if (a != null) for (A x : a) l.add(x); return l; } static AutoCloseable tempSetThreadLocal(final ThreadLocal tl, A a) { if (tl == null) return null; final A prev = setThreadLocal(tl, a); return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); }}; } static List _registerDangerousWeakMap_preList; static A _registerDangerousWeakMap(A map) { return _registerDangerousWeakMap(map, null); } static A _registerDangerousWeakMap(A map, Object init) { callF(init, map); if (init instanceof String) { final String f = (String) init; init = new VF1() { public void get(Map map) { try { callMC(f, map) ; } catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "callMC(f, map)"; }}; } if (javax() == null) { // We're in class init if (_registerDangerousWeakMap_preList == null) _registerDangerousWeakMap_preList = synchroList(); _registerDangerousWeakMap_preList.add(pair(map, init)); return map; } call(javax(), "_registerDangerousWeakMap", map, init); return map; } static void _onLoad_registerDangerousWeakMap() { assertNotNull(javax()); if (_registerDangerousWeakMap_preList == null) return; for (Pair p : _registerDangerousWeakMap_preList) _registerDangerousWeakMap(p.a, p.b); _registerDangerousWeakMap_preList = null; } static Throwable getExceptionCause(Throwable e) { Throwable c = e.getCause(); return c != null ? c : e; } static String joinWithSpace(Iterable c) { return join(" ", c); } static String joinWithSpace(String... c) { return join(" ", c); } static boolean isInstanceX(Class type, Object arg) { if (type == boolean.class) return arg instanceof Boolean; if (type == int.class) return arg instanceof Integer; if (type == long.class) return arg instanceof Long; if (type == float.class) return arg instanceof Float; if (type == short.class) return arg instanceof Short; if (type == char.class) return arg instanceof Character; if (type == byte.class) return arg instanceof Byte; if (type == double.class) return arg instanceof Double; return type.isInstance(arg); } static boolean methodIsStatic(Method m) { return (m.getModifiers() & Modifier.STATIC) != 0; } static boolean argumentCompatibleWithType(Object arg, Class type) { return arg == null ? !type.isPrimitive() : isInstanceX(type, arg); } static void arraycopy(Object[] a, Object[] b) { if (a != null && b != null) arraycopy(a, 0, b, 0, Math.min(a.length, b.length)); } static void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) { if (n != 0) System.arraycopy(src, srcPos, dest, destPos, n); } static A[] arrayOfType(Class type, int n) { return makeArray(type, n); } static A[] arrayOfType(int n, Class type) { return arrayOfType(type, n); } static List getClassNames(Collection l) { List out = new ArrayList(); if (l != null) for (Object o : l) out.add(o == null ? null : getClassName(o)); return out; } static Class __javax; static Class getJavaX() { try { return __javax; } catch (Exception __e) { throw rethrow(__e); } } static A printStackTrace(A e) { // we go to system.out now - system.err is nonsense print(getStackTrace(e)); return e; } static void printStackTrace() { printStackTrace(new Throwable()); } static void printStackTrace(String msg) { printStackTrace(new Throwable(msg)); } static void printStackTrace(String msg, Throwable e) { printStackTrace(new Throwable(msg, e)); } static Map synchronizedMap() { return synchroMap(); } static Map synchronizedMap(Map map) { return synchroMap(map); } static boolean emptyString(String s) { return s == null || s.length() == 0; } static ArrayList emptyList() { return new ArrayList(); //ret Collections.emptyList(); } static ArrayList emptyList(int capacity) { return new ArrayList(max(0, capacity)); } // Try to match capacity static ArrayList emptyList(Iterable l) { return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList(); } static ArrayList emptyList(Object[] l) { return emptyList(l(l)); } // get correct type at once static ArrayList emptyList(Class c) { return new ArrayList(); } //static final Map> getOpt_cache = newDangerousWeakHashMap(f getOpt_special_init); static class getOpt_Map extends WeakHashMap { getOpt_Map() { if (getOpt_special == null) getOpt_special = new HashMap(); clear(); } public void clear() { super.clear(); //print("getOpt clear"); put(Class.class, getOpt_special); put(String.class, getOpt_special); } } static final Map> getOpt_cache = _registerDangerousWeakMap(synchroMap(new getOpt_Map())); //static final Map> getOpt_cache = _registerWeakMap(synchroMap(new getOpt_Map)); static HashMap getOpt_special; // just a marker /*static void getOpt_special_init(Map map) { map.put(Class.class, getOpt_special); map.put(S.class, getOpt_special); }*/ static Object getOpt_cached(Object o, String field) { try { if (o == null) return null; Class c = o.getClass(); HashMap map; synchronized(getOpt_cache) { map = getOpt_cache.get(c); if (map == null) map = getOpt_makeCache(c); } if (map == getOpt_special) { if (o instanceof Class) return getOpt((Class) o, field); /*if (o instanceof S) ret getOpt(getBot((S) o), field);*/ if (o instanceof Map) return ((Map) o).get(field); } Field f = map.get(field); if (f != null) return f.get(o); return null; } catch (Exception __e) { throw rethrow(__e); } } // used internally - we are in synchronized block static HashMap getOpt_makeCache(Class c) { HashMap map; if (isSubtypeOf(c, Map.class)) map = getOpt_special; else { map = new HashMap(); if (!reflection_classesNotToScan().contains(c.getName())) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) { makeAccessible(f); String name = f.getName(); if (!map.containsKey(name)) map.put(name, f); } _c = _c.getSuperclass(); } while (_c != null); } } if (getOpt_cache != null) getOpt_cache.put(c, map); return map; } static Field getOpt_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); return null; } static PersistableThrowable persistableThrowable(Throwable e) { return e == null ? null : new PersistableThrowable(e); } static boolean startsWithOneOf(String s, String... l) { for (String x : l) if (startsWith(s, x)) return true; return false; } static boolean startsWithOneOf(String s, Matches m, String... l) { for (String x : l) if (startsWith(s, x, m)) return true; return false; } static boolean isAGIBlueDomain(String domain) { return domainIsUnder(domain, theAGIBlueDomain()); } static String hostNameFromURL(String url) { try { return new URL(url).getHost(); } catch (Exception __e) { throw rethrow(__e); } } static Object pcallF(Object f, Object... args) { return pcallFunction(f, args); } static B pcallF(F1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { return null; } } static void pcallF(VF1 f, A a) { try { { if (f != null) f.get(a); } } catch (Throwable __e) { _handleException(__e); } } static B pcallF(IF1 f, A a) { try { return f == null ? null : f.get(a); } catch (Throwable __e) { return null; } } static Set vm_generalIdentityHashSet(Object name) { synchronized(get(javax(), "generalMap")) { Set set = (Set) (vm_generalMap_get(name)); if (set == null) vm_generalMap_put(name, set = syncIdentityHashSet()); return set; } } static Map vm_generalHashMap(Object name) { synchronized(get(javax(), "generalMap")) { Map m = (Map) (vm_generalMap_get(name)); if (m == null) vm_generalMap_put(name, m = syncHashMap()); return m; } } static String className(Object o) { return getClassName(o); } // get purpose 1: access a list/array/map (safer version of x.get(y)) static A get(List l, int idx) { return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null; } // seems to conflict with other signatures /*static B get(Map map, A key) { ret map != null ? map.get(key) : null; }*/ static A get(A[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : null; } // default to false static boolean get(boolean[] l, int idx) { return idx >= 0 && idx < l(l) ? l[idx] : false; } // get purpose 2: access a field by reflection or a map static Object get(Object o, String field) { try { if (o == null) return null; if (o instanceof Class) return get((Class) o, field); if (o instanceof Map) return ((Map) o).get(field); Field f = getOpt_findField(o.getClass(), field); if (f != null) { makeAccessible(f); return f.get(o); } } catch (Exception e) { throw asRuntimeException(e); } throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName()); } static Object get_raw(String field, Object o) { return get_raw(o, field); } static Object get_raw(Object o, String field) { try { if (o == null) return null; Field f = get_findField(o.getClass(), field); makeAccessible(f); return f.get(o); } catch (Exception __e) { throw rethrow(__e); } } static Object get(Class c, String field) { try { Field f = get_findStaticField(c, field); makeAccessible(f); return f.get(null); } catch (Exception e) { throw new RuntimeException(e); } } static Field get_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); } static Field get_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); } static Object get(String field, Object o) { return get(o, field); } static boolean eqOneOf(Object o, Object... l) { for (Object x : l) if (eq(o, x)) return true; return false; } static A setThreadLocal(ThreadLocal tl, A value) { if (tl == null) return null; A old = tl.get(); tl.set(value); return old; } static HashMap> callMC_cache = new HashMap(); static String callMC_key; static Method callMC_value; // varargs assignment fixer for a single string array argument static Object callMC(String method, String[] arg) { return callMC(method, new Object[] {arg}); } static Object callMC(String method, Object... args) { try { Method me; if (callMC_cache == null) callMC_cache = new HashMap(); // initializer time workaround synchronized(callMC_cache) { me = method == callMC_key ? callMC_value : null; } if (me != null) try { return invokeMethod(me, null, args); } catch (IllegalArgumentException e) { throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); } List m; synchronized(callMC_cache) { m = callMC_cache.get(method); } if (m == null) { if (callMC_cache.isEmpty()) { callMC_makeCache(); m = callMC_cache.get(method); } if (m == null) throw fail("Method named " + method + " not found in main"); } int n = m.size(); if (n == 1) { me = m.get(0); synchronized(callMC_cache) { callMC_key = method; callMC_value = me; } try { return invokeMethod(me, null, args); } catch (IllegalArgumentException e) { throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e); } } for (int i = 0; i < n; i++) { me = m.get(i); if (call_checkArgs(me, args, false)) return invokeMethod(me, null, args); } throw fail("No method called " + method + " with arguments (" + joinWithComma(getClasses(args)) + ") found in main"); } catch (Exception __e) { throw rethrow(__e); } } static void callMC_makeCache() { synchronized(callMC_cache) { callMC_cache.clear(); Class _c = (Class) mc(), c = _c; while (c != null) { for (Method m : c.getDeclaredMethods()) if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) { makeAccessible(m); multiMapPut(callMC_cache, m.getName(), m); } c = c.getSuperclass(); } } } static Pair pair(A a, B b) { return new Pair(a, b); } static Pair pair(A a) { return new Pair(a, a); } static A[] makeArray(Class type, int n) { return (A[]) Array.newInstance(type, n); } static int max(int a, int b) { return Math.max(a, b); } static int max(int a, int b, int c) { return max(max(a, b), c); } static long max(int a, long b) { return Math.max((long) a, b); } static long max(long a, long b) { return Math.max(a, b); } static double max(int a, double b) { return Math.max((double) a, b); } static float max(float a, float b) { return Math.max(a, b); } static double max(double a, double b) { return Math.max(a, b); } static int max(Collection c) { int x = Integer.MIN_VALUE; for (int i : c) x = max(x, i); return x; } static double max(double[] c) { if (c.length == 0) return Double.MIN_VALUE; double x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static float max(float[] c) { if (c.length == 0) return Float.MAX_VALUE; float x = c[0]; for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); return x; } static byte max(byte[] c) { byte x = -128; for (byte d : c) if (d > x) x = d; return x; } static short max(short[] c) { short x = -0x8000; for (short d : c) if (d > x) x = d; return x; } static int max(int[] c) { int x = Integer.MIN_VALUE; for (int d : c) if (d > x) x = d; return x; } static void clear(Collection c) { if (c != null) c.clear(); } static void clear(Map map) { if (map != null) map.clear(); } static void put(Map map, A a, B b) { if (map != null) map.put(a, b); } static void put(List l, int i, A a) { if (l != null && i >= 0 && i < l(l)) l.set(i, a); } static B mapGet2(Map map, A a) { return map == null ? null : map.get(a); } static B mapGet2(A a, Map map) { return map == null ? null : map.get(a); } static boolean isSubtypeOf(Class a, Class b) { return b.isAssignableFrom(a); // << always hated that method, let's replace it! } static Set reflection_classesNotToScan_value = litset( "jdk.internal.loader.URLClassPath" ); static Set reflection_classesNotToScan() { return reflection_classesNotToScan_value; } static boolean startsWith(String a, String b) { return a != null && a.startsWith(unnull(b)); } static boolean startsWith(String a, char c) { return nemptyString(a) && a.charAt(0) == c; } static boolean startsWith(String a, String b, Matches m) { if (!startsWith(a, b)) return false; m.m = new String[] {substring(a, strL(b))}; return true; } static boolean startsWith(List a, List b) { if (a == null || listL(b) > listL(a)) return false; for (int i = 0; i < listL(b); i++) if (neq(a.get(i), b.get(i))) return false; return true; } static boolean domainIsUnder(String domain, String mainDomain) { return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain); } static String theAGIBlueDomain() { return "agi.blue"; } static Object pcallFunction(Object f, Object... args) { try { return callFunction(f, args); } catch (Throwable __e) { _handleException(__e); } return null; } static volatile PersistableThrowable _handleException_lastException; static List _handleException_onException = synchroList(ll("printStackTrace2")); static boolean _handleException_showThreadCancellations = false; static void _handleException(Throwable e) { _handleException_lastException = persistableThrowable(e); Throwable e2 = innerException(e); if (e2.getClass() == RuntimeException.class && eq(e2.getMessage(), "Thread cancelled.") || e2 instanceof InterruptedException) { if (_handleException_showThreadCancellations) System.out.println(getStackTrace_noRecord(e2)); return; } for (Object f : cloneList(_handleException_onException)) try { callF(f, e); } catch (Throwable e3) { try { printStackTrace2(e3); // not using pcall here - it could lead to endless loops } catch (Throwable e4) { System.out.println(getStackTrace(e3)); System.out.println(getStackTrace(e4)); } } } static Object vm_generalMap_get(Object key) { return vm_generalMap().get(key); } static Object vm_generalMap_put(Object key, Object value) { return mapPutOrRemove(vm_generalMap(), key, value); } static Set syncIdentityHashSet() { return (Set) synchronizedSet(identityHashSet()); } static Map syncHashMap() { return synchroHashMap(); } static Throwable printStackTrace2(Throwable e) { // we go to system.out now - system.err is nonsense print(getStackTrace2(e)); return e; } static void printStackTrace2() { printStackTrace2(new Throwable()); } static void printStackTrace2(String msg) { printStackTrace2(new Throwable(msg)); } static List getClasses(Object[] array) { List l = emptyList(l(array)); for (Object o : array) l.add(_getClass(o)); return l; } static void multiMapPut(Map> map, A a, B b) { List l = map.get(a); if (l == null) map.put(a, l = new ArrayList()); l.add(b); } static HashSet litset(A... items) { return lithashset(items); } static String unnull(String s) { return s == null ? "" : s; } static Collection unnull(Collection l) { return l == null ? emptyList() : l; } static List unnull(List l) { return l == null ? emptyList() : l; } static int[] unnull(int[] l) { return l == null ? emptyIntArray() : l; } static char[] unnull(char[] l) { return l == null ? emptyCharArray() : l; } static double[] unnull(double[] l) { return l == null ? emptyDoubleArray() : l; } static Map unnull(Map l) { return l == null ? emptyMap() : l; } static Iterable unnull(Iterable i) { return i == null ? emptyList() : i; } static A[] unnull(A[] a) { return a == null ? (A[]) emptyObjectArray() : a; } static BitSet unnull(BitSet b) { return b == null ? new BitSet() : b; } //ifclass Symbol static Pair unnull(Pair p) { return p != null ? p : new Pair(null, null); } static long unnull(Long l) { return l == null ? 0L : l; } static boolean nemptyString(String s) { return s != null && s.length() > 0; } static int listL(Collection l) { return l == null ? 0 : l.size(); } static boolean neq(Object a, Object b) { return !eq(a, b); } static boolean eqic(String a, String b) { if ((a == null) != (b == null)) return false; if (a == null) return true; return a.equalsIgnoreCase(b); } static boolean eqic(char a, char b) { if (a == b) return true; char u1 = Character.toUpperCase(a); char u2 = Character.toUpperCase(b); if (u1 == u2) return true; return Character.toLowerCase(u1) == Character.toLowerCase(u2); } static boolean ewic(String a, String b) { return endsWithIgnoreCase(a, b); } static boolean ewic(String a, String b, Matches m) { return endsWithIgnoreCase(a, b, m); } static Object callFunction(Object f, Object... args) { return callF(f, args); } static Throwable innerException(Throwable e) { return getInnerException(e); } static Map vm_generalMap_map; static Map vm_generalMap() { if (vm_generalMap_map == null) vm_generalMap_map = (Map) get(javax(), "generalMap"); return vm_generalMap_map; } static B mapPutOrRemove(Map map, A key, B value) { if (map != null && key != null) if (value != null) return map.put(key, value); else return map.remove(key); return null; } static Set synchronizedSet() { return synchroHashSet(); } static Set synchronizedSet(Set set) { return Collections.synchronizedSet(set); } static Set identityHashSet() { return Collections.newSetFromMap(new IdentityHashMap()); } static String getStackTrace2(Throwable e) { return hideCredentials(getStackTrace(unwrapTrivialExceptionWraps(e)) + replacePrefix("java.lang.RuntimeException: ", "FAIL: ", hideCredentials(str(innerException2(e)))) + "\n"); } static Class _getClass(String name) { try { return Class.forName(name); } catch (ClassNotFoundException e) { return null; // could optimize this } } static Class _getClass(Object o) { return o == null ? null : o instanceof Class ? (Class) o : o.getClass(); } static Class _getClass(Object realm, String name) { try { return getClass(realm).getClassLoader().loadClass(classNameToVM(name)); } catch (ClassNotFoundException e) { return null; // could optimize this } } static HashSet lithashset(A... items) { HashSet set = new HashSet(); for (A a : items) set.add(a); return set; } static int[] emptyIntArray_a = new int[0]; static int[] emptyIntArray() { return emptyIntArray_a; } static char[] emptyCharArray = new char[0]; static char[] emptyCharArray() { return emptyCharArray; } static double[] emptyDoubleArray = new double[0]; static double[] emptyDoubleArray() { return emptyDoubleArray; } static Map emptyMap() { return new HashMap(); } static Object[] emptyObjectArray_a = new Object[0]; static Object[] emptyObjectArray() { return emptyObjectArray_a; } static String asString(Object o) { return o == null ? null : o.toString(); } static boolean endsWithIgnoreCase(String a, String b) { int la = l(a), lb = l(b); return la >= lb && regionMatchesIC(a, la-lb, b, 0, lb); } static boolean endsWithIgnoreCase(String a, String b, Matches m) { if (!endsWithIgnoreCase(a, b)) return false; if (m != null) m.m = new String[] { substring(a, 0, l(a)-l(b)) }; return true; } static Throwable getInnerException(Throwable e) { if (e == null) return null; while (e.getCause() != null) e = e.getCause(); return e; } static Throwable getInnerException(Runnable r) { return getInnerException(getException(r)); } // TODO: OurSyncCollections static Set synchroHashSet() { return Collections.synchronizedSet(new HashSet()); } static Throwable unwrapTrivialExceptionWraps(Throwable e) { if (e == null) return e; while (e.getClass() == RuntimeException.class && e.getCause() != null && eq(e.getMessage(), str(e.getCause()))) e = e.getCause(); return e; } static String replacePrefix(String prefix, String replacement, String s) { if (!startsWith(s, prefix)) return s; return replacement + substring(s, l(prefix)); } static Throwable innerException2(Throwable e) { if (e == null) return null; while (empty(e.getMessage()) && e.getCause() != null) e = e.getCause(); return e; } static Class getClass(String name) { try { return Class.forName(name); } catch (ClassNotFoundException e) { return null; } } static Class getClass(Object o) { return o instanceof Class ? (Class) o : o.getClass(); } static Class getClass(Object realm, String name) { try { try { return getClass(realm).getClassLoader().loadClass(classNameToVM(name)); } catch (ClassNotFoundException e) { return null; } } catch (Exception __e) { throw rethrow(__e); } } static String classNameToVM(String name) { return name.replace(".", "$"); } static boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) { return a != null && a.regionMatches(true, offsetA, b, offsetB, len); } static Throwable getException(Runnable r) { try { callF(r); return null; } catch (Throwable e) { return e; } } // immutable, has strong refs final static class _MethodCache { final Class c; final HashMap> cache = new HashMap(); _MethodCache(Class c) { this.c = c; _init(); } void _init() { Class _c = c; while (_c != null) { for (Method m : _c.getDeclaredMethods()) if (!isAbstract(m) && !reflection_isForbiddenMethod(m)) multiMapPut(cache, m.getName(), makeAccessible(m)); _c = _c.getSuperclass(); } // add default methods - this might lead to a duplication // because the overridden method is also added, but it's not // a problem except for minimal performance loss. for (Class intf : allInterfacesImplementedBy(c)) for (Method m : intf.getDeclaredMethods()) if (m.isDefault() && !reflection_isForbiddenMethod(m)) multiMapPut(cache, m.getName(), makeAccessible(m)); } // Returns only matching methods Method findMethod(String method, Object[] args) { try { List m = cache.get(method); if (m == null) return null; int n = m.size(); for (int i = 0; i < n; i++) { Method me = m.get(i); if (call_checkArgs(me, args, false)) return me; } return null; } catch (Exception __e) { throw rethrow(__e); } } Method findStaticMethod(String method, Object[] args) { try { List m = cache.get(method); if (m == null) return null; int n = m.size(); for (int i = 0; i < n; i++) { Method me = m.get(i); if (isStaticMethod(me) && call_checkArgs(me, args, false)) return me; } return null; } catch (Exception __e) { throw rethrow(__e); } } }static abstract class VF1 implements IVF1 { public abstract void get(A a); }static class Matches { String[] m; Matches() {} Matches(String... m) { this.m = m;} String get(int i) { return i < m.length ? m[i] : null; } String unq(int i) { return unquote(get(i)); } String tlc(int i) { return unq(i).toLowerCase(); } boolean bool(int i) { return "true".equals(unq(i)); } String rest() { return m[m.length-1]; } // for matchStart int psi(int i) { return Integer.parseInt(unq(i)); } public String toString() { return "Matches(" + joinWithComma(quoteAll(asList(m))) + ")"; } public int hashCode() { return _hashCode(toList(m)); } public boolean equals(Object o) { return o instanceof Matches && arraysEqual(m, ((Matches) o).m); } } static interface IF1 { B get(A a); }static interface ISetter { void set(A a); } static class Var implements IVar, ISetter { Var() {} Var(A v) { this.v = v;} A v; // you can access this directly if you use one thread public synchronized void set(A a) { if (v != a) { v = a; notifyAll(); } } public synchronized A get() { return v; } public synchronized boolean has() { return v != null; } public synchronized void clear() { v = null; } public String toString() { return str(this.get()); } }static class PersistableThrowable { String className; String msg; String stacktrace; PersistableThrowable() {} PersistableThrowable(Throwable e) { if (e == null) className = "Crazy Null Error"; else { className = getClassName(e).replace('/', '.'); msg = e.getMessage(); stacktrace = getStackTrace_noRecord(e); } } public String toString() { return nempty(msg) ? className + ": " + msg : className; } }static abstract class F1 { abstract B get(A a); }static class Pair implements Comparable> { A a; B b; Pair() {} Pair(A a, B b) { this.b = b; this.a = a;} public int hashCode() { return hashCodeFor(a) + 2*hashCodeFor(b); } public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Pair)) return false; Pair t = (Pair) o; return eq(a, t.a) && eq(b, t.b); } public String toString() { return "<" + a + ", " + b + ">"; } public int compareTo(Pair p) { if (p == null) return 1; int i = ((Comparable) a).compareTo(p.a); if (i != 0) return i; return ((Comparable) b).compareTo(p.b); } } static interface IVF1 { void get(A a); }static interface IVar extends IF0 { void set(A a); A get(); default boolean has() { return get() != null; } default void clear() { set(null); } } static interface IF0 { A get(); } static boolean isAbstract(Class c) { return (c.getModifiers() & Modifier.ABSTRACT) != 0; } static boolean isAbstract(Method m) { return (m.getModifiers() & Modifier.ABSTRACT) != 0; } static boolean reflection_isForbiddenMethod(Method m) { return m.getDeclaringClass() == Object.class && eqOneOf(m.getName(), "finalize", "clone", "registerNatives"); } static Set allInterfacesImplementedBy(Class c) { if (c == null) return null; HashSet set = new HashSet(); allInterfacesImplementedBy_find(c, set); return set; } static void allInterfacesImplementedBy_find(Class c, Set set) { if (c.isInterface() && !set.add(c)) return; do { for (Class intf : c.getInterfaces()) allInterfacesImplementedBy_find(intf, set); } while ((c = c.getSuperclass()) != null); } static Method findMethod(Object o, String method, Object... args) { return findMethod_cached(o, method, args); } static boolean findMethod_checkArgs(Method m, Object[] args, boolean debug) { Class[] types = m.getParameterTypes(); if (types.length != args.length) { if (debug) System.out.println("Bad parameter length: " + args.length + " vs " + types.length); return false; } for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) { if (debug) System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); return false; } return true; } static Method findStaticMethod(Class c, String method, Object... args) { Class _c = c; while (c != null) { for (Method m : c.getDeclaredMethods()) { if (!m.getName().equals(method)) continue; if ((m.getModifiers() & Modifier.STATIC) == 0 || !findStaticMethod_checkArgs(m, args)) continue; return m; } c = c.getSuperclass(); } return null; } static boolean findStaticMethod_checkArgs(Method m, Object[] args) { Class[] types = m.getParameterTypes(); if (types.length != args.length) return false; for (int i = 0; i < types.length; i++) if (!(args[i] == null || isInstanceX(types[i], args[i]))) return false; return true; } static String unquote(String s) { if (s == null) return null; if (startsWith(s, '[')) { int i = 1; while (i < s.length() && s.charAt(i) == '=') ++i; if (i < s.length() && s.charAt(i) == '[') { String m = s.substring(1, i); if (s.endsWith("]" + m + "]")) return s.substring(i+1, s.length()-i-1); } } if (s.length() > 1) { char c = s.charAt(0); if (c == '\"' || c == '\'') { int l = endsWith(s, c) ? s.length()-1 : s.length(); StringBuilder sb = new StringBuilder(l-1); for (int i = 1; i < l; i++) { char ch = s.charAt(i); if (ch == '\\') { char nextChar = (i == l - 1) ? '\\' : s.charAt(i + 1); // Octal escape? if (nextChar >= '0' && nextChar <= '7') { String code = "" + nextChar; i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; if ((i < l - 1) && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '7') { code += s.charAt(i + 1); i++; } } sb.append((char) Integer.parseInt(code, 8)); continue; } switch (nextChar) { case '\"': ch = '\"'; break; case '\\': ch = '\\'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; case '\'': ch = '\''; break; // Hex Unicode: u???? case 'u': if (i >= l - 5) { ch = 'u'; break; } int code = Integer.parseInt( "" + s.charAt(i + 2) + s.charAt(i + 3) + s.charAt(i + 4) + s.charAt(i + 5), 16); sb.append(Character.toChars(code)); i += 5; continue; default: ch = nextChar; // added by Stefan } i++; } sb.append(ch); } return sb.toString(); } } return s; // not quoted - return original } static List quoteAll(Collection l) { List x = new ArrayList(); for (String s : l) x.add(quote(s)); return x; } static int _hashCode(Object a) { return a == null ? 0 : a.hashCode(); } static boolean arraysEqual(Object[] a, Object[] b) { if (a.length != b.length) return false; for (int i = 0; i < a.length; i++) if (neq(a[i], b[i])) return false; return true; } static boolean nempty(Collection c) { return !empty(c); } static boolean nempty(CharSequence s) { return !empty(s); } static boolean nempty(Object[] o) { return !empty(o); } static boolean nempty(byte[] o) { return !empty(o); } static boolean nempty(int[] o) { return !empty(o); } static boolean nempty(Map m) { return !empty(m); } static boolean nempty(Iterator i) { return i != null && i.hasNext(); } static boolean nempty(Object o) { return !empty(o); } static int hashCodeFor(Object a) { return a == null ? 0 : a.hashCode(); } static A set(A o, String field, Object value) { if (o == null) return null; if (o instanceof Class) set((Class) o, field, value); else try { Field f = set_findField(o.getClass(), field); makeAccessible(f); smartSet(f, o, value); } catch (Exception e) { throw new RuntimeException(e); } return o; } static void set(Class c, String field, Object value) { if (c == null) return; try { Field f = set_findStaticField(c, field); makeAccessible(f); smartSet(f, null, value); } catch (Exception e) { throw new RuntimeException(e); } } static Field set_findStaticField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Static field '" + field + "' not found in " + c.getName()); } static Field set_findField(Class c, String field) { Class _c = c; do { for (Field f : _c.getDeclaredFields()) if (f.getName().equals(field)) return f; _c = _c.getSuperclass(); } while (_c != null); throw new RuntimeException("Field '" + field + "' not found in " + c.getName()); } static Method findMethod_cached(Object o, String method, Object... args) { try { if (o == null) return null; if (o instanceof Class) { _MethodCache cache = callOpt_getCache(((Class) o)); List methods = cache.cache.get(method); if (methods != null) for (Method m : methods) if (isStaticMethod(m) && findMethod_checkArgs(m, args, false)) return m; return null; } else { _MethodCache cache = callOpt_getCache(o.getClass()); List methods = cache.cache.get(method); if (methods != null) for (Method m : methods) if (findMethod_checkArgs(m, args, false)) return m; return null; } } catch (Exception __e) { throw rethrow(__e); } } static boolean endsWith(String a, String b) { return a != null && a.endsWith(b); } static boolean endsWith(String a, char c) { return nempty(a) && lastChar(a) == c; } static boolean endsWith(String a, String b, Matches m) { if (!endsWith(a, b)) return false; m.m = new String[] {dropLast(l(b), a)}; return true; } static String quote(Object o) { if (o == null) return "null"; return quote(str(o)); } static String quote(String s) { if (s == null) return "null"; StringBuilder out = new StringBuilder((int) (l(s)*1.5+2)); quote_impl(s, out); return out.toString(); } static void quote_impl(String s, StringBuilder out) { out.append('"'); int l = s.length(); for (int i = 0; i < l; i++) { char c = s.charAt(i); if (c == '\\' || c == '"') out.append('\\').append(c); else if (c == '\r') out.append("\\r"); else if (c == '\n') out.append("\\n"); else if (c == '\t') out.append("\\t"); else if (c == '\0') out.append("\\0"); else out.append(c); } out.append('"'); } static void smartSet(Field f, Object o, Object value) throws Exception { try { f.set(o, value); } catch (Exception e) { Class type = f.getType(); // take care of common case (long to int) if (type == int.class && value instanceof Long) value = ((Long) value).intValue(); if (type == LinkedHashMap.class && value instanceof Map) { f.set(o, asLinkedHashMap((Map) value)); return; } throw e; } } static char lastChar(String s) { return empty(s) ? '\0' : s.charAt(l(s)-1); } static A[] dropLast(A[] a) { return dropLast(a, 1); } static A[] dropLast(A[] a, int n) { if (a == null) return null; n = Math.min(n, a.length); A[] b = arrayOfSameType(a, a.length-n); System.arraycopy(a, 0, b, 0, b.length); return b; } static List dropLast(List l) { return subList(l, 0, l(l)-1); } static List dropLast(int n, List l) { return subList(l, 0, l(l)-n); } static List dropLast(Iterable l) { return dropLast(asList(l)); } static String dropLast(String s) { return substring(s, 0, l(s)-1); } static String dropLast(String s, int n) { return substring(s, 0, l(s)-n); } static String dropLast(int n, String s) { return dropLast(s, n); } static LinkedHashMap asLinkedHashMap(Map map) { if (map instanceof LinkedHashMap) return (LinkedHashMap) map; LinkedHashMap m = new LinkedHashMap(); if (map != null) synchronized(collectionMutex(map)) { m.putAll(map); } return m; } static A[] arrayOfSameType(A[] a, int n) { return newObjectArrayOfSameType(a, n); } static A[] newObjectArrayOfSameType(A[] a) { return newObjectArrayOfSameType(a, a.length); } static A[] newObjectArrayOfSameType(A[] a, int n) { return (A[]) Array.newInstance(a.getClass().getComponentType(), n); } }