├── .gitignore ├── LICENSE ├── README.md ├── build.sh └── src ├── ANSNA.c ├── ANSNA.h ├── Concept.c ├── Concept.h ├── Cycle.c ├── Cycle.h ├── Decision.c ├── Decision.h ├── Encode.c ├── Encode.h ├── Event.c ├── Event.h ├── FIFO.c ├── FIFO.h ├── Globals.c ├── Globals.h ├── Implication.c ├── Implication.h ├── Inference.c ├── Inference.h ├── Memory.c ├── Memory.h ├── PriorityQueue.c ├── PriorityQueue.h ├── SDR.c ├── SDR.h ├── Stamp.c ├── Stamp.h ├── Table.c ├── Table.h ├── Truth.c ├── Truth.h ├── Usage.c ├── Usage.h └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | 3.exe 2 | ANSA.exe 3 | a.out 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![ANSNA Logo](https://user-images.githubusercontent.com/8284677/52514098-f0081c00-2c06-11e9-8810-dceb8c99c261.png) 2 | 3 | Adaptive Neuro-Symbolic Network Agent 4 | 5 | ANSNA is an adaptive sensorimotor system that makes use of events, each holding a Sparse Distributed Representation (SDR). ANSNA is able to compose and decompose them into new events using union, tuple, intersection and union operations, and can learn predictive co-occurrence statistics in terms of which sets of events predict which others, using principles of Non-Axiomatic Logic. All events are mapped to a container (concept) with the closest SDR to itself, and both input and derived ones come with an attention value attached, where only high-priority events will be processed often, and the lowest ones forgotten at full capacity, to work under the available resource supply. Some of these events are beliefs, and lead to the derivation of predicted events, or the strengthening of learned predictive implications, and some are goals, and lead to the derivation of sub-goals. Some of these derived goals have a SDR that triggers an operation. In summary, the SDR encoding allows to effectively match aspects of a similar but in certain aspects different new situation to already known ones, and the learning of the predictive co-occurrence statistics lets the system learn new ways to achieve or predict certain outcomes, as to become more capable to reach its goals over time. 6 | 7 | Goal 8 | ---- 9 | This project is trying to combine my most valuable insights about Dr. Pei Wang's NARS (Non-Axiomatic Reasoning System), Jeffrey Hawkins HTM (Hierarchical Temporal Memory), Tony Lofthouse's ALANN (Adaptive Logic and Neural Network), Rod Rinkus's Sparsey, Pentti Kanerva's SDM (Sparse distributed memory), and my own projects of the last decade, for creating an autonomous sensorimotor agent that starts with zero knowledge and organizes its experience into conceptual units in such an efficient way that it can directly be applied for autonomous systems with rich sensory data. (Wiki: https://github.com/patham9/ANSNA/wiki) 10 | 11 | Closing the loop 12 | ---------------- 13 | Especially since the great successes of DL (Deep Learning), albeit mostly used to build passive sensory stimuli classifiers, symbolic systems suffer from bad reputation. Also justified, as many of them are rule based systems without any learning capacity whatsoever, mostly only following deductive ways of reasoning. But there are exceptions, systems like NARS or OpenCog that can learn novel knowledge from their experience, by a combination of inference and other data mining processes: 14 | - OpenNARS: https://www.youtube.com/watch?v=TlxoZ64cVvQ 15 | - OpenNARS: https://www.youtube.com/watch?v=hAO1zRj2z9A 16 | - OpenNARS: https://www.youtube.com/watch?v=GEmcT4Nk-78 17 | - OpenCog: https://www.youtube.com/watch?v=X8C7nhIULZs 18 | 19 | These current proto-AGI systems "close the loop", in the sense that they realize everything, from perception to the formation and usage of conceptual knowledge, and ultimatively, also decision making. Not by keeping track of, and simply using, the action of highest utility for a situation, but because the consequences of applying the action, in the current context, are both understood and desired by the AGI system. 20 | 21 | Learning from the past 22 | ---------------------- 23 | The field of AGI is full of misconceptions. In fact, the issues of logic-based systems was never that they use logic, but what kind of logic they use. Also it was never about that they use symbolic representations. For instance, is easy to see that a cognitive logic, such as Non-Axiomatic Logic (https://www.worldscientific.com/worldscibooks/10.1142/8665) or Probabilistic Logic Networks (https://www.springer.com/us/book/9780387768717) has no issue to encode and reason about the experienced brightness values of pixels, with different granularity. The knowledge representation these logics provide might be at best too mighty or inefficient to use, but in no way is that a fundamental restriction of any kind. A fundamental restriction of the traditional rule based systems was simply that they didn't have a way to measure the "truth" of a hypothesis in a statistical manner, a masurement of evidental support or some kind of higher-order probability, measurements these cognitive logics support. And how can we expect a system to learn anything from the environment without an ability to exploit correlations beteween events? ANSNA takes the position, that everything can be learned and conceptualized based on some kind of, often hierarchical, composition of observed spatial and temporal correlations (everything is grounded into sensorimotor-experience), and how much of them can be constructed, explored and evaluated is a matter of resources the system can afford. 24 | 25 | AIKR 26 | ---- 27 | Same as NARS, proposed by Dr. Pei Wang, ANSNA takes the Assumption of Insufficient Knowledge and Resources (AIKR) as fundamental working assumption. Having understood this assumption, there is simply no rational way in believing that AGI could be built without obeying this principle. When resources wouldn't be an issue that need to be addressed, for deciding in which of the, seemingly, infinite directions, to reason, in every moment in time, my precious reader, then please take your AIXI (https://en.wikipedia.org/wiki/AIXI) and go home. Or consider, that in such an universe, human attention for resource allocation within the brain would be superfluous, we would never forget, AGI would likely be everywhere, all the worms would have it, it's really not difficult to evolve a single equation, if following it would be anywhere near feasible and fruitful. 28 | For more on the topic, read: "Insufficient Knowledge and Resources — A Biological Constraint and Its Functional Implications": https://pdfs.semanticscholar.org/aa7c/5b8b49eb132643242987cb5f4c45ededb2be.pdf 29 | 30 | Attention and structures to attend 31 | ---------------------------------- 32 | What requirements do the structures need to fullfill that we manipulate in our mind for all kind of purposes? What exactly happens in our mind if we think about our blue planet and jump to the oceans? Is everything we think about something we directly observed, simply some kind of experience-replay? Or do we compose and manipulate structures in our mind, structures representing partial aspects of a situation, and structures we have potentially never seen before? NARS, ALANN, and ANSNA try to realize the latter. But how are these structures represented? As some kind of composition of ID's (NARS compound terms), as bit vectors (HTM SDR's), as some kind of implicit, potentially temporally unstable, transient, state in firing patterns (spiking neural networks)? As a subset of collections of weights in an old-school deep neural network? ANSNA takes the position that SDR's are a highly efficient way to encode mental compositions. 33 | 34 | Given certain experienced patterns exist within a mind, according to what criteria are they considered, used, de-priorized, or even completely forgotten? The ALANN model by Tony Lofthouse provides a very promising answer to that question. Having studied attention mechanisms for NARS, AERA, various FARG architectures (https://cogsci.indiana.edu/book.html), and others as discussed in Helgi Páll Helgason's Ph.D. thesis (see https://en.ru.is/media/td/Helgi_Pall_Helgason_PhD_CS_HR.pdf), and extensively tested a prototype of the ALANN system, I am convinced that it provides a simple and yet almost complete solution to the resource allocation problem in an artificial mind. 35 | 36 | ANSNA in a nutshell 37 | ------------------- 38 | - Overcoming symbolic limitations (space usage, inefficiency in matching and processing) by the use of SDR encodings: SDR-based representation of experienced and inferred structures. 39 | - Concept-centric memory to efficiently capture structure of the world. 40 | - Cognitive logic applied on SDR's rather than "symbols", restricted to NAL7/8 plus a SDR-based realization of NAL6: sequences and implications to exploit and use correlations in inputs, variable bits for learning general relationships. Inheritance and similarity naturally arise from symmetric and asymmetric SDR overlap evaluations. 41 | - ALANN control system, inspired by spiking neural networks. 42 | - Specialized to large-scale sensorimotor learning, different to OpenNARS which was designed to accept high-level user input: ANSNA comes with a minimal but essential subset of NAL6, NAL7 and NAL8, allowing it to learn predictive hypotheses, general procedure knowledge and categories using SDR encodings. 43 | - SDR's instead of tree-based compound terms, allow to attach dozens of sensors values to inputs without complicating their processing. 44 | 45 | ANSNA the name 46 | -------------- 47 | Adaptive - ALANN control model for resource allocation under AIKR. 48 | 49 | Neuro-Symbolic - "Sub-symbolic" SDR encodings, while utilizing cognitive logic (NAL), and taking neural network mechanisms into account, wherever they make sense. 50 | 51 | Network - Learning conceptual representations while having several neural network properties, such as inference/spike based activation spreading and predictive links between concepts. 52 | 53 | Agent - Goal to "close the loop", to learn conceptual knowledge from sensor data and to act according to own motivations. 54 | 55 | So what is ANSNA 56 | ---------------- 57 | Some kind of spiking neural network, or a reasoning system? That's a matter of interpretation, but it tries to combine principles from both paradigms. Hopefully one day it is a system that learns general relationships from raw sensory data and interacts with the environment. 58 | 59 | What ANSNA, NARS and ALANN have in common 60 | ---------------------------------------------------------------------- 61 | 1. Obeying AIKR. 62 | 0. Experience-grounded rather than model-theoretic semantics. 63 | 1. Attention Mechanism and system-eigendynamics as source for creativity. 64 | 2. Lifelong online learning. 65 | 4. NAL-based evidence measurement. 66 | 3. Conceptual representations of patterns in the experience. 67 | 5. Real-time operation: Ability to deal with events that come in at any moment. 68 | 6. Knowledge representation that has both symbolic and sub-symbolic, or neuro-symbolic, aspects. 69 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | Str=`ls src/*.c | xargs` 2 | echo $Str 3 | echo "Compilation started: Unused code will be printed and removed from the binary:" 4 | gcc -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--print-gc-sections -D_POSIX_C_SOURCE=199506L -pedantic -std=c99 -g3 -O3 -Wall -Wextra -Wformat-security $Str -lm -oANSNA 5 | echo "Done." 6 | -------------------------------------------------------------------------------- /src/ANSNA.c: -------------------------------------------------------------------------------- 1 | #include "ANSNA.h" 2 | 3 | long currentTime = 1; 4 | 5 | void ANSNA_INIT() 6 | { 7 | SDR_INIT(); 8 | Memory_INIT(); //clear data structures 9 | Event_INIT(); //reset base id counter 10 | currentTime = 1; //reset time 11 | } 12 | 13 | void ANSNA_Cycles(int cycles) 14 | { 15 | for(int i=0; idebug) == 0) 31 | { 32 | char debug[20]; 33 | //assign index as name to event and concept since concept has no name yet 34 | sprintf(debug, "%d", c->id); 35 | strcpy(ev.debug, debug); 36 | strcpy(c->debug, debug); 37 | } 38 | else 39 | { 40 | //name event according to concept 41 | strcpy(ev.debug, c->debug); 42 | } 43 | char* st = type == EVENT_TYPE_BELIEF ? "." : "!"; 44 | printf("Input: %s%s :|: %%%f;%f%%\n", c->debug, st, truth.frequency, truth.confidence); 45 | } 46 | for(int i=0; isdr = sdr; 6 | //Generate hash too: 7 | concept->sdr_hash = SDR_Hash(&sdr); 8 | } 9 | 10 | void Concept_Print(Concept *concept) 11 | { 12 | puts("Concept:"); 13 | SDR_Print(&concept->sdr); 14 | Usage_Print(&concept->usage); 15 | puts(""); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/Concept.h: -------------------------------------------------------------------------------- 1 | #ifndef CONCEPT_H 2 | #define CONCEPT_H 3 | 4 | /////////////////// 5 | // SDR Concept // 6 | /////////////////// 7 | //A concept named by a SDR 8 | 9 | //References// 10 | //-----------// 11 | #include "FIFO.h" 12 | #include "Table.h" 13 | #include "Usage.h" 14 | 15 | //Parameters// 16 | //----------// 17 | #define OPERATIONS_MAX 10 18 | #define MIN_CONFIDENCE 0.01 19 | 20 | //Data structure// 21 | //--------------// 22 | typedef struct { 23 | int id; 24 | Usage usage; 25 | SDR sdr; 26 | SDR_HASH_TYPE sdr_hash; 27 | Event belief_spike; 28 | Event incoming_goal_spike; 29 | Event goal_spike; 30 | Table precondition_beliefs[OPERATIONS_MAX]; 31 | //For debugging: 32 | char debug[50]; 33 | } Concept; 34 | 35 | //Methods// 36 | //-------// 37 | //Assign a new name to a concept 38 | void Concept_SetSDR(Concept *concept, SDR sdr); 39 | //print a concept 40 | void Concept_Print(Concept *concept); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/Cycle.c: -------------------------------------------------------------------------------- 1 | #include "Cycle.h" 2 | 3 | //doing inference within the matched concept, returning whether decisionMaking should continue 4 | static Decision Cycle_ActivateConcept(Concept *c, Event *e, long currentTime) 5 | { 6 | Decision decision = {0}; 7 | //Matched event, see https://github.com/patham9/ANSNA/wiki/SDR:-SDRInheritance-for-matching,-and-its-truth-value 8 | Event eMatch = Memory_MatchEventToConcept(c, e); 9 | if(eMatch.truth.confidence > MIN_CONFIDENCE) 10 | { 11 | c->usage = Usage_use(c->usage, currentTime); //given its new role it should be doable to add a priorization mechanism to it 12 | //add event as spike to the concept: 13 | if(eMatch.type == EVENT_TYPE_BELIEF) 14 | { 15 | c->belief_spike = eMatch; 16 | } 17 | else 18 | { 19 | //pass spike if the concept doesn't have a satisfying motor command 20 | decision = Decision_Suggest(&eMatch, currentTime); 21 | if(!decision.execute) 22 | { 23 | c->incoming_goal_spike = eMatch; 24 | } 25 | else 26 | { 27 | e->propagated = true; 28 | } 29 | } 30 | } 31 | return decision; 32 | } 33 | 34 | //Process an event, by creating a concept, or activating an existing 35 | static Decision Cycle_ProcessEvent(Event *e, long currentTime) 36 | { 37 | Decision decision = {0}; 38 | e->processed = true; 39 | Event_SetSDR(e, e->sdr); // TODO make sure that hash needs to be calculated once instead already 40 | IN_DEBUG( puts("Event was selected:"); Event_Print(e); ) 41 | //determine the concept it is related to 42 | int closest_concept_i; 43 | Concept *c = NULL; 44 | if(Memory_getClosestConcept(&e->sdr, e->sdr_hash, &closest_concept_i)) 45 | { 46 | c = concepts.items[closest_concept_i].address; 47 | decision = Cycle_ActivateConcept(c, e, currentTime); 48 | } 49 | //add a new concept for e too at the end (in all layers) 50 | if(Memory_EventIsNovel(e, c)) 51 | { 52 | Memory_Conceptualize(&e->sdr); 53 | } 54 | return decision; 55 | } 56 | 57 | //Propagate spikes for subgoal processing, generating anticipations and decisions 58 | static Decision Cycle_PropagateSpikes(long currentTime) 59 | { 60 | Decision decision = {0}; 61 | //process spikes 62 | if(PROPAGATE_GOAL_SPIKES) 63 | { 64 | //pass goal spikes on to the next 65 | for(int i=0; igoal_spike.type != EVENT_TYPE_DELETED && !postc->goal_spike.propagated && Truth_Expectation(postc->goal_spike.truth) > PROPAGATION_THRESHOLD) 69 | { 70 | for(int opi=0; opiprecondition_beliefs[opi].itemsAmount; j++) 73 | { 74 | Implication *imp = &postc->precondition_beliefs[opi].array[j]; 75 | Memory_RelinkImplication(imp); 76 | Concept *pre = imp->sourceConcept; 77 | if(pre->incoming_goal_spike.type == EVENT_TYPE_DELETED || pre->incoming_goal_spike.processed) 78 | { 79 | pre->incoming_goal_spike = Inference_GoalDeduction(&postc->goal_spike, &postc->precondition_beliefs[opi].array[j]); 80 | } 81 | } 82 | } 83 | } 84 | postc->goal_spike.propagated = true; 85 | } 86 | //process incoming goal spikes, invoking potential operations 87 | for(int i=0; iincoming_goal_spike.type != EVENT_TYPE_DELETED) 91 | { 92 | c->goal_spike = Inference_IncreasedActionPotential(&c->goal_spike, &c->incoming_goal_spike, currentTime); 93 | if(c->goal_spike.type != EVENT_TYPE_DELETED && !c->goal_spike.processed && Truth_Expectation(c->goal_spike.truth) > PROPAGATION_THRESHOLD) 94 | { 95 | Decision decision = Cycle_ProcessEvent(&c->goal_spike, currentTime); 96 | if(decision.execute) 97 | { 98 | return decision; 99 | } 100 | } 101 | } 102 | c->incoming_goal_spike = (Event) {0}; 103 | } 104 | } 105 | return decision; 106 | } 107 | 108 | //Reinforce link between concept a and b (creating it if non-existent) 109 | static void Cycle_ReinforceLink(Event *a, Event *b, int operationID) 110 | { 111 | if(a->type != EVENT_TYPE_BELIEF || b->type != EVENT_TYPE_BELIEF) 112 | { 113 | return; 114 | } 115 | int AConceptIndex; 116 | int BConceptIndex; 117 | if(Memory_getClosestConcept(&a->sdr, a->sdr_hash, &AConceptIndex) && 118 | Memory_getClosestConcept(&b->sdr, b->sdr_hash, &BConceptIndex)) 119 | { 120 | Concept *A = concepts.items[AConceptIndex].address; 121 | Concept *B = concepts.items[BConceptIndex].address; 122 | if(A != B) 123 | { 124 | //temporal induction 125 | if(!Stamp_checkOverlap(&a->stamp, &b->stamp)) 126 | { 127 | Implication precondition_implication = Inference_BeliefInduction(a, b); 128 | precondition_implication.sourceConcept = A; 129 | precondition_implication.sourceConceptSDR = A->sdr; 130 | if(precondition_implication.truth.confidence >= MIN_CONFIDENCE) 131 | { 132 | char debug[200]; 133 | sprintf(debug, "<(&/,%s,^op%d(),+%ld) =/> %s>.",A->debug, operationID,precondition_implication.occurrenceTimeOffset ,B->debug); 134 | IN_DEBUG ( if(operationID != 0) { puts(debug); Truth_Print(&precondition_implication.truth); puts("\n"); getchar(); } ) 135 | IN_OUTPUT( fputs("Formed implication: ", stdout); Implication_Print(&precondition_implication); ) 136 | Implication *revised_precon = Table_AddAndRevise(&B->precondition_beliefs[operationID], &precondition_implication, debug); 137 | if(revised_precon != NULL) 138 | { 139 | revised_precon->sourceConcept = A; 140 | revised_precon->sourceConceptSDR = A->sdr; 141 | IN_OUTPUT( if(revised_precon->sdr_hash != 0) { fputs("REVISED pre-condition implication: ", stdout); Implication_Print(revised_precon); } ) 142 | } 143 | } 144 | } 145 | } 146 | } 147 | } 148 | 149 | void Cycle_Perform(long currentTime) 150 | { 151 | //1. process newest event 152 | if(belief_events.itemsAmount > 0) 153 | { 154 | //form concepts for the sequences of different length 155 | for(int len=0; lenprocessed) 159 | { 160 | Cycle_ProcessEvent(toProcess, currentTime); 161 | Event postcondition = *toProcess; 162 | Decision_AssumptionOfFailure(postcondition.operationID, currentTime); //collection of negative evidence, new way 163 | //Mine for <(&/,precondition,operation) =/> postcondition> patterns in the FIFO: 164 | if(len == 0) //postcondition always len1 165 | { 166 | if(postcondition.operationID != 0) 167 | { 168 | return; 169 | } 170 | for(int k=1; koperationID; 179 | if(operationID != 0) //also meaning len2==0 180 | { 181 | for(int j=k+1; joperationID == 0) 187 | { 188 | Cycle_ReinforceLink(precondition, &postcondition, operationID); 189 | } 190 | } 191 | } 192 | } 193 | else 194 | { 195 | Cycle_ReinforceLink(precondition, &postcondition, operationID); 196 | } 197 | } 198 | } 199 | } 200 | } 201 | } 202 | } 203 | } 204 | //process goals 205 | Decision decision[PROPAGATION_ITERATIONS + 1] = {0}; 206 | if(goal_events.itemsAmount > 0) 207 | { 208 | Event *goal = FIFO_GetNewestSequence(&goal_events, 0); 209 | if(!goal->processed) 210 | { 211 | decision[0] = Cycle_ProcessEvent(goal, currentTime); 212 | //allow reasoning into the future by propagating spikes from goals back to potential current evens 213 | for(int i=0; i= best_decision.desire) 224 | { 225 | best_decision = decision[i]; 226 | } 227 | } 228 | if(best_decision.execute && best_decision.operationID > 0) 229 | { 230 | Decision_Execute(&best_decision); 231 | } 232 | //end of iterations, remove spikes 233 | for(int i=0; iincoming_goal_spike = (Event) {0}; 237 | c->goal_spike = (Event) {0}; 238 | } 239 | //Re-sort queue 240 | PriorityQueue_Rebuild(&concepts); 241 | } 242 | -------------------------------------------------------------------------------- /src/Cycle.h: -------------------------------------------------------------------------------- 1 | #ifndef H_CYCLE 2 | #define H_CYCLE 3 | 4 | ///////////////////////////////////// 5 | // ANSNA Control Cycle // 6 | ///////////////////////////////////// 7 | //A FIFO-like structure, that only supports put in and overwrites 8 | //the oldest task when full 9 | 10 | //References// 11 | //-----------// 12 | #include "Globals.h" 13 | #include "Decision.h" 14 | #include "Inference.h" 15 | 16 | //Methods// 17 | //-------// 18 | //Apply one operating cyle 19 | void Cycle_Perform(long currentTime); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/Decision.c: -------------------------------------------------------------------------------- 1 | #include "Decision.h" 2 | 3 | double DECISION_THRESHOLD = DECISION_THRESHOLD_INITIAL; 4 | double ANTICIPATION_THRESHOLD = ANTICIPATION_THRESHOLD_INITIAL; 5 | double ANTICIPATION_CONFIDENCE = ANTICIPATION_CONFIDENCE_INITIAL; 6 | double MOTOR_BABBLING_CHANCE = MOTOR_BABBLING_CHANCE_INITIAL; 7 | //Inject action event after execution or babbling 8 | void Decision_Execute(Decision *decision) 9 | { 10 | assert(decision->operationID > 0, "Operation 0 is reserved for no action"); 11 | decision->op = operations[decision->operationID-1]; 12 | (*decision->op.action)(); 13 | //and add operator feedback 14 | ANSNA_AddInputBelief(decision->op.sdr); 15 | } 16 | 17 | //"reflexes" to try different operations, especially important in the beginning 18 | static Decision Decision_MotorBabbling() 19 | { 20 | Decision decision = (Decision) {0}; 21 | int n_ops = 0; 22 | for(int i=0; i 0) 27 | { 28 | decision.operationID = 1+(rand() % (n_ops)); 29 | IN_DEBUG ( 30 | printf(" ANSNA BABBLE %d\n", decision.operationID); 31 | ) 32 | decision.execute = true; 33 | } 34 | return decision; 35 | } 36 | 37 | int stampID = -1; 38 | Decision Decision_BestCandidate(Event *goal, long currentTime) 39 | { 40 | Decision decision = (Decision) {0}; 41 | int closest_postc_i; 42 | if(Memory_getClosestConcept(&goal->sdr, goal->sdr_hash, &closest_postc_i)) 43 | { 44 | Concept *postc = concepts.items[closest_postc_i].address; 45 | double bestTruthExpectation = 0; 46 | Implication bestImp = {0}; 47 | Concept *prec; 48 | for(int opi=1; opiprecondition_beliefs[opi].itemsAmount; j++) 55 | { 56 | Memory_RelinkImplication(&postc->precondition_beliefs[opi].array[j]); 57 | Implication imp = postc->precondition_beliefs[opi].array[j]; 58 | IN_DEBUG 59 | ( 60 | printf("CONSIDERED IMPLICATION: impTruth=(%f, %f) %s \n", imp.truth.frequency, imp.truth.confidence, imp.debug); 61 | SDR_Print(&imp.sdr); 62 | ) 63 | //now look at how much the precondition is fulfilled 64 | Concept *current_prec = imp.sourceConcept; 65 | Event *precondition = ¤t_prec->belief_spike; //a. :|: 66 | if(precondition != NULL && precondition->type != EVENT_TYPE_DELETED) 67 | { 68 | Event ContextualOperation = Inference_GoalDeduction(goal, &imp); //(&/,a,op())! :\: 69 | double operationGoalTruthExpectation = Truth_Expectation(Inference_OperationDeduction(&ContextualOperation, precondition, currentTime).truth); //op()! :|: 70 | IN_DEBUG 71 | ( 72 | printf("CONSIDERED PRECON: desire=%f %s\n", operationGoalTruthExpectation, current_prec->debug); 73 | fputs("CONSIDERED PRECON truth ", stdout); 74 | Truth_Print(&precondition->truth); 75 | fputs("CONSIDERED goal truth ", stdout); 76 | Truth_Print(&goal->truth); 77 | fputs("CONSIDERED imp truth ", stdout); 78 | Truth_Print(&imp.truth); 79 | printf("CONSIDERED time %ld\n", precondition->occurrenceTime); 80 | SDR_Print(¤t_prec->sdr); 81 | SDR_Print(&precondition->sdr); 82 | ) 83 | if(operationGoalTruthExpectation > bestTruthExpectation) 84 | { 85 | prec = current_prec; 86 | bestImp = imp; 87 | decision.operationID = opi; 88 | decision.desire = operationGoalTruthExpectation; 89 | bestTruthExpectation = operationGoalTruthExpectation; 90 | } 91 | } 92 | } 93 | } 94 | if(bestTruthExpectation < DECISION_THRESHOLD) 95 | { 96 | return decision; 97 | } 98 | printf("decision expectation %f impTruth=(%f, %f): %s future=%ld\n", bestTruthExpectation, bestImp.truth.frequency, bestImp.truth.confidence, bestImp.debug, bestImp.occurrenceTimeOffset); 99 | IN_DEBUG 100 | ( 101 | printf("%s %f,%f",bestImp.debug, bestImp.truth.frequency, bestImp.truth.confidence); 102 | puts(""); 103 | printf("SELECTED PRECON: %s\n", prec->debug); 104 | puts(bestImp.debug); //++ 105 | printf(" ANSNA TAKING ACTIVE CONTROL %d\n", decision.operationID); 106 | ) 107 | decision.execute = true; 108 | 109 | } 110 | return decision; 111 | } 112 | 113 | void Decision_AssumptionOfFailure(int operationID, long currentTime) 114 | { 115 | assert(operationID >= 0 && operationID < OPERATIONS_MAX, "Wrong operation id, did you inject an event manually?"); 116 | for(int j=0; jprecondition_beliefs[operationID].itemsAmount; h++) 120 | { 121 | Memory_RelinkImplication(&postc->precondition_beliefs[operationID].array[h]); 122 | Implication imp = postc->precondition_beliefs[operationID].array[h]; //(&/,a,op) =/> b. 123 | Concept *current_prec = imp.sourceConcept; 124 | Event *precondition = ¤t_prec->belief_spike; //a. :|: 125 | if(precondition != NULL && precondition->type != EVENT_TYPE_DELETED) 126 | { 127 | Event updated_precondition = Inference_EventUpdate(precondition, currentTime); 128 | Event op = { .type = EVENT_TYPE_BELIEF, 129 | .truth = { .frequency = 1.0, .confidence = 0.9 }, 130 | .occurrenceTime = currentTime, 131 | .operationID = operationID }; 132 | Event seqop = Inference_BeliefIntersection(&updated_precondition, &op); //(&/,a,op). :|: 133 | Event result = Inference_BeliefDeduction(&seqop, &imp); //b. :/: 134 | if(Truth_Expectation(result.truth) > ANTICIPATION_THRESHOLD) 135 | { 136 | Implication negative_confirmation = imp; 137 | Truth TNew = { .frequency = 0.0, .confidence = ANTICIPATION_CONFIDENCE }; 138 | Truth TPast = Truth_Projection(precondition->truth, 0, imp.occurrenceTimeOffset); 139 | negative_confirmation.truth = Truth_Eternalize(Truth_Induction(TPast, TNew)); 140 | negative_confirmation.stamp = (Stamp) { .evidentalBase = { -stampID } }; 141 | IN_DEBUG ( printf("ANTICIPATE %s, future=%ld \n", imp.debug, imp.occurrenceTimeOffset); ) 142 | assert(negative_confirmation.truth.confidence >= 0.0 && negative_confirmation.truth.confidence <= 1.0, "(666) confidence out of bounds"); 143 | Implication *added = Table_AddAndRevise(&postc->precondition_beliefs[operationID], &negative_confirmation, negative_confirmation.debug); 144 | if(added != NULL) 145 | { 146 | added->sourceConcept = negative_confirmation.sourceConcept; 147 | added->sourceConceptSDR = negative_confirmation.sourceConceptSDR; 148 | } 149 | stampID--; 150 | } 151 | } 152 | } 153 | } 154 | } 155 | 156 | Decision Decision_Suggest(Event *goal, long currentTime) 157 | { 158 | Decision decision = {0}; 159 | //try motor babbling with a certain chance 160 | if(!decision.execute && rand() % 1000000 < (int)(MOTOR_BABBLING_CHANCE*1000000.0)) 161 | { 162 | decision = Decision_MotorBabbling(); 163 | } 164 | //try matching op if didn't motor babble 165 | if(!decision.execute) 166 | { 167 | decision = Decision_BestCandidate(goal, currentTime); 168 | } 169 | return decision; 170 | } 171 | -------------------------------------------------------------------------------- /src/Decision.h: -------------------------------------------------------------------------------- 1 | #ifndef DECISION_H 2 | #define DECISION_H 3 | 4 | //References// 5 | //----------// 6 | #include 7 | #include 8 | #include "Memory.h" 9 | #include "ANSNA.h" 10 | 11 | ////////////////////// 12 | // ANSNA Decision // 13 | ////////////////////// 14 | //Realization of goals 15 | 16 | //Parameters// 17 | //----------// 18 | //truth expectation needed for executions 19 | #define DECISION_THRESHOLD_INITIAL 0.501 20 | extern double DECISION_THRESHOLD; 21 | #define ANTICIPATION_THRESHOLD_INITIAL 0.501 22 | extern double ANTICIPATION_THRESHOLD; 23 | #define ANTICIPATION_CONFIDENCE_INITIAL 0.005 24 | extern double ANTICIPATION_CONFIDENCE; 25 | //motor babbling chance 26 | #define MOTOR_BABBLING_CHANCE_INITIAL 0.2 27 | extern double MOTOR_BABBLING_CHANCE; 28 | 29 | //Data structure// 30 | //--------------// 31 | typedef struct 32 | { 33 | double desire; 34 | bool execute; 35 | int operationID; 36 | Operation op; 37 | }Decision; 38 | 39 | //Methods// 40 | //-------// 41 | //execute decision 42 | void Decision_Execute(Decision *decision); 43 | //assumption of failure, also works for "do nothing operator" 44 | void Decision_AssumptionOfFailure(int operationID, long currentTime); 45 | //ANSNA decision making rule applying when goal is an operation 46 | Decision Decision_Suggest(Event *goal, long currentTime); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/Encode.c: -------------------------------------------------------------------------------- 1 | #include "Encode.h" 2 | 3 | SDR input_terms[TERMS_MAX]; 4 | bool input_terms_used[TERMS_MAX]; 5 | 6 | //inspired by https://arxiv.org/pdf/1602.05925.pdf 7 | //but the bucket always being half of the SDR size +min_overlap 8 | //as needed for continuous perception purposes 9 | SDR Encode_Scalar(int min, int max, int value) 10 | { 11 | //min_overlap>0 guarantees continuous perception! 12 | int min_overlap = TERM_ONES; //Allow at least an overlap of the amount of 1-bits used for term encoding 13 | int range = max - min; 14 | int relative = value - min; 15 | int bucketsize = (SDR_SIZE/2 + min_overlap); 16 | int available_places = MAX(0, SDR_SIZE - bucketsize); 17 | double reached = ((double)relative) / ((double)range); //in [0,1] 18 | int max_index = (int) (reached * ((double) available_places)); 19 | SDR result = {0}; 20 | for(int i=max_index; i 13 | #include 14 | #include "SDR.h" 15 | #include "Globals.h" 16 | 17 | //Parameters// 18 | //----------// 19 | #define TERMS_MAX 500 20 | #define TERM_ONES 5 21 | 22 | //Data structure// 23 | //--------------// 24 | extern SDR input_terms[TERMS_MAX]; 25 | extern bool input_terms_used[TERMS_MAX]; 26 | 27 | //Methods// 28 | //-------// 29 | //encodes an integer value as a SDR 30 | //https://www.youtube.com/watch?v=V3Yqtpytif0&list=PL3yXMgtrZmDqhsFQzwUC9V8MeeVOQ7eZ9&index=6 31 | SDR Encode_Scalar(int min, int max, int value); 32 | //Encodes a term 33 | SDR Encode_Term(char *name); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/Event.c: -------------------------------------------------------------------------------- 1 | #include "Event.h" 2 | 3 | void Event_SetSDR(Event *event, SDR sdr) 4 | { 5 | event->sdr = sdr; 6 | //Generate hash too: 7 | event->sdr_hash = SDR_Hash(&sdr); 8 | } 9 | 10 | long base = 1; 11 | Event Event_InputEvent(SDR sdr, char type, Truth truth, long currentTime) 12 | { 13 | return (Event) { .sdr = sdr, 14 | .sdr_hash = SDR_Hash(&sdr), 15 | .type = type, 16 | .truth = truth, 17 | .stamp = (Stamp) { .evidentalBase = { base++ } }, 18 | .occurrenceTime = currentTime }; 19 | } 20 | 21 | void Event_INIT() 22 | { 23 | base = 1; 24 | } 25 | 26 | void Event_Print(Event *event) 27 | { 28 | printf("Event: %s\n", event->debug); 29 | SDR_Print(&event->sdr); 30 | //printf("SDR hash=%d", event->sdr_hash); 31 | printf(event->type == EVENT_TYPE_GOAL ? "type=goal\n" : (EVENT_TYPE_BELIEF ? "type=belief\n" : "type=deleted\n" )); 32 | printf("operationID=%d\n", event->operationID); 33 | Truth_Print(&event->truth); 34 | Stamp_print(&event->stamp); 35 | printf("occurrenceTime=%ld\n\n", event->occurrenceTime); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/Event.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENT_H 2 | #define EVENT_H 3 | 4 | /////////////////// 5 | // SDR Event // 6 | /////////////////// 7 | //also see https://github.com/patham9/ANSNA/wiki/Input 8 | 9 | //References// 10 | //-----------// 11 | #include "SDR.h" 12 | #include "Stamp.h" 13 | 14 | //Data structure// 15 | //--------------// 16 | #define EVENT_TYPE_GOAL 1 17 | #define EVENT_TYPE_BELIEF 2 18 | #define EVENT_TYPE_DELETED 0 19 | typedef struct { 20 | SDR sdr; 21 | SDR_HASH_TYPE sdr_hash; 22 | char type; //either JUDGMENT or GOAL 23 | Truth truth; 24 | Stamp stamp; 25 | long occurrenceTime; 26 | int operationID; //automatically obtained from SDR on input 27 | bool processed; 28 | bool propagated; 29 | char debug[30]; 30 | } Event; 31 | 32 | //Methods// 33 | //-------// 34 | //Init/Reset module 35 | void Event_INIT(); 36 | //Assign a new name to an event 37 | void Event_SetSDR(Event *event, SDR sdr); 38 | //construct an input event 39 | Event Event_InputEvent(SDR sdr, char type, Truth truth, long currentTime); 40 | //print event 41 | void Event_Print(Event *event); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/FIFO.c: -------------------------------------------------------------------------------- 1 | #include "FIFO.h" 2 | 3 | void FIFO_RESET(FIFO *fifo) 4 | { 5 | fifo->itemsAmount = 0; 6 | fifo->currentIndex = 0; 7 | for(int len=0; lenarray[len][i] = (Event) {0}; 12 | } 13 | } 14 | } 15 | 16 | void FIFO_Add(Event *event, FIFO *fifo) 17 | { 18 | //build sequence elements: 19 | for(int len=0; lenarray[len][fifo->currentIndex] = *event; 25 | } 26 | else //len>0, so chain previous sequence with length len-1 with new event 27 | { 28 | Event *sequence = FIFO_GetNewestSequence(fifo, len-1); 29 | if(sequence == NULL || sequence->type == EVENT_TYPE_DELETED) 30 | { 31 | break; 32 | } 33 | //printf("occurrence times a=%d, b=%d", ((int) sequence->occurrenceTime),((int) event->occurrenceTime)); 34 | Event new_sequence = Inference_BeliefIntersection(sequence, event); 35 | fifo->array[len][fifo->currentIndex] = new_sequence; 36 | } 37 | 38 | } 39 | fifo->currentIndex = (fifo->currentIndex + 1) % FIFO_SIZE; 40 | fifo->itemsAmount = MIN(fifo->itemsAmount + 1, FIFO_SIZE); 41 | } 42 | 43 | Event* FIFO_GetKthNewestSequence(FIFO *fifo, int k, int len) 44 | { 45 | if(fifo->itemsAmount == 0 || k >= fifo->itemsAmount) 46 | { 47 | return NULL; 48 | } 49 | int index = fifo->currentIndex - 1 - k; 50 | if(index < 0) 51 | { 52 | index = FIFO_SIZE+index; 53 | } 54 | return &fifo->array[len][index]; 55 | } 56 | 57 | Event* FIFO_GetNewestSequence(FIFO *fifo, int len) 58 | { 59 | return FIFO_GetKthNewestSequence(fifo, 0, len); 60 | } 61 | -------------------------------------------------------------------------------- /src/FIFO.h: -------------------------------------------------------------------------------- 1 | #ifndef H_FIFO 2 | #define H_FIFO 3 | 4 | ///////////////////////////////////// 5 | // First in first out (forgotten) // 6 | ///////////////////////////////////// 7 | //A FIFO-like structure, that only supports put in and overwrites 8 | //the oldest task when full 9 | 10 | //References// 11 | //-----------// 12 | #include "Inference.h" 13 | #include "Globals.h" 14 | #include "Encode.h" 15 | 16 | //Parameters// 17 | //----------// 18 | #define FIFO_SIZE 20 19 | #define MAX_SEQUENCE_LEN 2 20 | 21 | //Data structure// 22 | //--------------// 23 | typedef struct 24 | { 25 | int itemsAmount; 26 | int currentIndex; 27 | Event array[MAX_SEQUENCE_LEN][FIFO_SIZE]; 28 | } FIFO; 29 | typedef struct 30 | { 31 | Event *originalEvent; 32 | Event projectedEvent; 33 | } FIFO_Query_Result; 34 | 35 | //Methods// 36 | //-------// 37 | //Resets the FIFO 38 | void FIFO_RESET(FIFO *fifo); 39 | //Add an event to the FIFO 40 | void FIFO_Add(Event *event, FIFO *fifo); 41 | //Get the newest element 42 | Event* FIFO_GetNewestSequence(FIFO *fifo, int len); 43 | //Get the k-th newest FIFO element 44 | Event* FIFO_GetKthNewestSequence(FIFO *fifo, int k, int len); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/Globals.c: -------------------------------------------------------------------------------- 1 | #include "Globals.h" 2 | #include 3 | #include 4 | 5 | int OUTPUT = 1; 6 | void assert(bool b, char* message) 7 | { 8 | if(!b) 9 | { 10 | puts(message); 11 | puts("Test failed."); 12 | exit(1); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Globals.h: -------------------------------------------------------------------------------- 1 | #define DEBUG 0 2 | extern int OUTPUT; 3 | #define DEBUG_INFO(x) {if(DEBUG == 1){}} 4 | 5 | #ifdef DEBUG 6 | #define PRINTD printf 7 | #else 8 | #define PRINTD(format, args...) ((void)0) 9 | #endif 10 | 11 | #define IN_DEBUG(x) {if(DEBUG){ x } } 12 | #define IN_OUTPUT(x) {if(OUTPUT){ x } } 13 | 14 | #include 15 | 16 | void assert(bool b, char* message); 17 | 18 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 19 | #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 20 | -------------------------------------------------------------------------------- /src/Implication.c: -------------------------------------------------------------------------------- 1 | #include "Implication.h" 2 | 3 | void Implication_SetSDR(Implication *implication, SDR sdr) 4 | { 5 | implication->sdr = sdr; 6 | //Generate hash too: 7 | implication->sdr_hash = SDR_Hash(&sdr); 8 | } 9 | 10 | void Implication_Print(Implication *implication) 11 | { 12 | puts("Implication:"); 13 | SDR_Print(&implication->sdr); 14 | Truth_Print(&implication->truth); 15 | Stamp_print(&implication->stamp); 16 | printf("occurrenceTimeOffset=%ld\n\n", implication->occurrenceTimeOffset); 17 | } 18 | -------------------------------------------------------------------------------- /src/Implication.h: -------------------------------------------------------------------------------- 1 | #ifndef BELIEF_H 2 | #define BELIEF_H 3 | 4 | ////////////////////// 5 | // Implication // 6 | ////////////////////// 7 | //essentially allowing concepts to predict activations of others 8 | 9 | //References// 10 | //-----------// 11 | #include "SDR.h" 12 | #include "Stamp.h" 13 | 14 | //Data structure// 15 | //--------------// 16 | typedef struct { 17 | SDR sdr; 18 | SDR_HASH_TYPE sdr_hash; 19 | Truth truth; 20 | Stamp stamp; 21 | //for deciding occurrence time of conclusion: 22 | long occurrenceTimeOffset; 23 | //for efficient spike propagation: 24 | void *sourceConcept; 25 | SDR sourceConceptSDR; //to check whether it's still the same 26 | SDR_HASH_TYPE sourceConceptSDRHash; 27 | char debug[100]; //++ DEBUG 28 | } Implication; 29 | 30 | //Methods// 31 | //-------// 32 | //Assign a new name to an implication 33 | void Implication_SetSDR(Implication *implication, SDR sdr); 34 | void Implication_Print(Implication *implication); 35 | 36 | #endif 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Inference.c: -------------------------------------------------------------------------------- 1 | #include "Inference.h" 2 | #include "SDR.h" 3 | 4 | #define DERIVATION_STAMP(a,b) Stamp conclusionStamp = Stamp_make(&a->stamp, &b->stamp); 5 | #define DERIVATION_STAMP_AND_TIME(a,b) DERIVATION_STAMP(a,b) \ 6 | long conclusionTime = b->occurrenceTime; \ 7 | Truth truthA = Truth_Projection(a->truth, a->occurrenceTime, conclusionTime); \ 8 | Truth truthB = b->truth; 9 | 10 | static double weighted_average(double a1, double a2, double w1, double w2) 11 | { 12 | return (a1*w1+a2*w2)/(w1+w2); 13 | } 14 | 15 | //{Event a., Event b.} |- Event (&/,a,b). 16 | Event Inference_BeliefIntersection(Event *a, Event *b) 17 | { 18 | assert(b->occurrenceTime >= a->occurrenceTime, "after(b,a) violated in Inference_BeliefIntersection"); 19 | DERIVATION_STAMP_AND_TIME(a,b) 20 | return (Event) { .sdr = SDR_Tuple(&a->sdr,&b->sdr), 21 | .type = EVENT_TYPE_BELIEF, 22 | .truth = Truth_Intersection(truthA, truthB), 23 | .stamp = conclusionStamp, 24 | .occurrenceTime = conclusionTime }; 25 | } 26 | 27 | //{Event a., Event b., after(b,a)} |- Implication b>. 28 | Implication Inference_BeliefInduction(Event *a, Event *b) 29 | { 30 | assert(b->occurrenceTime > a->occurrenceTime, "after(b,a) violated in Inference_BeliefInduction"); 31 | DERIVATION_STAMP_AND_TIME(a,b) 32 | return (Implication) { .sdr = a->sdr, 33 | .truth = Truth_Eternalize(Truth_Induction(truthA, truthB)), 34 | .stamp = conclusionStamp, 35 | .occurrenceTimeOffset = b->occurrenceTime - a->occurrenceTime }; 36 | } 37 | 38 | //{Event a., Event a.} |- Event a. 39 | //{Event a!, Event a!} |- Event a! 40 | static Event Inference_EventRevision(Event *a, Event *b) 41 | { 42 | assert(b->occurrenceTime > a->occurrenceTime, "after(b,a) violated in Inference_BeliefInduction"); 43 | DERIVATION_STAMP_AND_TIME(a,b) 44 | return (Event) { .sdr = a->sdr, 45 | .type = a->type, 46 | .truth = Truth_Revision(truthA, truthB), 47 | .stamp = conclusionStamp, 48 | .occurrenceTime = conclusionTime }; 49 | } 50 | 51 | //{Implication b>., b>.} |- Implication b>. 52 | Implication Inference_ImplicationRevision(Implication *a, Implication *b) 53 | { 54 | DERIVATION_STAMP(a,b) 55 | double occurrenceTimeOffsetAvg = weighted_average(a->occurrenceTimeOffset, b->occurrenceTimeOffset, Truth_c2w(a->truth.confidence), Truth_c2w(b->truth.confidence)); 56 | Implication ret = (Implication) { .sdr = a->sdr, 57 | .truth = Truth_Revision(a->truth, b->truth), 58 | .stamp = conclusionStamp, 59 | .occurrenceTimeOffset = occurrenceTimeOffsetAvg }; 60 | strcpy(ret.debug, a->debug); 61 | return ret; 62 | } 63 | 64 | //{Event b!, Implication b>.} |- Event a! 65 | Event Inference_GoalDeduction(Event *component, Implication *compound) 66 | { 67 | DERIVATION_STAMP(component,compound) 68 | return (Event) { .sdr = compound->sdr, 69 | .type = EVENT_TYPE_GOAL, 70 | .truth = Truth_Deduction(compound->truth, component->truth), 71 | .stamp = conclusionStamp, 72 | .occurrenceTime = component->occurrenceTime - compound->occurrenceTimeOffset }; 73 | } 74 | 75 | //{Event a.} |- Event a. updated to currentTime 76 | Event Inference_EventUpdate(Event *ev, long currentTime) 77 | { 78 | Event ret = *ev; 79 | ret.truth = Truth_Projection(ret.truth, ret.occurrenceTime, currentTime); 80 | return ret; 81 | } 82 | 83 | //{Event (&/,a,op())!, Event a.} |- Event op()! 84 | Event Inference_OperationDeduction(Event *compound, Event *component, long currentTime) 85 | { 86 | DERIVATION_STAMP(component,compound) 87 | Event compoundUpdated = Inference_EventUpdate(compound, currentTime); 88 | Event componentUpdated = Inference_EventUpdate(component, currentTime); 89 | return (Event) { .sdr = compound->sdr, 90 | .type = EVENT_TYPE_GOAL, 91 | .truth = Truth_Deduction(compoundUpdated.truth, componentUpdated.truth), 92 | .stamp = conclusionStamp, 93 | .occurrenceTime = compound->occurrenceTime }; 94 | } 95 | 96 | //{Event a!, Event a!} |- Event a! (revision and choice) 97 | Event Inference_IncreasedActionPotential(Event *existing_potential, Event *incoming_spike, long currentTime) 98 | { 99 | if(existing_potential->type == EVENT_TYPE_DELETED) 100 | { 101 | return *incoming_spike; 102 | } 103 | else 104 | { 105 | double expExisting = Truth_Expectation(Inference_EventUpdate(existing_potential, currentTime).truth); 106 | double expIncoming = Truth_Expectation(Inference_EventUpdate(incoming_spike, currentTime).truth); 107 | //check if there is evidental overlap 108 | bool overlap = Stamp_checkOverlap(&incoming_spike->stamp, &existing_potential->stamp); 109 | //if there is, apply choice, keeping the stronger one: 110 | if(overlap) 111 | { 112 | if(expIncoming > expExisting) 113 | { 114 | return *incoming_spike; 115 | } 116 | } 117 | else 118 | //and else revise, increasing the "activation potential" 119 | { 120 | Event revised_spike = Inference_EventRevision(existing_potential, incoming_spike); 121 | if(revised_spike.truth.confidence >= existing_potential->truth.confidence) 122 | { 123 | return revised_spike; 124 | } 125 | //lower, also use choice 126 | if(expIncoming > expExisting) 127 | { 128 | return *incoming_spike; 129 | } 130 | } 131 | } 132 | return *existing_potential; 133 | } 134 | 135 | //{Event a., Implication b>.} |- Event b. 136 | Event Inference_BeliefDeduction(Event *component, Implication *compound) 137 | { 138 | DERIVATION_STAMP(component,compound) 139 | return (Event) { .sdr = compound->sdr, 140 | .type = EVENT_TYPE_BELIEF, 141 | .truth = Truth_Deduction(compound->truth, component->truth), 142 | .stamp = conclusionStamp, 143 | .occurrenceTime = component->occurrenceTime + compound->occurrenceTimeOffset }; 144 | } 145 | -------------------------------------------------------------------------------- /src/Inference.h: -------------------------------------------------------------------------------- 1 | #ifndef INFERENCE_H 2 | #define INFERENCE_H 3 | 4 | /////////////////// 5 | // INFERENCE // 6 | /////////////////// 7 | //Support for NAL inference on SDR's 8 | //But only a limited set: 9 | //the commented derivations are all that need to happen in ANSNA. 10 | 11 | //References// 12 | //-----------// 13 | #include 14 | #include 15 | #include "Event.h" 16 | #include "Implication.h" 17 | #include "Globals.h" 18 | #include 19 | 20 | //Methods// 21 | //-------// 22 | //{Event a.} |- Event a. updated to currentTime 23 | Event Inference_EventUpdate(Event *ev, long currentTime); 24 | //{Event a., Event b.} |- Event (&/,a,b). 25 | Event Inference_BeliefIntersection(Event *a, Event *b); 26 | //{Event a., Event b.} |- Implication c>. 27 | Implication Inference_BeliefInduction(Event *a, Event *b); 28 | //{Implication b>., b>.} |- Implication b>. 29 | Implication Inference_ImplicationRevision(Implication *a, Implication *b); 30 | //{Event b!, Implication b>.} |- Event a! 31 | Event Inference_GoalDeduction(Event *component, Implication *compound); 32 | //{Event (&/,a,op())!, Event a.} |- Event op()! 33 | Event Inference_OperationDeduction(Event *compound, Event *component, long currentTime); 34 | //{Event a!, Event a!} |- Event a! (essentially revision or choice dependent on evidental overlap) 35 | Event Inference_IncreasedActionPotential(Event *existing_potential, Event *incoming_spike, long currentTime); 36 | //{Event a., Implication b>.} |- Event b. 37 | Event Inference_BeliefDeduction(Event *component, Implication *compound); 38 | #endif 39 | -------------------------------------------------------------------------------- /src/Memory.c: -------------------------------------------------------------------------------- 1 | #include "Memory.h" 2 | 3 | PriorityQueue concepts; 4 | FIFO belief_events; 5 | FIFO goal_events; 6 | Operation operations[OPERATIONS_MAX]; 7 | 8 | double PROPAGATION_THRESHOLD = PROPAGATION_THRESHOLD_INITIAL; 9 | double CONCEPT_FORMATION_NOVELTY = CONCEPT_FORMATION_NOVELTY_INITIAL; 10 | 11 | Concept concept_storage[CONCEPTS_MAX]; 12 | Item concept_items_storage[CONCEPTS_MAX]; 13 | int operations_index = 0; 14 | 15 | static void Memory_ResetEvents() 16 | { 17 | FIFO_RESET(&belief_events); 18 | FIFO_RESET(&goal_events); 19 | } 20 | 21 | static void Memory_ResetConcepts() 22 | { 23 | PriorityQueue_RESET(&concepts, concept_items_storage, CONCEPTS_MAX); 24 | for(int i=0; isdr_hash == sdr_hash) 50 | { 51 | if(SDR_Equal(&existing->sdr, sdr)) 52 | { 53 | if(returnIndex != NULL) 54 | { 55 | *returnIndex = i; 56 | } 57 | return true; 58 | } 59 | } 60 | } 61 | return false; 62 | } 63 | 64 | void Memory_Conceptualize(SDR *sdr) 65 | { 66 | SDR_HASH_TYPE hash = SDR_Hash(sdr); 67 | if(!Memory_FindConceptBySDR(sdr, hash, NULL)) 68 | { 69 | Concept *addedConcept = NULL; 70 | //try to add it, and if successful add to voting structure 71 | PriorityQueue_Push_Feedback feedback = PriorityQueue_Push(&concepts, 0.0); 72 | if(feedback.added) 73 | { 74 | addedConcept = feedback.addedItem.address; 75 | *addedConcept = (Concept) {0}; 76 | Concept_SetSDR(addedConcept, *sdr); 77 | addedConcept->id = concept_id; 78 | concept_id++; 79 | } 80 | } 81 | } 82 | 83 | bool Memory_getClosestConcept(SDR *sdr, SDR_HASH_TYPE sdr_hash, int *returnIndex) 84 | { 85 | if(concepts.itemsAmount == 0) 86 | { 87 | return false; 88 | } 89 | int foundSameConcept_i; 90 | if(Memory_FindConceptBySDR(sdr, sdr_hash, &foundSameConcept_i)) 91 | { 92 | *returnIndex = foundSameConcept_i; 93 | return true; 94 | } 95 | int best_i = -1; 96 | double bestValSoFar = -1; 97 | for(int i=0; isdr))); 100 | if(curVal > bestValSoFar) 101 | { 102 | bestValSoFar = curVal; 103 | best_i = i; 104 | } 105 | } 106 | if(best_i == -1) //TODO how? 107 | { 108 | return false; 109 | } 110 | *returnIndex = best_i; 111 | return true; 112 | } 113 | 114 | bool Memory_addEvent(Event *event) 115 | { 116 | if(event->type == EVENT_TYPE_BELIEF) 117 | { 118 | FIFO_Add(event, &belief_events); //not revised yet 119 | return true; 120 | } 121 | if(event->type == EVENT_TYPE_GOAL) 122 | { 123 | FIFO_Add(event, &goal_events); 124 | return true; 125 | } 126 | assert(false, "errornous event type"); 127 | return true; 128 | } 129 | 130 | void Memory_addConcept(Concept *concept, long currentTime) 131 | { 132 | PriorityQueue_Push_Feedback feedback = PriorityQueue_Push(&concepts, Usage_usefulness(concept->usage, currentTime)); 133 | if(feedback.added) 134 | { 135 | Concept *toRecyle = feedback.addedItem.address; 136 | *toRecyle = *concept; 137 | } 138 | } 139 | 140 | void Memory_addOperation(Operation op) 141 | { 142 | operations[operations_index%OPERATIONS_MAX] = op; 143 | operations_index++; 144 | } 145 | 146 | Event Memory_MatchEventToConcept(Concept *c, Event *e) 147 | { 148 | Event eMatch = *e; 149 | eMatch.sdr = c->sdr; 150 | eMatch.truth = Truth_Deduction(SDR_Inheritance(&e->sdr, &c->sdr), e->truth); 151 | return eMatch; 152 | } 153 | 154 | bool Memory_EventIsNovel(Event *event, Concept *c_matched_to) 155 | { 156 | if(!Memory_FindConceptBySDR(&event->sdr, event->sdr_hash, NULL)) 157 | { 158 | bool different_enough = true; 159 | if(c_matched_to != NULL) 160 | { 161 | double novelty = 1.0 - Truth_Expectation(SDR_Similarity(&event->sdr, &c_matched_to->sdr)); 162 | if(novelty < CONCEPT_FORMATION_NOVELTY) 163 | { 164 | different_enough = false; 165 | } 166 | } 167 | return different_enough; 168 | } 169 | return false; 170 | } 171 | 172 | void Memory_RelinkImplication(Implication *imp) 173 | { 174 | if(imp->sourceConceptSDRHash != ((Concept*) &imp->sourceConcept)->sdr_hash && !SDR_Equal(&imp->sourceConceptSDR, &((Concept*) imp->sourceConcept)->sdr)) 175 | { 176 | int closest_concept_i; 177 | if(Memory_getClosestConcept(&imp->sourceConceptSDR, SDR_Hash(&imp->sourceConceptSDR), &closest_concept_i)) 178 | { 179 | imp->sourceConcept = concepts.items[closest_concept_i].address; 180 | imp->sourceConceptSDR = ((Concept*) imp->sourceConcept)->sdr; 181 | imp->sourceConceptSDRHash = SDR_Hash(&imp->sourceConceptSDR); 182 | } 183 | else 184 | { 185 | assert(false, "No concept to re-link to, call the ghostbusters!\n"); 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /src/Memory.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMORY_H 2 | #define MEMORY_H 3 | 4 | /////////////////// 5 | // ANSNA Memory // 6 | /////////////////// 7 | //The conce-based memory of ANSNA 8 | //See voting mechanism to make it fast: 9 | //https://github.com/patham9/ANSNA/wiki/Voting-Schema 10 | 11 | //References// 12 | ////////////// 13 | #include "Concept.h" 14 | #include "PriorityQueue.h" 15 | 16 | //Parameters// 17 | //----------// 18 | #define CONCEPTS_MAX 1024 //always adjust both 19 | #define USE_HASHING true 20 | #define PROPAGATE_GOAL_SPIKES true 21 | #define PROPAGATION_THRESHOLD_INITIAL 0.501 22 | extern double PROPAGATION_THRESHOLD; 23 | #define PROPAGATION_ITERATIONS 5 24 | #define CONCEPT_FORMATION_NOVELTY_INITIAL 0.2 25 | extern double CONCEPT_FORMATION_NOVELTY; 26 | 27 | //Data structure// 28 | //--------------// 29 | //Data structures 30 | extern PriorityQueue concepts; 31 | extern FIFO belief_events; 32 | extern FIFO goal_events; 33 | typedef void (*Action)(void); 34 | typedef struct 35 | { 36 | SDR sdr; 37 | Action action; 38 | }Operation; 39 | extern Operation operations[OPERATIONS_MAX]; 40 | 41 | //Methods// 42 | //-------// 43 | //Init memory 44 | void Memory_INIT(); 45 | //Find a concept 46 | bool Memory_FindConceptBySDR(SDR *sdr, SDR_HASH_TYPE sdr_hash, int *returnIndex); 47 | //Create a new concept 48 | void Memory_Conceptualize(SDR *sdr); 49 | //Return closest concept 50 | bool Memory_getClosestConcept(SDR *sdr, SDR_HASH_TYPE sdr_hash, int *returnIndex); 51 | //Add an already existing concept to memory that was taken out from the concept priority queue 52 | void Memory_addConcept(Concept *concept, long currentTime); 53 | //Add event to memory 54 | bool Memory_addEvent(Event *event); 55 | //Add operation to memory 56 | void Memory_addOperation(Operation op); 57 | //Match event to concept 58 | Event Memory_MatchEventToConcept(Concept *c, Event *e); 59 | //Whether an event is novel in respect to a concept 60 | bool Memory_EventIsNovel(Event *event, Concept *c_matched_to); 61 | //relink implication, so that link stays intact after forgetting 62 | void Memory_RelinkImplication(Implication *imp); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/PriorityQueue.c: -------------------------------------------------------------------------------- 1 | #include "PriorityQueue.h" 2 | 3 | void PriorityQueue_RESET(PriorityQueue *queue, Item *items, int maxElements) 4 | { 5 | queue->items = items; 6 | queue->maxElements = maxElements; 7 | queue->itemsAmount = 0; 8 | } 9 | 10 | #define at(i) (queue->items[i]) 11 | 12 | static void swap(PriorityQueue *queue, int index1, int index2) 13 | { 14 | Item temp = at(index1); 15 | at(index1) = at(index2); 16 | at(index2) = temp; 17 | } 18 | 19 | static bool isOnMaxLevel(int i) 20 | { 21 | int level=-1; 22 | int n = i+1; 23 | while(n) 24 | { 25 | n = n >> 1; 26 | level++; 27 | } 28 | return level & 1; /*% 2*/; 29 | } 30 | 31 | static int parent(int i) 32 | { 33 | return ((i+1)/2)-1; 34 | } 35 | 36 | static int grandparent(int i) 37 | { 38 | return ((i+1)/4)-1; 39 | } 40 | 41 | static int leftChild(int i) 42 | { 43 | return 2*i + 1; 44 | } 45 | 46 | static int leftGrandChild(int i) 47 | { 48 | return 4*i + 3; 49 | } 50 | 51 | static int smallestChild(PriorityQueue *queue, int i, bool invert) 52 | { //return smallest of children or self if no children 53 | int l = leftChild(i); 54 | if(l >= queue->itemsAmount) 55 | { 56 | return i; //no children, return self 57 | } 58 | int r = l+1; //right child 59 | if(r < queue->itemsAmount) 60 | { 61 | Item lv = at(l); 62 | Item rv = at(r); 63 | if((rv.priority < lv.priority)^invert) 64 | { 65 | return r; 66 | } 67 | } 68 | return l; 69 | } 70 | 71 | static int smallestGrandChild(PriorityQueue *queue, int i, bool invert) 72 | {//return smallest of grandchildren or self if no children 73 | int l = leftGrandChild(i); 74 | if(l >= queue->itemsAmount) 75 | { 76 | return i; 77 | } 78 | Item lv = at(l); 79 | int min = l; 80 | for(int r=l+1; ritemsAmount && r < l+4; r++) 81 | { //iterate on three grandsiblings (they are consecutive) 82 | Item rv = at(r); 83 | if((rv.priority < lv.priority)^invert) 84 | { 85 | lv = rv; 86 | min = r; 87 | } 88 | } 89 | return min; 90 | } 91 | 92 | void trickleDown(PriorityQueue *queue, int i, bool invert) 93 | { //assert(invert == isOnMaxLevel(i)); 94 | while(1) 95 | { 96 | //enforce min-max property on level(i), we need to check children and grandchildren 97 | int m = smallestChild(queue, i, invert); 98 | if(m == i) 99 | { 100 | break; //no children 101 | } 102 | if((at(m).priority < at(i).priority)^invert) //swap children, max property on level(i)+1 automatically enforced 103 | { 104 | swap(queue, i, m); 105 | } 106 | int j = smallestGrandChild(queue, i, invert); 107 | if(j == i) 108 | { 109 | break; //no grandchildren 110 | } 111 | if((at(j).priority < at(i).priority)^invert) 112 | { 113 | swap(queue, i, j); 114 | i = j; //we need to enforce min-max property on level(j) now. 115 | } 116 | else 117 | { 118 | break; //no swap, finish 119 | } 120 | } 121 | } 122 | 123 | void bubbleUp(PriorityQueue *queue, int i) 124 | { 125 | int m; 126 | m = parent(i); 127 | bool invert = isOnMaxLevel(i); 128 | if(m>=0 && ((at(i).priority > at(m).priority)^invert)) 129 | { 130 | swap(queue, i, m); 131 | i = m; 132 | invert = !invert; 133 | } 134 | m = grandparent(i); 135 | while(m>=0 && ((at(i).priority < at(m).priority)^invert)) 136 | { 137 | swap(queue, i, m); 138 | i = m; 139 | m = grandparent(i); 140 | } 141 | } 142 | 143 | static bool PriorityQueue_PopMin(PriorityQueue *queue, void** returnItemAddress) 144 | { 145 | if(queue->itemsAmount == 0) 146 | { 147 | return false; 148 | } 149 | Item item = at(0); 150 | swap(queue, 0, queue->itemsAmount-1); 151 | queue->itemsAmount--; 152 | trickleDown(queue, 0, false); //enforce minmax heap property 153 | *returnItemAddress = item.address; 154 | return true; 155 | } 156 | 157 | PriorityQueue_Push_Feedback PriorityQueue_Push(PriorityQueue *queue, double priority) 158 | { 159 | PriorityQueue_Push_Feedback feedback = (PriorityQueue_Push_Feedback) {0}; 160 | //first evict if necessary 161 | if(queue->itemsAmount >= queue->maxElements) 162 | { 163 | double minPriority = at(0).priority; 164 | if(priority < minPriority) 165 | { //smaller than smallest 166 | return feedback; 167 | } 168 | feedback.evicted = true; 169 | feedback.evictedItem.priority = minPriority; 170 | PriorityQueue_PopMin(queue, &feedback.evictedItem.address); 171 | } 172 | at(queue->itemsAmount).priority = priority; 173 | if(feedback.evicted) 174 | { 175 | at(queue->itemsAmount).address = feedback.evictedItem.address; 176 | } 177 | feedback.added = true; 178 | feedback.addedItem = at(queue->itemsAmount); 179 | queue->itemsAmount++; 180 | bubbleUp(queue, queue->itemsAmount-1); 181 | return feedback; 182 | } 183 | 184 | bool PriorityQueue_PopAt(PriorityQueue *queue, int i, void** returnItemAddress) 185 | { 186 | if(queue->itemsAmount == 0) 187 | { 188 | return false; 189 | } 190 | Item item = at(i); 191 | swap(queue, i, queue->itemsAmount-1); 192 | queue->itemsAmount--; 193 | trickleDown(queue, i, true); //enforce minmax heap property 194 | if(returnItemAddress != NULL) 195 | { 196 | *returnItemAddress = item.address; 197 | } 198 | return true; 199 | } 200 | 201 | void PriorityQueue_Rebuild(PriorityQueue *queue) 202 | { 203 | for(int i=0; iitemsAmount; i++) 204 | { 205 | bubbleUp(queue, i); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/PriorityQueue.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIORITYQUEUE_H 2 | #define PRIORITYQUEUE_H 3 | 4 | ///////////////////// 5 | // Priority queue // 6 | ///////////////////// 7 | //The priority queue for concepts and tasks 8 | //Related publication: Atkinson, M. D., Sack, J. R., Santoro, N., & Strothotte, T. (1986). Min-max heaps and generalized priority queues. Communications of the ACM, 29(10), 996-1000. 9 | //Ported from https://github.com/quxiaofeng/python-stl/blob/master/meshlab/MeshLabSrc_AllInc_v132/meshlab/src/plugins_experimental/edit_ocme/src/cache/old/mmheap.h 10 | 11 | //References// 12 | //-----------// 13 | #include 14 | #include 15 | 16 | //Data structure// 17 | //--------------// 18 | typedef struct 19 | { 20 | double priority; 21 | void *address; 22 | } Item; 23 | 24 | typedef struct 25 | { 26 | Item *items; 27 | int itemsAmount; 28 | int maxElements; 29 | } PriorityQueue; 30 | 31 | typedef struct 32 | { 33 | bool added; 34 | Item addedItem; 35 | bool evicted; 36 | Item evictedItem; 37 | } PriorityQueue_Push_Feedback; 38 | 39 | //Methods// 40 | //-------// 41 | //Resets the priority queue 42 | void PriorityQueue_RESET(PriorityQueue *queue, Item *items, int maxElements); 43 | //Push element of a certain priority into the queue. 44 | //If successful, addedItem will point to the item in the data structure, with address of the evicted item, if eviction happened 45 | PriorityQueue_Push_Feedback PriorityQueue_Push(PriorityQueue *queue, double priority); 46 | //use this function and add again if maybe lower! 47 | bool PriorityQueue_PopAt(PriorityQueue *queue, int i, void** returnItemAddress); 48 | //Rebuilds the data structure by re-inserting all elements: 49 | void PriorityQueue_Rebuild(PriorityQueue *queue); 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /src/SDR.c: -------------------------------------------------------------------------------- 1 | #include "SDR.h" 2 | 3 | int SDR_ReadBitInBlock(SDR *sdr, int block_i, int block_bit_j) 4 | { 5 | return (sdr->blocks[block_i] >> block_bit_j) & 1; 6 | } 7 | 8 | void SDR_WriteBitInBlock(SDR *sdr, int block_i, int block_bit_j, int value) 9 | { 10 | sdr->blocks[block_i] = (sdr->blocks[block_i] & (~(((SDR_BLOCK_TYPE)1) << block_bit_j))) | (((SDR_BLOCK_TYPE)value) << block_bit_j); 11 | } 12 | 13 | int SDR_ReadBit(SDR *sdr, int bit_i) 14 | { 15 | SDR_INDEX_TO_BLOCK_AND_BIT(bit_i, block_i,block_bit_i) 16 | return SDR_ReadBitInBlock(sdr, block_i, block_bit_i); 17 | } 18 | 19 | void SDR_WriteBit(SDR *sdr, int bit_i, int value) 20 | { 21 | SDR_INDEX_TO_BLOCK_AND_BIT(bit_i, block_i,block_bit_i) 22 | SDR_WriteBitInBlock(sdr, block_i, block_bit_i, value); 23 | } 24 | 25 | void SDR_Print(SDR *sdr) 26 | { 27 | ITERATE_SDR_BITS(i,j, 28 | if (SDR_ReadBitInBlock(sdr,i,j)) 29 | { 30 | printf("[%d](%d,%d)\n", (int) (i*SDR_BLOCK_SIZE+j), i, j); 31 | } 32 | ) 33 | puts("==="); 34 | } 35 | 36 | int SDR_CountTrue(SDR *sdr) 37 | { 38 | int cnt = 0; 39 | ITERATE_SDR_BITS(i,j, 40 | if (SDR_ReadBitInBlock(sdr,i,j)) 41 | { 42 | cnt++; 43 | } 44 | ) 45 | return cnt; 46 | } 47 | 48 | //Xor of both SDR's 49 | static SDR SDR_Xor(SDR *a, SDR *b) 50 | { 51 | SDR c; 52 | ITERATE_SDR_BLOCKS(i, 53 | c.blocks[i] = a->blocks[i] ^ b->blocks[i]; 54 | ) 55 | return c; 56 | } 57 | 58 | SDR SDR_PermuteByRotation(SDR *sdr, bool forward) 59 | { 60 | SDR c = *sdr; 61 | int shiftToLeftmost = SDR_BLOCK_SIZE-1; 62 | if(forward) 63 | { 64 | for(unsigned int i=0; i 0); 68 | } 69 | } 70 | else 71 | { 72 | for(unsigned int i=0; i>1) | (right_bit << shiftToLeftmost); 76 | } 77 | } 78 | return c; 79 | } 80 | 81 | //permutation for tuple encoding 82 | int SDR_permS[SDR_SIZE]; 83 | int SDR_permS_inv[SDR_SIZE]; 84 | int SDR_permP[SDR_SIZE]; 85 | int SDR_permP_inv[SDR_SIZE]; 86 | 87 | SDR SDR_Tuple(SDR *a, SDR *b) 88 | { 89 | SDR aPerm = SDR_Permute(a,SDR_permS); 90 | SDR bPerm = SDR_Permute(b,SDR_permP); 91 | return SDR_Xor(&aPerm, &bPerm); 92 | } 93 | 94 | SDR SDR_TupleGetFirstElement(SDR *compound, SDR *secondElement) 95 | { 96 | SDR bPerm = SDR_Permute(secondElement, SDR_permP); 97 | SDR sdrxor = SDR_Xor(&bPerm, compound); 98 | SDR a = SDR_Permute(&sdrxor, SDR_permS_inv); 99 | return a; 100 | } 101 | 102 | SDR SDR_TupleGetSecondElement(SDR *compound, SDR *firstElement) 103 | { 104 | SDR aPerm = SDR_Permute(firstElement, SDR_permS); 105 | SDR sdrxor = SDR_Xor(&aPerm, compound); 106 | SDR b = SDR_Permute(&sdrxor, SDR_permP_inv); 107 | return b; 108 | } 109 | 110 | bool SDR_Equal(SDR *a, SDR *b) 111 | { 112 | ITERATE_SDR_BLOCKS(i, 113 | if(a->blocks[i] != b->blocks[i]) 114 | { 115 | return false; 116 | } 117 | ) 118 | return true; 119 | } 120 | 121 | Truth SDR_Inheritance(SDR *full, SDR *part) 122 | { 123 | int countOneInBoth = 0; 124 | int generalCaseMisses1Bit = 0; 125 | ITERATE_SDR_BITS(i,j, 126 | countOneInBoth += (SDR_ReadBitInBlock(part,i,j) & SDR_ReadBitInBlock(full,i,j)); 127 | generalCaseMisses1Bit += (~SDR_ReadBitInBlock(part,i,j) & SDR_ReadBitInBlock(full,i,j)); 128 | ) 129 | double E_total = countOneInBoth + generalCaseMisses1Bit; 130 | double f_total = ((double) countOneInBoth)/E_total; 131 | Truth truth = { .frequency = f_total, .confidence = Truth_w2c(E_total)}; 132 | return truth; 133 | } 134 | 135 | Truth SDR_Similarity(SDR *a, SDR *b) 136 | { 137 | return Truth_Intersection(SDR_Inheritance(a,b), SDR_Inheritance(b,a)); 138 | } 139 | 140 | SDR_HASH_TYPE SDR_Hash(SDR *sdr) 141 | { 142 | SDR_HASH_TYPE hash = 0; 143 | ITERATE_SDR_BLOCKS(i, 144 | int pieces = SDR_BLOCK_SIZE / SDR_HASH_TYPE_SIZE; 145 | for(int j=0; jblocks[i] >> shift_right); 149 | } 150 | ) 151 | return hash; 152 | } 153 | 154 | void SDR_GeneratePermutation(int *perm, int *perm_inverse) 155 | { 156 | for(int i=0; i 16 | #include 17 | #include 18 | #include 19 | #include "Truth.h" 20 | 21 | //Parameters// 22 | //----------// 23 | #define SDR_SIZE 2048 24 | #ifndef SDR_BLOCK_TYPE 25 | #define SDR_BLOCK_TYPE uintmax_t 26 | #endif 27 | #define SDR_BLOCK_SIZE (8*sizeof(SDR_BLOCK_TYPE)) 28 | #define SDR_HASH_TYPE uint64_t 29 | #define SDR_HASH_TYPE_SIZE (8*sizeof(SDR_HASH_TYPE)) 30 | 31 | //Data structure// 32 | //--------------// 33 | #define SDR_NUM_BLOCKS SDR_SIZE / SDR_BLOCK_SIZE 34 | typedef struct 35 | { 36 | SDR_BLOCK_TYPE blocks[SDR_NUM_BLOCKS]; 37 | }SDR; 38 | 39 | //Macros// 40 | //-------// 41 | //Iterate all the blocks of an SDR 42 | #define ITERATE_SDR_BLOCKS(I,CODE) {\ 43 | for(unsigned int I=0; IevidentalBase[i] != STAMP_FREE) 13 | { 14 | ret.evidentalBase[j] = stamp1->evidentalBase[i]; 15 | j++; 16 | if(j >= STAMP_SIZE) 17 | { 18 | break; 19 | } 20 | } 21 | else 22 | { 23 | processStamp1 = false; 24 | } 25 | } 26 | if(processStamp2) 27 | { 28 | if(stamp2->evidentalBase[i] != STAMP_FREE) 29 | { 30 | ret.evidentalBase[j] = stamp2->evidentalBase[i]; 31 | j++; 32 | if(j >= STAMP_SIZE) 33 | { 34 | break; 35 | } 36 | } 37 | else 38 | { 39 | processStamp2 = false; 40 | } 41 | } 42 | if(!processStamp1 && !processStamp2) 43 | { 44 | break; 45 | } 46 | } 47 | return ret; 48 | } 49 | 50 | bool Stamp_checkOverlap(Stamp *a, Stamp *b) 51 | { 52 | for (int i=0;ievidentalBase[i] == STAMP_FREE) 55 | { 56 | break; 57 | } 58 | for (int j=0;jevidentalBase[j] == STAMP_FREE) 61 | { 62 | break; 63 | } 64 | if (a->evidentalBase[i] == b->evidentalBase[j]) 65 | { 66 | return true; 67 | } 68 | } 69 | } 70 | return false; 71 | } 72 | 73 | void Stamp_print(Stamp *stamp) 74 | { 75 | fputs("stamp=", stdout); 76 | for(int i=0; ievidentalBase[i] == STAMP_FREE) 79 | { 80 | break; 81 | } 82 | printf("%ld,", stamp->evidentalBase[i]); 83 | } 84 | puts(""); 85 | } 86 | -------------------------------------------------------------------------------- /src/Stamp.h: -------------------------------------------------------------------------------- 1 | #ifndef STAMP_H 2 | #define STAMP_H 3 | 4 | ////////////////////// 5 | // Stamp // 6 | ////////////////////// 7 | //keeps track of evidental bases 8 | 9 | //References// 10 | //----------// 11 | #include 12 | #include 13 | 14 | //Parameters// 15 | //----------// 16 | #define STAMP_SIZE 20 17 | #define STAMP_FREE 0 18 | 19 | //Data structure// 20 | //--------------// 21 | //Stamp as implemented by all NARS implementations 22 | typedef struct { 23 | //EvidentalBase of stamp 24 | long evidentalBase[STAMP_SIZE]; 25 | } Stamp; 26 | 27 | //Methods// 28 | //-------// 29 | //zip stamp1 and stamp2 into a stamp 30 | Stamp Stamp_make(Stamp *stamp1, Stamp *stamp2); 31 | //true iff there is evidental base overlap between a and b 32 | bool Stamp_checkOverlap(Stamp *a, Stamp *b); 33 | //print stamp 34 | void Stamp_print(Stamp *stamp); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/Table.c: -------------------------------------------------------------------------------- 1 | #include "Table.h" 2 | 3 | Implication *Table_Add(Table *table, Implication *imp) 4 | { 5 | double impTruthExp = Truth_Expectation(imp->truth); 6 | for(int i=0; iarray[i].sdr_hash == imp->sdr_hash &&*/ SDR_Equal(&table->array[i].sdr,&imp->sdr)); 9 | //either it's not yet full and we reached a new space, 10 | //or the term is different and the truth expectation is higher 11 | //or the term is the same and the confidence is higher 12 | if(i==table->itemsAmount || (!same_term && impTruthExp > Truth_Expectation(table->array[i].truth)) || (same_term && imp->truth.confidence > table->array[i].truth.confidence)) 13 | { 14 | //ok here it has to go, move down the rest, evicting the last element if we hit TABLE_SIZE-1. 15 | for(int j=MIN(table->itemsAmount, TABLE_SIZE-1); j>i; j--) 16 | { 17 | table->array[j] = table->array[j-1]; 18 | } 19 | table->array[i] = *imp; 20 | table->itemsAmount = MIN(table->itemsAmount+1, TABLE_SIZE); 21 | return &table->array[i]; 22 | } 23 | } 24 | return NULL; 25 | } 26 | 27 | static void Table_Remove(Table *table, int index) 28 | { 29 | //move up the rest beginning at index 30 | for(int j=index; jitemsAmount; j++) 31 | { 32 | table->array[j] = j == table->itemsAmount-1 ? (Implication) {0} : table->array[j+1]; 33 | } 34 | table->itemsAmount = MAX(0, table->itemsAmount-1); 35 | } 36 | 37 | static void Table_SantiyCheck(Table *table) 38 | { 39 | for(int i=0; iitemsAmount; i++) 40 | { 41 | for(int j=0; jitemsAmount; j++) 42 | { 43 | if(i != j) 44 | { 45 | assert(!SDR_Equal(&table->array[i].sdr, &table->array[j].sdr), "THEY CANNOT BE THE SAME\n"); 46 | } 47 | } 48 | } 49 | } 50 | 51 | Implication *Table_AddAndRevise(Table *table, Implication *imp, char *debug) 52 | { 53 | IN_DEBUG ( Table_SantiyCheck(table); ) 54 | //1. find element with same SDR 55 | int same_i = -1; 56 | for(int i=0; iitemsAmount; i++) 57 | { 58 | if(/*imp->sdr_hash == table->array[i].sdr_hash &&*/ SDR_Equal(&imp->sdr, &table->array[i].sdr)) 59 | { 60 | same_i = i; 61 | break; 62 | } 63 | } 64 | //2. if there was one, revise with it or apply choice if overlap 65 | if(same_i != -1) 66 | { 67 | //revision adds the revised element, removing the old implication from the table 68 | Implication OldImp = table->array[same_i]; 69 | assert(OldImp.truth.frequency >= 0.0 && OldImp.truth.frequency <= 1.0, "(1) frequency out of bounds"); 70 | assert(OldImp.truth.confidence >= 0.0 && OldImp.truth.confidence <= 1.0, "(1) confidence out of bounds"); 71 | assert(imp->truth.frequency >= 0.0 && imp->truth.frequency <= 1.0, "(2) frequency out of bounds"); 72 | assert(imp->truth.confidence >= 0.0 && imp->truth.confidence <= 1.0, "(2) confidence out of bounds"); 73 | Implication revised = Inference_ImplicationRevision(&OldImp, imp); 74 | assert(revised.truth.frequency >= 0.0 && revised.truth.frequency <= 1.0, "(3) frequency out of bounds"); 75 | assert(revised.truth.confidence >= 0.0 && revised.truth.confidence <= 1.0, "(3) confidence out of bounds"); 76 | strcpy(revised.debug, debug); 77 | Implication_SetSDR(&revised, imp->sdr); 78 | //printf("AAA %s %.02f,%.02f\n", revised.debug, revised.truth.frequency, revised.truth.confidence); 79 | Table_Remove(table, same_i); 80 | //printf("REVISED\n"); 81 | Implication *ret = Table_Add(table, &revised); 82 | assert(ret != NULL, "Deletion and re-addition should have succeeded"); 83 | return ret; 84 | } 85 | else 86 | { 87 | //3. add imp too: 88 | strcpy(imp->debug, debug); 89 | //printf("ADDED\n"); 90 | return Table_Add(table, imp); 91 | } 92 | return NULL; 93 | } 94 | -------------------------------------------------------------------------------- /src/Table.h: -------------------------------------------------------------------------------- 1 | #ifndef TABLE_H 2 | #define TABLE_H 3 | 4 | ////////////////////// 5 | // Table // 6 | ////////////////////// 7 | //A table of implications, ranked by truth expectation 8 | 9 | //References// 10 | //----------// 11 | #include "Inference.h" 12 | #include "Globals.h" 13 | #include 14 | 15 | //Parameters// 16 | //----------// 17 | #define TABLE_SIZE 20 18 | 19 | //Data structure// 20 | //--------------// 21 | //A truth-expectation-ranked table for Implications, similar as pre- and post-condition table in OpenNARS, 22 | //except that this table supports revision by itself (as in ANSNA implications don't form concepts). 23 | typedef struct { 24 | Implication array[TABLE_SIZE]; 25 | int itemsAmount; 26 | } Table; 27 | 28 | //Methods// 29 | //-------// 30 | //Add implication to table 31 | Implication *Table_Add(Table *table, Implication *imp); 32 | //Add implication to table while allowing revision 33 | Implication* Table_AddAndRevise(Table *table, Implication *imp, char *debug); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/Truth.c: -------------------------------------------------------------------------------- 1 | #include "Truth.h" 2 | 3 | double TRUTH_EVIDENTAL_HORIZON = TRUTH_EVIDENTAL_HORIZON_INITIAL; 4 | double TRUTH_PROJECTION_DECAY = TRUTH_PROJECTION_DECAY_INITIAL; 5 | 6 | double Truth_w2c(double w) 7 | { 8 | return w / (w + TRUTH_EVIDENTAL_HORIZON); 9 | } 10 | 11 | double Truth_c2w(double c) 12 | { 13 | return TRUTH_EVIDENTAL_HORIZON * c / (1 - c); 14 | } 15 | 16 | double Truth_Expectation(Truth v) 17 | { 18 | return (v.confidence * (v.frequency - 0.5) + 0.5); 19 | } 20 | 21 | Truth Truth_Revision(Truth v1, Truth v2) 22 | { 23 | double f1 = v1.frequency; 24 | double f2 = v2.frequency; 25 | double w1 = Truth_c2w(v1.confidence); 26 | double w2 = Truth_c2w(v2.confidence); 27 | double w = w1 + w2; 28 | double f = MIN(1.0, (w1 * f1 + w2 * f2) / w); 29 | double c = Truth_w2c(w); 30 | return (Truth) {.frequency = f, .confidence = MIN(1.0-TRUTH_EPSILON, MAX(MAX(c, v1.confidence), v2.confidence))}; 31 | } 32 | 33 | Truth Truth_Deduction(Truth v1, Truth v2) 34 | { 35 | double f1 = v1.frequency; 36 | double f2 = v2.frequency; 37 | double c1 = v1.confidence; 38 | double c2 = v2.confidence; 39 | double f = f1 * f2; 40 | double c = c1 * c2 * f; 41 | return (Truth) {.frequency = f, .confidence = c}; 42 | } 43 | 44 | Truth Truth_Induction(Truth v1, Truth v2) 45 | { 46 | double f1 = v2.frequency; 47 | double f2 = v1.frequency; 48 | double c1 = v2.confidence; 49 | double c2 = v1.confidence; 50 | double w = f2 * c1 * c2; 51 | double c = Truth_w2c(w); 52 | return (Truth) {.frequency = f1, .confidence = c};; 53 | } 54 | 55 | Truth Truth_Intersection(Truth v1, Truth v2) 56 | { 57 | double f1 = v1.frequency; 58 | double f2 = v2.frequency; 59 | double c1 = v1.confidence; 60 | double c2 = v2.confidence; 61 | double f = f1 * f2; 62 | double c = c1 * c2; 63 | return (Truth) {.frequency = f, .confidence = c}; 64 | } 65 | 66 | Truth Truth_Eternalize(Truth v) 67 | { 68 | float f = v.frequency; 69 | float c = v.confidence; 70 | return (Truth) {.frequency = f, .confidence = Truth_w2c(c)}; 71 | } 72 | 73 | Truth Truth_Projection(Truth v, long originalTime, long targetTime) 74 | { 75 | double difference = labs(targetTime - originalTime); 76 | return (Truth) { .frequency = v.frequency, .confidence = v.confidence * pow(TRUTH_PROJECTION_DECAY,difference)}; 77 | } 78 | 79 | void Truth_Print(Truth *truth) 80 | { 81 | printf("Truth: frequency=%f, confidence=%f\n", truth->frequency, truth->confidence); 82 | } 83 | -------------------------------------------------------------------------------- /src/Truth.h: -------------------------------------------------------------------------------- 1 | #ifndef TRUTH_H 2 | #define TRUTH_H 3 | 4 | //////////////////////////////////////////// 5 | // ANSNA truth value and truth functions // 6 | //////////////////////////////////////////// 7 | 8 | //References// 9 | //-----------// 10 | #include 11 | #include 12 | #include 13 | #include "Globals.h" 14 | 15 | //Data structure// 16 | //--------------// 17 | typedef struct { 18 | //Frequency 19 | double frequency; 20 | //Confidence 21 | double confidence; 22 | } Truth; 23 | 24 | //Parameters// 25 | //----------// 26 | #define TRUTH_EVIDENTAL_HORIZON_INITIAL 1.0 27 | extern double TRUTH_EVIDENTAL_HORIZON; 28 | #define TRUTH_PROJECTION_DECAY_INITIAL 0.8 29 | extern double TRUTH_PROJECTION_DECAY; 30 | #define TRUTH_EPSILON 0.01 31 | 32 | //Methods// 33 | //-------// 34 | double Truth_w2c(double w); 35 | double Truth_c2w(double c); 36 | double Truth_Expectation(Truth v); 37 | Truth Truth_Revision(Truth v1, Truth v2); 38 | Truth Truth_Deduction(Truth v1, Truth v2); 39 | Truth Truth_Induction(Truth v1, Truth v2); 40 | Truth Truth_Intersection(Truth v1, Truth v2); 41 | Truth Truth_Eternalize(Truth v); 42 | Truth Truth_Projection(Truth v, long originalTime, long targetTime); 43 | void Truth_Print(Truth *truth); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/Usage.c: -------------------------------------------------------------------------------- 1 | #include "Usage.h" 2 | 3 | double Usage_usefulness(Usage usage, long currentTime) 4 | { 5 | double age = currentTime - usage.lastUsed; 6 | double usefulnessToNormalize = ((double) usage.useCount) / (age + 1.0); 7 | return usefulnessToNormalize / (usefulnessToNormalize + 1.0); 8 | } 9 | 10 | Usage Usage_use(Usage usage, long currentTime) 11 | { 12 | return (Usage) { .useCount = usage.useCount+1, 13 | .lastUsed = currentTime }; 14 | } 15 | 16 | void Usage_Print(Usage *usage) 17 | { 18 | printf("Usage: useCount=%d lastUsed=%d\n", usage->useCount, usage->lastUsed); 19 | } 20 | -------------------------------------------------------------------------------- /src/Usage.h: -------------------------------------------------------------------------------- 1 | #ifndef USEFULNESSVALUE_H 2 | #define USEFULNESSVALUE_H 3 | 4 | ///////////////////////////// 5 | // ANSNA usefulness value // 6 | ///////////////////////////// 7 | 8 | //References// 9 | //-----------// 10 | #include 11 | 12 | //Data structure// 13 | //--------------// 14 | typedef struct { 15 | //use_count, how often it was used in total 16 | int useCount; 17 | //age, how many cycles ago it was last used 18 | int lastUsed; 19 | } Usage; 20 | 21 | //Methods// 22 | //-------// 23 | //how useful it is in respect to the current moment 24 | double Usage_usefulness(Usage usage, long currentTime); 25 | //use the item 26 | Usage Usage_use(Usage usage, long currentTime); 27 | //print it 28 | void Usage_Print(Usage *usage); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "SDR.h" 6 | #include "Memory.h" 7 | #include "Encode.h" 8 | #include "ANSNA.h" 9 | 10 | void SDR_Test() 11 | { 12 | puts(">>SDR Test Start"); 13 | puts("testing encoding and permutation:"); 14 | SDR mySDR = Encode_Term("term1"); 15 | int previous = SDR_ReadBit(&mySDR, 0); 16 | assert(SDR_ReadBitInBlock(&mySDR,0,0) == previous, "SDR ReadBitInBlock mismatch with SDR_ReadBit"); 17 | SDR_WriteBit(&mySDR, 0, previous); 18 | assert(SDR_ReadBit(&mySDR, 0) == previous, "SDR was written to with same value, shouldn't have changed"); 19 | assert(SDR_CountTrue(&mySDR) == TERM_ONES, "SDR term should have TERM_ONES ones"); 20 | SDR sdr2 = SDR_PermuteByRotation(&mySDR, true); 21 | SDR mySDR_Recons1 = SDR_PermuteByRotation(&sdr2, false); 22 | assert(SDR_Equal(&mySDR_Recons1, &mySDR), "Inverse rotation should lead to original result"); 23 | int perm[SDR_SIZE]; 24 | int perm_inv[SDR_SIZE]; 25 | SDR_GeneratePermutation(perm, perm_inv); 26 | SDR sdr3 = SDR_Permute(&mySDR, perm); 27 | SDR mySDR_recons2 = SDR_Permute(&sdr3, perm_inv); 28 | assert(SDR_Equal(&mySDR_recons2, &mySDR), "Inverse permutation should lead to original result"); 29 | puts("testing tuples now:"); 30 | SDR mySDR2 = Encode_Term("term2"); 31 | fputs("recons:", stdout); 32 | SDR tuple = SDR_Tuple(&mySDR, &mySDR2); 33 | SDR SDR1Recons = SDR_TupleGetFirstElement(&tuple, &mySDR2); 34 | SDR SDR2Recons = SDR_TupleGetSecondElement(&tuple, &mySDR); 35 | Truth selfTest = SDR_Similarity(&mySDR, &mySDR); 36 | printf("sdr1 sdr1 similarity: %f %f\n", selfTest.frequency, selfTest.confidence); 37 | assert(selfTest.frequency == 1, "No negative evidence is allowed to be found when matching to itself"); 38 | Truth t1 = SDR_Similarity(&mySDR, &SDR1Recons); 39 | assert(t1.frequency == 1, "Reconstructed tuple element1 should be almost the same as the original"); 40 | Truth t2 = SDR_Similarity(&mySDR2, &SDR2Recons); 41 | assert(t2.frequency == 1, "Reconstructed tuple element2 should be almost the same as the original"); 42 | Truth t3 = SDR_Similarity(&mySDR, &SDR2Recons); 43 | assert(t3.frequency < 0.5, "These elements should mostly differ"); 44 | Truth t4 = SDR_Similarity(&mySDR2, &SDR1Recons); 45 | assert(t4.frequency < 0.5, "These elements should mostly differ too"); 46 | puts("<>FIFO test start"); 52 | FIFO fifo = {0}; 53 | //First, evaluate whether the fifo works, not leading to overflow 54 | for(int i=FIFO_SIZE*2; i>=1; i--) //"rolling over" once by adding a k*FIFO_Size items 55 | { 56 | Event event1 = { .sdr = Encode_Term("test"), 57 | .type = EVENT_TYPE_BELIEF, 58 | .truth = { .frequency = 1.0, .confidence = 0.9 }, 59 | .stamp = { .evidentalBase = { i } }, 60 | .occurrenceTime = FIFO_SIZE*2 - i*10 }; 61 | FIFO_Add(&event1, &fifo); 62 | } 63 | for(int i=0; isdr),buf); 86 | } 87 | } 88 | assert(fifo2.itemsAmount == FIFO_SIZE, "FIFO size differs"); 89 | puts("<>Stamp test start"); 95 | Stamp stamp1 = { .evidentalBase = {1,2} }; 96 | Stamp_print(&stamp1); 97 | Stamp stamp2 = { .evidentalBase = {2,3,4} }; 98 | Stamp_print(&stamp2); 99 | Stamp stamp3 = Stamp_make(&stamp1, &stamp2); 100 | fputs("zipped:", stdout); 101 | Stamp_print(&stamp3); 102 | assert(Stamp_checkOverlap(&stamp1,&stamp2) == true, "Stamp should overlap"); 103 | puts("<>PriorityQueue test start"); 109 | PriorityQueue queue; 110 | int n_items = 10; 111 | Item items[n_items]; 112 | for(int i=0; i0 || feedback.evictedItem.priority == ((double)(1.0/((double) (n_items*2)))), "the evicted item has to be the lowest priority one"); 129 | assert(queue.itemsAmount < n_items+1, "eviction should only happen when full!"); 130 | evictions++; 131 | } 132 | } 133 | puts("<>Table test start"); 139 | Table table = {0}; 140 | for(int i=TABLE_SIZE*2; i>=1; i--) 141 | { 142 | Implication imp = { .sdr = Encode_Scalar(1,TABLE_SIZE*2,i), 143 | .truth = { .frequency = 1.0, .confidence = 1.0/((double)(i+1)) }, 144 | .stamp = { .evidentalBase = { i } }, 145 | .occurrenceTimeOffset = 10 }; 146 | Table_Add(&table, &imp); 147 | } 148 | for(int i=0; i0.5, "The revision result should be more confident than the table element that existed."); 159 | puts("<>Memory test start"); 166 | Event e = Event_InputEvent(Encode_Term("a"), 167 | EVENT_TYPE_BELIEF, 168 | (Truth) { .frequency = 1, .confidence = 0.9 }, 169 | 1337); 170 | Memory_addEvent(&e); 171 | assert(belief_events.array[0][0].truth.confidence == (double) 0.9, "event has to be there"); //identify 172 | int returnIndex; 173 | assert(!Memory_getClosestConcept(&e.sdr, e.sdr_hash, &returnIndex), "a concept doesn't exist yet!"); 174 | Memory_Conceptualize(&e.sdr); 175 | int concept_i; 176 | assert(Memory_FindConceptBySDR(&e.sdr, SDR_Hash(&e.sdr), &concept_i), "Concept should have been created!"); 177 | Concept *c = concepts.items[concept_i].address; 178 | assert(Memory_FindConceptBySDR(&e.sdr, e.sdr_hash, &returnIndex), "Concept should be found!"); 179 | assert(c == concepts.items[returnIndex].address, "e should match to c!"); 180 | assert(Memory_getClosestConcept(&e.sdr, e.sdr_hash, &returnIndex), "Concept should be found!"); 181 | assert(c == concepts.items[returnIndex].address, "e should match to c!"); 182 | Event e2 = Event_InputEvent(Encode_Term("b"), 183 | EVENT_TYPE_BELIEF, 184 | (Truth) { .frequency = 1, .confidence = 0.9 }, 185 | 1337); 186 | Memory_addEvent(&e2); 187 | Memory_Conceptualize(&e2.sdr); 188 | assert(Memory_FindConceptBySDR(&e2.sdr, SDR_Hash(&e2.sdr), &concept_i), "Concept should have been created!"); 189 | Concept *c2 = concepts.items[concept_i].address; 190 | Concept_Print(c2); 191 | assert(Memory_getClosestConcept(&e2.sdr, e2.sdr_hash, &returnIndex), "Concept should be found!"); 192 | assert(c2 == concepts.items[returnIndex].address, "e2 should closest-match to c2!"); 193 | assert(Memory_getClosestConcept(&e.sdr, e.sdr_hash, &returnIndex), "Concept should be found!"); 194 | assert(c == concepts.items[returnIndex].address, "e should closest-match to c!"); 195 | puts("<>ANSNA Alphabet test start"); 202 | ANSNA_AddInput(Encode_Term("a"), EVENT_TYPE_BELIEF, ANSNA_DEFAULT_TRUTH); 203 | for(int i=0; i<50; i++) 204 | { 205 | int k=i%10; 206 | if(i % 3 == 0) 207 | { 208 | char c[2] = {'a'+k,0}; 209 | ANSNA_AddInput(Encode_Term(c), EVENT_TYPE_BELIEF, ANSNA_DEFAULT_TRUTH); 210 | } 211 | ANSNA_Cycles(1); 212 | puts("TICK"); 213 | } 214 | puts("<>ANSNA Procedure test start"); 227 | ANSNA_AddOperation(Encode_Term("op"), ANSNA_Procedure_Test_Op); 228 | ANSNA_AddInputBelief(Encode_Term("a")); 229 | ANSNA_Cycles(10); 230 | puts("---------------"); 231 | ANSNA_AddInputBelief(Encode_Term("op")); 232 | ANSNA_Cycles(10); 233 | puts("---------------"); 234 | ANSNA_AddInputBelief(Encode_Term("result")); 235 | ANSNA_Cycles(10); 236 | puts("---------------"); 237 | ANSNA_AddInputBelief(Encode_Term("a")); 238 | ANSNA_Cycles(10); 239 | puts("---------------"); 240 | ANSNA_AddInputGoal(Encode_Term("result")); 241 | ANSNA_Cycles(10); 242 | puts("---------------"); 243 | assert(ANSNA_Procedure_Test_Op_executed, "ANSNA should have executed op!"); 244 | puts("<>ANSNA Follow test start"); 264 | ANSNA_AddOperation(Encode_Term("op_left"), ANSNA_Follow_Test_Left); 265 | ANSNA_AddOperation(Encode_Term("op_right"), ANSNA_Follow_Test_Right); 266 | int simsteps = 1000000; 267 | int LEFT = 0; 268 | int RIGHT = 1; 269 | int BALL = RIGHT; 270 | int score = 0; 271 | int goods = 0; 272 | int bads = 0; 273 | for(int i=0;i -100, "too bad score"); 317 | assert(bads < 500, "too many wrong trials"); 318 | if(score >= 500) 319 | break; 320 | ANSNA_Cycles(10); 321 | } 322 | printf("<>ANSNA Pong start"); 345 | ANSNA_AddOperation(Encode_Term("op_left"), ANSNA_Pong_Left); 346 | ANSNA_AddOperation(Encode_Term("op_right"), ANSNA_Pong_Right); 347 | ANSNA_AddOperation(Encode_Term("op_stop"), ANSNA_Pong_Stop); 348 | int szX = 50; 349 | int szY = 20; 350 | int ballX = szX/2; 351 | int ballY = szY/5; 352 | int batX = 20; 353 | int batVX = 0; 354 | int batWidth = 6; //"radius", batWidth from middle to the left and right 355 | int vX = 1; 356 | int vY = 1; 357 | int hits = 0; 358 | int misses = 0; 359 | int t=0; 360 | while(1) 361 | { 362 | t++; 363 | //if(t%10000 == 0) 364 | // getchar(); 365 | fputs("\033[1;1H\033[2J", stdout); //POSIX clear screen 366 | for(int i=0; i= szX-1) 429 | { 430 | vX = -1; 431 | } 432 | if(ballY <= 0) 433 | { 434 | vY = 1; 435 | } 436 | if(ballY >= szY-1) 437 | { 438 | vY = -1; 439 | } 440 | if(t%2 == -1) 441 | { 442 | ballX += vX; 443 | } 444 | ballY += vY; 445 | if(ballY == 0) 446 | { 447 | if(abs(ballX-batX) <= batWidth) 448 | { 449 | ANSNA_AddInputBelief(Encode_Term("good_ansna")); 450 | puts("good"); 451 | hits++; 452 | } 453 | else 454 | { 455 | //ANSNA_AddInput(Encode_Term("good_ansna"), EVENT_TYPE_BELIEF, (Truth) {.frequency = 0, .confidence = 0.9}); 456 | puts("bad"); 457 | misses++; 458 | } 459 | } 460 | if(ballY == 0 || ballX == 0 || ballX >= szX-1) 461 | { 462 | ballY = szY/2+rand()%(szY/2); 463 | ballX = rand()%szX; 464 | vX = rand()%2 == 0 ? 1 : -1; 465 | } 466 | if(ANSNA_Pong_Left_executed) 467 | { 468 | ANSNA_Pong_Left_executed = false; 469 | puts("Exec: op_left"); 470 | batVX = -3; 471 | } 472 | if(ANSNA_Pong_Right_executed) 473 | { 474 | ANSNA_Pong_Right_executed = false; 475 | puts("Exec: op_right"); 476 | batVX = 3; 477 | } 478 | if(ANSNA_Pong_Stop_executed) 479 | { 480 | ANSNA_Pong_Stop_executed = false; 481 | puts("Exec: op_stop"); 482 | batVX = 0; 483 | } 484 | batX=MAX(-batWidth*2,MIN(szX-1+batWidth,batX+batVX*batWidth/2)); 485 | printf("Hits=%d misses=%d ratio=%f time=%ld\n", hits, misses, (float) (((float) hits) / ((float) misses)), currentTime); 486 | nanosleep((struct timespec[]){{0, 20000000L}}, NULL); //POSIX sleep 487 | //ANSNA_Cycles(10); 488 | } 489 | } 490 | //int t=0; 491 | void ANSNA_Pong(bool useNumericEncoding) 492 | { 493 | OUTPUT = 0; 494 | ANSNA_INIT(); 495 | puts(">>ANSNA Pong start"); 496 | ANSNA_AddOperation(Encode_Term("op_left"), ANSNA_Pong_Left); 497 | ANSNA_AddOperation(Encode_Term("op_right"), ANSNA_Pong_Right); 498 | int szX = 50; 499 | int szY = 20; 500 | int ballX = szX/2; 501 | int ballY = szY/5; 502 | int batX = 20; 503 | int batVX = 0; 504 | int batWidth = 4; //"radius", batWidth from middle to the left and right 505 | int vX = 1; 506 | int vY = 1; 507 | int hits = 0; 508 | int misses = 0; 509 | while(1) 510 | { 511 | //t++; 512 | //if(t%10000 == 0) 513 | // getchar(); 514 | fputs("\033[1;1H\033[2J", stdout); //POSIX clear screen 515 | for(int i=0; i= szX-1) 573 | { 574 | vX = -1; 575 | } 576 | if(ballY <= 0) 577 | { 578 | vY = 1; 579 | } 580 | if(ballY >= szY-1) 581 | { 582 | vY = -1; 583 | } 584 | ballX += vX; 585 | ballY += vY; 586 | if(ballY == 0) 587 | { 588 | if(abs(ballX-batX) <= batWidth) 589 | { 590 | ANSNA_AddInputBelief(Encode_Term("good_ansna")); 591 | puts("good"); 592 | hits++; 593 | } 594 | else 595 | { 596 | //ANSNA_AddInput(Encode_Term("good_ansna"), EVENT_TYPE_BELIEF, (Truth) {.frequency = 0, .confidence = 0.9}, "good_ansna"); 597 | puts("bad"); 598 | misses++; 599 | } 600 | } 601 | if(ballY == 0 || ballX == 0 || ballX >= szX-1) 602 | { 603 | ballY = szY/2+rand()%(szY/2); 604 | ballX = rand()%szX; 605 | vX = rand()%2 == 0 ? 1 : -1; 606 | } 607 | if(ANSNA_Pong_Left_executed) 608 | { 609 | ANSNA_Pong_Left_executed = false; 610 | puts("Exec: op_left"); 611 | batVX = -2; 612 | } 613 | if(ANSNA_Pong_Right_executed) 614 | { 615 | ANSNA_Pong_Right_executed = false; 616 | puts("Exec: op_right"); 617 | batVX = 2; 618 | } 619 | batX=MAX(0,MIN(szX-1,batX+batVX*batWidth/2)); 620 | printf("Hits=%d misses=%d ratio=%f time=%ld\n", hits, misses, (float) (((float) hits) / ((float) misses)), currentTime); 621 | nanosleep((struct timespec[]){{0, 20000000L}}, NULL); //POSIX sleep 622 | //ANSNA_Cycles(10); 623 | } 624 | } 625 | 626 | bool ANSNA_Lightswitch_GotoSwitch_executed = false; 627 | void ANSNA_Lightswitch_GotoSwitch() 628 | { 629 | ANSNA_Lightswitch_GotoSwitch_executed = true; 630 | puts("ANSNA invoked goto switch"); 631 | } 632 | bool ANSNA_Lightswitch_ActivateSwitch_executed = false; 633 | void ANSNA_Lightswitch_ActivateSwitch() 634 | { 635 | ANSNA_Lightswitch_ActivateSwitch_executed = true; 636 | puts("ANSNA invoked activate switch"); 637 | } 638 | void ANSNA_Multistep_Test() 639 | { 640 | MOTOR_BABBLING_CHANCE = 0; 641 | puts(">>ANSNA Multistep test start"); 642 | OUTPUT = 0; 643 | ANSNA_INIT(); 644 | ANSNA_AddOperation(Encode_Term("op_goto_switch"), ANSNA_Lightswitch_GotoSwitch); 645 | ANSNA_AddOperation(Encode_Term("op_activate_switch"), ANSNA_Lightswitch_ActivateSwitch); 646 | for(int i=0; i<5; i++) 647 | { 648 | ANSNA_AddInputBelief(Encode_Term("start_at")); 649 | ANSNA_AddInputBelief(Encode_Term("op_goto_switch")); 650 | ANSNA_Cycles(1); 651 | ANSNA_AddInputBelief(Encode_Term("switch_at")); 652 | ANSNA_AddInputBelief(Encode_Term("op_activate_switch")); 653 | ANSNA_AddInputBelief(Encode_Term("switch_active")); 654 | ANSNA_Cycles(1); 655 | ANSNA_AddInputBelief(Encode_Term("light_active")); 656 | ANSNA_Cycles(10); 657 | } 658 | ANSNA_Cycles(10); 659 | ANSNA_AddInputBelief(Encode_Term("start_at")); 660 | ANSNA_AddInputGoal(Encode_Term("light_active")); 661 | ANSNA_Cycles(10); 662 | assert(ANSNA_Lightswitch_GotoSwitch_executed && !ANSNA_Lightswitch_ActivateSwitch_executed, "ANSNA needs to go to the switch first"); 663 | ANSNA_Lightswitch_GotoSwitch_executed = false; 664 | puts("ANSNA arrived at the switch"); 665 | ANSNA_AddInputBelief(Encode_Term("switch_at")); 666 | ANSNA_AddInputGoal(Encode_Term("light_active")); 667 | assert(!ANSNA_Lightswitch_GotoSwitch_executed && ANSNA_Lightswitch_ActivateSwitch_executed, "ANSNA needs to activate the switch"); 668 | ANSNA_Lightswitch_ActivateSwitch_executed = false; 669 | puts("<>ANSNA Multistep2 test start"); 675 | OUTPUT = 0; 676 | ANSNA_INIT(); 677 | ANSNA_AddOperation(Encode_Term("op_goto_switch"), ANSNA_Lightswitch_GotoSwitch); 678 | ANSNA_AddOperation(Encode_Term("op_activate_switch"), ANSNA_Lightswitch_ActivateSwitch); 679 | for(int i=0; i<5; i++) 680 | { 681 | ANSNA_AddInputBelief(Encode_Term("start_at")); 682 | ANSNA_AddInputBelief(Encode_Term("op_goto_switch")); 683 | ANSNA_Cycles(1); 684 | ANSNA_AddInputBelief(Encode_Term("switch_at")); 685 | ANSNA_Cycles(10); 686 | } 687 | ANSNA_Cycles(1000); 688 | for(int i=0; i<5; i++) 689 | { 690 | ANSNA_AddInputBelief(Encode_Term("switch_at")); 691 | ANSNA_AddInputBelief(Encode_Term("op_activate_switch")); 692 | ANSNA_AddInputBelief(Encode_Term("switch_active")); 693 | ANSNA_Cycles(1); 694 | ANSNA_AddInputBelief(Encode_Term("light_active")); 695 | ANSNA_Cycles(10); 696 | } 697 | ANSNA_Cycles(10); 698 | ANSNA_AddInputBelief(Encode_Term("start_at")); 699 | ANSNA_AddInputGoal(Encode_Term("light_active")); 700 | ANSNA_Cycles(10); 701 | assert(ANSNA_Lightswitch_GotoSwitch_executed && !ANSNA_Lightswitch_ActivateSwitch_executed, "ANSNA needs to go to the switch first (2)"); 702 | ANSNA_Lightswitch_GotoSwitch_executed = false; 703 | puts("ANSNA arrived at the switch"); 704 | ANSNA_AddInputBelief(Encode_Term("switch_at")); 705 | ANSNA_AddInputGoal(Encode_Term("light_active")); 706 | assert(!ANSNA_Lightswitch_GotoSwitch_executed && ANSNA_Lightswitch_ActivateSwitch_executed, "ANSNA needs to activate the switch (2)"); 707 | ANSNA_Lightswitch_ActivateSwitch_executed = false; 708 | puts("<= 'a' && c<='z')) 1050 | { 1051 | c = lastchar; 1052 | } 1053 | lastchar = c; 1054 | if(c == 'a') 1055 | { 1056 | goto_s0 = true; 1057 | puts("op_goto_s0."); 1058 | ANSNA_AddInputBelief(Encode_Term("op_goto_s0")); 1059 | } 1060 | if(c == 'b') 1061 | { 1062 | goto_s1 = true; 1063 | puts("op_goto_s1."); 1064 | ANSNA_AddInputBelief(Encode_Term("op_goto_s1")); 1065 | } 1066 | if(c == 'c') 1067 | { 1068 | goto_s2 = true; 1069 | puts("op_goto_s2."); 1070 | ANSNA_AddInputBelief(Encode_Term("op_goto_s2")); 1071 | } 1072 | if(c == 'd') 1073 | { 1074 | goto_s3 = true; 1075 | puts("op_goto_s3."); 1076 | ANSNA_AddInputBelief(Encode_Term("op_goto_s3")); 1077 | } 1078 | if(c == 'e') 1079 | { 1080 | goto_l0 = true; 1081 | puts("op_goto_l0."); 1082 | ANSNA_AddInputBelief(Encode_Term("op_goto_l0")); 1083 | } 1084 | if(c == 'f') 1085 | { 1086 | goto_l1 = true; 1087 | puts("op_goto_l1."); 1088 | ANSNA_AddInputBelief(Encode_Term("op_goto_l1")); 1089 | } 1090 | if(c == 'g') 1091 | { 1092 | activate = true; 1093 | puts("op_activate."); 1094 | ANSNA_AddInputBelief(Encode_Term("op_activate")); 1095 | } 1096 | if(c == 'h') 1097 | { 1098 | deactivate = true; 1099 | puts("op_deactivate."); 1100 | ANSNA_AddInputBelief(Encode_Term("op_deactivate")); 1101 | } 1102 | if(c == 'i') 1103 | { 1104 | puts("door_is_open!"); 1105 | ANSNA_AddInputGoal(Encode_Term("door_is_open")); 1106 | //door should be open 1107 | } 1108 | if(c == 'j') 1109 | { 1110 | puts("door_is_closed!"); 1111 | ANSNA_AddInputGoal(Encode_Term("door_is_closed")); 1112 | //door should be closed 1113 | } 1114 | if(c == 'k') 1115 | { 1116 | puts("s1_is_1!"); 1117 | ANSNA_AddInputGoal(Encode_Term("s1_is_1")); 1118 | //s1 should be 1 1119 | } 1120 | if(c == 'l') 1121 | { 1122 | puts("s1_is_0!"); 1123 | ANSNA_AddInputGoal(Encode_Term("s1_is_0")); 1124 | //s1 should be 0 1125 | } 1126 | if(c == 'm') 1127 | { 1128 | puts("s2_is_1!"); 1129 | ANSNA_AddInputGoal(Encode_Term("s2_is_1")); 1130 | //s2 should be 1 1131 | } 1132 | if(c == 'n') 1133 | { 1134 | puts("s2_is_0!"); 1135 | ANSNA_AddInputGoal(Encode_Term("s2_is_0")); 1136 | //s2 should be 0 1137 | } 1138 | if(c == 'o') 1139 | { 1140 | puts("s3_is_1!"); 1141 | ANSNA_AddInputGoal(Encode_Term("s3_is_1")); 1142 | //s3 should be 1 1143 | } 1144 | if(c == 'p') 1145 | { 1146 | puts("s3_is_0!"); 1147 | ANSNA_AddInputGoal(Encode_Term("s3_is_0")); 1148 | //s3 should be 0 1149 | } 1150 | if(c == 'q') 1151 | { 1152 | puts("l0_is_1!"); 1153 | ANSNA_AddInputGoal(Encode_Term("l0_is_1")); 1154 | //l0 should be 1 1155 | } 1156 | if(c == 'r') 1157 | { 1158 | puts("l0_is_1!"); 1159 | ANSNA_AddInputGoal(Encode_Term("l0_is_0")); 1160 | //l0 should be 0 1161 | } 1162 | if(c == 's') 1163 | { 1164 | puts("l1_is_1!"); 1165 | ANSNA_AddInputGoal(Encode_Term("l1_is_1")); 1166 | //l1 should be 1 1167 | } 1168 | if(c == 't') 1169 | { 1170 | puts("l1_is_0!"); 1171 | ANSNA_AddInputGoal(Encode_Term("l1_is_0")); 1172 | //l1 should be 0 1173 | } 1174 | if(c == 'u') 1175 | { 1176 | puts("at_s0!"); 1177 | ANSNA_AddInputGoal(Encode_Term("at_s0")); 1178 | //you should be at s0! 1179 | } 1180 | if(c == 'v') 1181 | { 1182 | puts("at_s1!"); 1183 | ANSNA_AddInputGoal(Encode_Term("at_s1")); 1184 | //you should be at s1! 1185 | } 1186 | if(c == 'w') 1187 | { 1188 | puts("at_s2!"); 1189 | ANSNA_AddInputGoal(Encode_Term("at_s2")); 1190 | //you should be at s2! 1191 | } 1192 | if(c == 'x') 1193 | { 1194 | puts("at_s3!"); 1195 | ANSNA_AddInputGoal(Encode_Term("at_s3")); 1196 | //you should be at s3! 1197 | } 1198 | if(c == 'y') 1199 | { 1200 | puts("at_l0!"); 1201 | ANSNA_AddInputGoal(Encode_Term("at_l0")); 1202 | //you should be at l0! 1203 | } 1204 | if(c == 'z') 1205 | { 1206 | puts("at_l1!"); 1207 | ANSNA_AddInputGoal(Encode_Term("at_l1")); 1208 | //you should be at l1! 1209 | } 1210 | } 1211 | } 1212 | 1213 | bool op_1_executed = false; 1214 | void op_1() 1215 | { 1216 | op_1_executed = true; 1217 | } 1218 | bool op_2_executed = false; 1219 | void op_2() 1220 | { 1221 | op_2_executed = true; 1222 | } 1223 | bool op_3_executed = false; 1224 | void op_3() 1225 | { 1226 | op_3_executed = true; 1227 | } 1228 | void Sequence_Test() 1229 | { 1230 | OUTPUT=0; 1231 | ANSNA_INIT(); 1232 | CONCEPT_FORMATION_NOVELTY = 0; 1233 | MOTOR_BABBLING_CHANCE = 0; 1234 | puts(">>Sequence test start"); 1235 | ANSNA_AddOperation(Encode_Term("op_1"), op_1); 1236 | ANSNA_AddOperation(Encode_Term("op_2"), op_2); 1237 | ANSNA_AddOperation(Encode_Term("op_3"), op_3); 1238 | for(int i=0;i<5;i++) 1239 | { 1240 | ANSNA_AddInputBelief(Encode_Term("a")); //0 2 4 5 1241 | ANSNA_AddInputBelief(Encode_Term("b")); 1242 | ANSNA_AddInputBelief(Encode_Term("op_1")); 1243 | ANSNA_AddInputBelief(Encode_Term("g")); 1244 | ANSNA_Cycles(100); 1245 | } 1246 | for(int i=0;i<100;i++) 1247 | { 1248 | ANSNA_AddInputBelief(Encode_Term("a")); 1249 | ANSNA_AddInputBelief(Encode_Term("op_1")); 1250 | ANSNA_Cycles(100); 1251 | } 1252 | for(int i=0;i<100;i++) 1253 | { 1254 | ANSNA_AddInputBelief(Encode_Term("b")); 1255 | ANSNA_AddInputBelief(Encode_Term("op_1")); 1256 | ANSNA_Cycles(100); 1257 | } 1258 | for(int i=0;i<2;i++) 1259 | { 1260 | ANSNA_AddInputBelief(Encode_Term("b")); 1261 | ANSNA_AddInputBelief(Encode_Term("op_2")); 1262 | ANSNA_AddInputBelief(Encode_Term("g")); 1263 | ANSNA_Cycles(100); 1264 | } 1265 | for(int i=0;i<2;i++) 1266 | { 1267 | ANSNA_AddInputBelief(Encode_Term("a")); 1268 | ANSNA_AddInputBelief(Encode_Term("op_3")); 1269 | ANSNA_AddInputBelief(Encode_Term("g")); 1270 | ANSNA_Cycles(100); 1271 | } 1272 | ANSNA_AddInputBelief(Encode_Term("a")); 1273 | ANSNA_AddInputBelief(Encode_Term("b")); 1274 | ANSNA_AddInputGoal(Encode_Term("g")); 1275 | assert(op_1_executed && !op_2_executed && !op_3_executed, "Expected op1 execution"); 1276 | op_1_executed = op_2_executed = op_3_executed = false; 1277 | //TODO use "preconditons as operator argument" which then should be equal to (&/,a,b) here 1278 | ANSNA_Cycles(100); 1279 | ANSNA_AddInputBelief(Encode_Term("b")); 1280 | ANSNA_AddInputGoal(Encode_Term("g")); 1281 | assert(!op_1_executed && op_2_executed && !op_3_executed, "Expected op2 execution"); //b here 1282 | op_1_executed = op_2_executed = op_3_executed = false; 1283 | ANSNA_Cycles(100); 1284 | ANSNA_AddInputBelief(Encode_Term("a")); 1285 | ANSNA_AddInputGoal(Encode_Term("g")); 1286 | assert(!op_1_executed && !op_2_executed && op_3_executed, "Expected op3 execution"); //a here 1287 | op_1_executed = op_2_executed = op_3_executed = false; 1288 | MOTOR_BABBLING_CHANCE = MOTOR_BABBLING_CHANCE_INITIAL; 1289 | CONCEPT_FORMATION_NOVELTY = CONCEPT_FORMATION_NOVELTY_INITIAL; 1290 | puts(">>Sequence Test successul"); 1291 | } 1292 | 1293 | int main(int argc, char *argv[]) 1294 | { 1295 | //printf("sizeof concept %d\n",(int) sizeof(Concept)); 1296 | //exit(0); 1297 | if(argc == 2) //pong 1298 | { 1299 | if(!strcmp(argv[1],"pong")) 1300 | { 1301 | ANSNA_Pong(false); 1302 | } 1303 | if(!strcmp(argv[1],"pong2")) 1304 | { 1305 | ANSNA_Pong2(false); 1306 | } 1307 | if(!strcmp(argv[1],"numeric-pong")) 1308 | { 1309 | ANSNA_Pong(true); 1310 | } 1311 | if(!strcmp(argv[1],"numeric-pong2")) 1312 | { 1313 | ANSNA_Pong2(true); 1314 | } 1315 | if(!strcmp(argv[1],"testchamber")) 1316 | { 1317 | ANSNA_TestChamber(); 1318 | } 1319 | } 1320 | srand(1337); 1321 | ANSNA_INIT(); 1322 | SDR_Test(); 1323 | Stamp_Test(); 1324 | FIFO_Test(); 1325 | PriorityQueue_Test(); 1326 | Table_Test(); 1327 | ANSNA_Alphabet_Test(); 1328 | ANSNA_Procedure_Test(); 1329 | Memory_Test(); 1330 | ANSNA_Follow_Test(); 1331 | ANSNA_Multistep_Test(); 1332 | ANSNA_Multistep2_Test(); 1333 | Sequence_Test(); 1334 | puts("\nAll tests ran successfully, if you wish to run examples now, just pass the corresponding parameter:"); 1335 | puts("ANSNA pong (starts Pong example)"); 1336 | puts("ANSNA numeric-pong (starts Pong example with numeric input)"); 1337 | puts("ANSNA pong2 (starts Pong2 example)"); 1338 | puts("ANSNA numeric-pong2 (starts Pong2 example with numeric input)"); 1339 | puts("ANSNA testchamber (starts Test Chamber multistep procedure learning example)"); 1340 | return 0; 1341 | } 1342 | 1343 | --------------------------------------------------------------------------------