ONA code documentation

Copyright 2022 The OpenNARS authors.

Modules:
0: CONCEPT
1: CONFIG
2: CYCLE
3: DECISION
4: HASHTABLE
5: IMPLICATION
6: INFERENCE
7: INVERTEDATOMINDEX
8: MEMORY
9: NAL
10: NAR
11: NARSESE
12: OCCURRENCETIMEINDEX
13: PRIORITYQUEUE
14: RULETABLE
15: SHELL
16: STACK
17: STAMP
18: STATS
19: TABLE
20: TERM
21: TRUTH
22: USAGE
23: VARIABLE
24: GLOBALS

Module: CONCEPT



// Concept //

//A concept represents a container which allows the reasoner

//1. To remember events that already happened

//2. Learn under what circumstances they do occur.

//3. To revise the statements encoded in them

//Various design decisions:

//- Differently than in OpenNARS, only statements can form concepts.

//- Concepts store a belief event, predicted event, and eternal version

//- Concepts store a goal event but no eternal goal

//- Concepts hold a priority value to encode their attention

//- Concepts hold a usefulness value to encode their forgetting

//Data structure//

typedef struct {
long id;
Usage usage;
Term term;
Event belief; //the highest confident eternal belief
Event belief_spike;
Event predicted_belief;
Event goal_spike;
Table precondition_beliefs[OPERATIONS_MAX+1];
double priority;
long processID; //avoids duplicate processing
long processID2; //avoids duplicate processing
long processID3; //avoids duplicate processing
long lastSelectionTime; //for selective temporal compounding
} Concept;

Module: CONFIG


/*-------------------------*/
/* Anticipation parameters */
/*-------------------------*/

//Truth expectation needed for anticipation
#define ANTICIPATION_THRESHOLD_INITIAL 0.501

//Confidence of anticipation failures
#define ANTICIPATION_CONFIDENCE_INITIAL 0.01

//Anticipate for concrete yet unexperienced outcomes derived from generals
#define ANTICIPATE_FOR_NOT_EXISTING_SPECIFIC_TEMPORAL_IMPLICATION true
/*---------------------*/
/* Decision parameters */
/*---------------------*/

//Truth expectation to move on to next component goal in sequence
#define CONDITION_THRESHOLD_INITIAL 0.501

//Desire expectation needed for executions
#define DECISION_THRESHOLD_INITIAL 0.501

//Motor babbling chance
#define MOTOR_BABBLING_CHANCE_INITIAL 0.2

//Decisions above the following threshold will suppress babbling actions
#define MOTOR_BABBLING_SUPPRESSION_THRESHOLD 0.55

//Whether temporal non-procedural implications are allowed to derive subgoals
#define NOP_SUBGOALING true

//Subsumption confidence threshold above which a specific hypothesis inhibits more generals
#define SUBSUMPTION_CONFIDENCE_THRESHOLD 0.05

//Subsumption confidence threshold below which a specific hypothesis inhibits more generals
#define SUBSUMPTION_FREQUENCY_THRESHOLD 0.5

//How long goal events describing bad outcomes are considered in decision making
#define NEG_GOAL_AGE_MAX EVENT_BELIEF_DISTANCE
/*----------------------*/
/* Attention parameters */
/*----------------------*/

//Event selections per cycle for inference
#define BELIEF_EVENT_SELECTIONS 1

//Goal event selections per cycle for inference
#define GOAL_EVENT_SELECTIONS 1

//Event priority decay of events per cycle
#define EVENT_DURABILITY 0.9999

//Concept priority decay of events per cycle
#define CONCEPT_DURABILITY 0.9

//Minimum priority to accept events
#define MIN_PRIORITY 0

//Occurrence time distance in which case event belief is preferred over eternal
#define EVENT_BELIEF_DISTANCE 20

//Amount of belief concepts to select to be matched to the selected event
#define BELIEF_CONCEPT_MATCH_TARGET 80

//Adaptation speed of the concept priority threshold to meet the match target
#define CONCEPT_THRESHOLD_ADAPTATION 0.000001

//Usage boost for input
#define ETERNAL_INPUT_USAGE_BOOST 1000000

//Unification depth, 2^(n+1)-1, n=2 levels lead to value 7
#define UNIFICATION_DEPTH 31

//Questions concept activation priority
#define QUESTION_PRIMING_INITIAL 0.1
/*---------------------------------*/
/* Temporal compounding parameters */
/*---------------------------------*/

//Maximum length of sequences
#define MAX_SEQUENCE_LEN 2

//Maximum compound op length
#define MAX_COMPOUND_OP_LEN 1

//Max. occurrence time distance between precondition and consequence
#define PRECONDITION_CONSEQUENCE_DISTANCE EVENT_BELIEF_DISTANCE

//Occurrence time distance to now to still correlate an outcome
#define CORRELATE_OUTCOME_RECENCY EVENT_BELIEF_DISTANCE

//Maximum time difference to form sequence between events
#define MAX_SEQUENCE_TIMEDIFF EVENT_BELIEF_DISTANCE

//Allow events which have not been selected to become preconditions
#define ALLOW_NOT_SELECTED_PRECONDITIONS_CONDITIONING false
/*------------------*/
/* Space parameters */
/*------------------*/

//Maximum amount of concepts
#define CONCEPTS_MAX 16384

//Amount of buckets for concept hashmap
#define CONCEPTS_HASHTABLE_BUCKETS CONCEPTS_MAX

//Maximum amount of belief events attention buffer holds
#define CYCLING_BELIEF_EVENTS_MAX 40

//Maximum amount of goal events attention buffer holds
#define CYCLING_GOAL_EVENTS_MAX 400

//Maximum amount of operations which can be registered
#define OPERATIONS_MAX 10

//Maximum amount of arguments an operation can babble
#define OPERATIONS_BABBLE_ARGS_MAX 10

//Maximum size of the stamp in terms of evidental base id's
#define STAMP_SIZE 10

//Maximum Implication table size
#define TABLE_SIZE 20

//Maximum compound term size
#define COMPOUND_TERM_SIZE_MAX 64

//Max. amount of atomic terms, must be <= 2^(sizeof(Atom)*8)
#define ATOMS_MAX 65536

//Amount of buckets for atoms hashmap
#define ATOMS_HASHTABLE_BUCKETS ATOMS_MAX

//The type of an atom
#define Atom unsigned short

//Maximum size of atomic terms in terms of characters
#define ATOMIC_TERM_LEN_MAX 32

//Maximum size of Narsese input in terms of characters
#define NARSESE_LEN_MAX 2148 //ATOMIC_TERM_LEN_MAX * COMPOUND_TERM_SIZE_MAX + 100 for punctuation event marker and TV

//Goal events queue derivation depth layers
#define CYCLING_GOAL_EVENTS_LAYERS 30

//Hashtable bucket size for atom counters in term
#define VAR_INTRO_HASHTABLE_BUCKETS COMPOUND_TERM_SIZE_MAX

//OccurrenceTimeIndex size (large enough to cover all events input and derived within EVENT_BELIEF_DISTANCE from currentTime)
#define OCCURRENCE_TIME_INDEX_SIZE 512
/*------------------*/
/* Truth parameters */
/*------------------*/

//Default frequency for input events
#define NAR_DEFAULT_FREQUENCY 1.0

//Default confidence for input events
#define NAR_DEFAULT_CONFIDENCE 0.9

//Default confidence for analytical premise
#define RELIANCE 0.9

//NAL evidental horizon
#define TRUTH_EVIDENTAL_HORIZON_INITIAL 1.0

//Time distance based projection decay of event truth
#define TRUTH_PROJECTION_DECAY_INITIAL 0.8

//Maximum value for confidence
#define MAX_CONFIDENCE 0.99

//Minimum confidence to accept events
#define MIN_CONFIDENCE 0.01
/*-----------------------*/
/* Derivation parameters */
/*-----------------------*/

//The NAL level of semantic inference
#define SEMANTIC_INFERENCE_NAL_LEVEL 7

//Filter for twice appearing atoms
#define ATOM_APPEARS_TWICE_FILTER true

//Filter for derivations which include nested implications or equivalences
#define NESTED_HOL_STATEMENT_FILTER true

//Filter for inheritance or similarity statement with dependent var
#define INH_OR_SIM_HAS_DEP_VAR_FILTER true

//We don't allow higher-order statements with A> or var2> components
#define HOL_STATEMENT_COMPONENT_HAS_INVALID_INH_OR_SIM_FILTER true

//Whether a higher-order statement is invalid if it contains a inh or sim without var
#define HOL_COMPONENT_NO_VAR_IS_INVALID_FILTER true

//Whether a higher-order statement is invalid if it contains a inh or sim without atomic term
#define HOL_COMPONENT_NO_ATOMIC_IS_INVALID_FILTER true

//Filter disjunction or conjunction in derivation if not right nested
#define JUNCTION_NOT_RIGHT_NESTED_FILTER true

//Variables introduced in set with more than 1 element filter
#define VARS_IN_MULTI_ELEMENT_SETS_FILTER true

//Filtering sub-statement terms with variables and atoms both like (&, $1, a)
#define TERMS_WITH_VARS_AND_ATOMS_FILTER true

Module: CYCLE



// NAR Control Cycle //

//The overall inference control cycle of ONA

//Special properties:

//- Needs a constant upper bound of time to complete

//- Handles temporal, procedural, and declarative reasoning

//Methods//

//Apply one operating cyle
void Cycle_Perform(long currentTime);

//Init cycle module
void Cycle_INIT();

Module: DECISION



// NAR Decision //

//Realization of goals.

//When a goal is processed, the system will realize it with the

//operation which most likely leads to it, whereby candidates

//are taken from the incoming implication links.

//To be above decision threshold, the source concepts

//(the preconditions of the implications) need to have a

//a quite true and recent event and the temporal implication

//link that "fires" needs to have sufficient truth value.

//However this isn't checked with individual thresholds

//as this would be brittle and hard to tune,

//instead deductive NAL inference is utilized to decide the desire

//value of each operation goal (for eeach link) individually,

//whereby the highest-truth expectation option above decison

//threshold is chosen.

//If none however is above decision threshold, the system

//derived the preconditions of the links as subgoals,

//again, as a form of deductive inference.

//Parameters//
extern double CONDITION_THRESHOLD;
extern double DECISION_THRESHOLD;
extern double ANTICIPATION_THRESHOLD;
extern double ANTICIPATION_CONFIDENCE;
extern double MOTOR_BABBLING_CHANCE;
extern int BABBLING_OPS;

//Data structure//

typedef struct
{
double desire;
bool execute;
Term operationTerm;
int operationID[MAX_COMPOUND_OP_LEN];
Operation op[MAX_COMPOUND_OP_LEN];
Term arguments[MAX_COMPOUND_OP_LEN];
Implication missing_specific_implication;
Implication usedContingency;
Event *reason;
}Decision;

//Methods//

//execute decision
void Decision_Execute(Decision *decision);

//assumption of failure, also works for "do nothing operator"
void Decision_Anticipate(int operationID, Term op_term, long currentTime);

//NAR decision making rule applying when goal is an operation
Decision Decision_Suggest(Concept *goalconcept, Event *goal, long currentTime);

//Better decision pair:
Decision Decision_BetterDecision(Decision best_decision, Decision decision);
#define EVENT_H

// Event //

//An event named by a term

//It can be a belief event corresponding to a certain

//invariance observed by the system

//Input patterns usually directly come from sensory channels

//while derived events can be compounds built by the system

//Events can also be goals, which makes

//the system want to observe a belief event with same term asap.

//Data structure//
extern long base;
extern Stamp importstamp;
#define EVENT_TYPE_GOAL 1
#define EVENT_TYPE_BELIEF 2
#define EVENT_TYPE_DELETED 0

typedef struct {
Term term;
char type; //either JUDGMENT or GOAL
Truth truth;
Stamp stamp;
long occurrenceTime;
double occurrenceTimeOffset; //necessary if the event is an =/>
bool processed;
long creationTime;
bool input;
} Event;

//Methods//

//Init/Reset module
void Event_INIT();

//construct an input event
Event Event_InputEvent(Term term, char type, Truth truth, double occurrenceTimeOffset, long currentTime);

//Whether two events are the same
bool Event_Equal(Event *event, Event *existing);

//Whether the left event with same term and stamp overlap is less confident than the second
bool Event_EqualTermEqualStampLessConfidentThan(Event *event, Event *existing);

//Eternalized event
Event Event_Eternalized(Event *event);

Module: HASHTABLE



// HashTable //

//A generic bounded hashtable

//Also used for other purposes, such as:

//- The concept hashtable HT[Term] -> Concept*

//- Mapping atoms to atom names

//- Counting how often the atoms in a term occur in the same term

//Data structure//

typedef bool (*Equal)(void*, void*);

typedef HASH_TYPE (*Hash)(void*);

typedef struct
{
void *key;
void *value;
void *next;
} VMItem;

typedef struct
{
VMItem** storageptrs;
VMItem* storage;
VMItem** HT; //the hash of the concept term is the index
Stack VMStack; //"Virtual memory" stack
int buckets;
Equal equal;
Hash hash;
} HashTable;

//Methods//

//Get a concept from the hashtable via term
void* HashTable_Get(HashTable *hashtable, void *key);

//Add a concept to the hashtable using the concept term
void HashTable_Set(HashTable *hashtable, void *key, void *value);

//Delete a concept from hashtable (the concept's term is the key)
void HashTable_Delete(HashTable *hashtable, void *key);

//Initialize hashtable "virtual memory" stack and HT array
void HashTable_INIT(HashTable *hashtable, VMItem* storage, VMItem** storageptrs, VMItem** HT, int buckets, int maxElements, Equal equal, Hash hash);

//Maximum chain length in hashtable
int HashTable_MaximumChainLength(HashTable *hashtable);

Module: IMPLICATION



// Implication //

//Temporal implications, essentially allowing the system to predict

//events from other events.

//Usually, in learning scenarios:

//- Positive evidence of a temporal implication comes from a successful prediction

//- Negative evidence of a temporal implication comes from a prediction failure

//Data structure//

typedef struct {
Term term;
Truth truth;
Stamp stamp;
//for deciding occurrence time of conclusion:
double occurrenceTimeOffset;
//for efficient spike propagation:
void *sourceConcept;
long sourceConceptId; //to check whether it's still the same
long creationTime;
} Implication;

Module: INFERENCE



// INFERENCE //

//This module handles all temporal (NAL-7) and procedural (NAL-8) inference.

//Methods//

//{Event a.} |- Event a. Truth_Projection (projecting to current time)
Event Inference_EventUpdate(Event *ev, long currentTime);

//{Event a., Event b.} |- Event (a &/ b). Truth_Intersection (after projecting a to b)
Event Inference_BeliefIntersection(Event *a, Event *b, bool *success);

//{Event a., Event b.} |- Implication
b>. Truth_Eternalize(Truth_Induction) (after projecting a to b)
Implication Inference_BeliefInduction(Event *a, Event *b, bool *success);

//{Implication
b>., b>.} |- Implication b>. Truth_Revision
Implication Inference_ImplicationRevision(Implication *a, Implication *b);

//{Event b!, Implication
b>.} |- Event a! Truth_Deduction
Event Inference_GoalDeduction(Event *component, Implication *compound, long currentTime);

//{Event (a &/ b)!, Event a.} |- Event b! Truth_Deduction
Event Inference_GoalSequenceDeduction(Event *compound, Event *component, long currentTime);

//{Event a!, Event a!} |- Event a! Truth_Revision or Choice (dependent on evidental overlap)
Event Inference_RevisionAndChoice(Event *existing_potential, Event *incoming_spike, long currentTime, bool *revised);

//{Event a., Implication
b>.} |- Event b. Truth_Deduction
Event Inference_BeliefDeduction(Event *component, Implication *compound);
Event Inference_EventRevision(Event *a, Event *b);

Module: INVERTEDATOMINDEX



// Inverted atom index //

//The inverted atom table for efficient query of to an event semantically related concepts

//Data structure//

typedef struct
{
Concept *c;
void *next;
}ConceptChainElement;
extern ConceptChainElement* conceptChainElementStoragePointers[UNIFICATION_DEPTH*CONCEPTS_MAX];
extern ConceptChainElement conceptChainElementStorage[UNIFICATION_DEPTH*CONCEPTS_MAX];
extern Stack conceptChainElementStack;
extern ConceptChainElement *invertedAtomIndex[ATOMS_MAX];

//Methods//

//Init inverted atom index
void InvertedAtomIndex_INIT();

//Add concept to inverted atom index
void InvertedAtomIndex_AddConcept(Term term, Concept *c);

//Remove concept from inverted atom index
void InvertedAtomIndex_RemoveConcept(Term term, Concept *c);

//Print the inverted atom index
void InvertedAtomIndex_Print();

//Get the invtable chain with the concepts for an atom
ConceptChainElement* InvertedAtomIndex_GetConceptChain(Atom atom);

Module: MEMORY



// NAR Memory //

//The concept-based memory of NAR

//Concepts are created from events

//and are linked to each other with temporal implications

//and by their subterms via InvertedAtomIndex

//Parameters//

//Inferences per cycle (amount of events from cycling events)
extern double PROPAGATION_THRESHOLD;
extern bool PRINT_DERIVATIONS;
extern bool PRINT_INPUT;
extern double conceptPriorityThreshold;

//Data structure//

typedef struct
{
Substitution subs;
bool failed;
}Feedback; //operation feedback

typedef Feedback (*Action)(Term);

typedef struct
{
Term term;
Action action;
Term arguments[OPERATIONS_BABBLE_ARGS_MAX];
bool stdinOutput;
}Operation;
extern bool ontology_handling;
extern Event selectedBeliefs[BELIEF_EVENT_SELECTIONS]; //better to be global
extern double selectedBeliefsPriority[BELIEF_EVENT_SELECTIONS]; //better to be global
extern int beliefsSelectedCnt;
extern Event selectedGoals[GOAL_EVENT_SELECTIONS]; //better to be global
extern double selectedGoalsPriority[GOAL_EVENT_SELECTIONS]; //better to be global
extern int goalsSelectedCnt;
extern int concept_id;

//Concepts in main memory:
extern PriorityQueue concepts;

//cycling events cycling in main memory:
extern PriorityQueue cycling_belief_events;
extern PriorityQueue cycling_goal_events[CYCLING_GOAL_EVENTS_LAYERS];

//Hashtable of concepts used for fast retrieval of concepts via term:
extern HashTable HTconcepts;

//OccurrenceTimeIndex for accelerating temporal induction
extern OccurrenceTimeIndex occurrenceTimeIndex;

//Registered perations
extern Operation operations[OPERATIONS_MAX];

//Priority threshold for printing derivations
extern double PRINT_EVENTS_PRIORITY_THRESHOLD;

//Methods//

//Init memory
void Memory_INIT();

//Find a concept
Concept *Memory_FindConceptByTerm(Term *term);

//Create a new concept
Concept* Memory_Conceptualize(Term *term, long currentTime);

//Add event to memory
void Memory_AddEvent(Event *event, long currentTime, double priority, bool input, bool derived, bool revised, int layer);
void Memory_AddInputEvent(Event *event, long currentTime);

//Add operation to memory
void Memory_AddOperation(int id, Operation op);

//check if implication is still valid (source concept might be forgotten)
bool Memory_ImplicationValid(Implication *imp);

//Print an event in memory:
void Memory_printAddedEvent(Stamp *stamp, Event *event, double priority, bool input, bool derived, bool revised, bool controlInfo, bool selected);

//Print an implication in memory:
void Memory_printAddedImplication(Stamp *stamp, Term *implication, Truth *truth, double occurrenceTimeOffset, double priority, bool input, bool revised, bool controlInfo);

//Get operation ID
int Memory_getOperationID(Term *term);

Module: NAL



// NAL ecosystem //

//Declarative NAL 1-6 reasoning abilities not covered by Inference.h

//Methods//

//Generates inference rule code
void NAL_GenerateRuleTable();

//Method for the derivation of new events as called by the generated rule table
void NAL_DerivedEvent(Term conclusionTerm, long conclusionOccurrence, Truth conclusionTruth, Stamp stamp, long currentTime, double parentPriority, double conceptPriority, double occurrenceTimeOffset, Concept *validation_concept, long validation_cid, bool varIntro, bool allowOnlyExtVarIntroAndTwoIndependentVars);

//macro for syntactic representation, increases readability, double premise inference
#define R2(premise1, premise2, _, conclusion, truthFunction) NAL_GenerateRule(#premise1, #premise2, #conclusion, #truthFunction, true, false, false); NAL_GenerateRule(#premise2, #premise1, #conclusion, #truthFunction, true, true, false);
#define R2VarIntro(premise1, premise2, _, conclusion, truthFunction) NAL_GenerateRule(#premise1, #premise2, #conclusion, #truthFunction, true, false, true); NAL_GenerateRule(#premise2, #premise1, #conclusion, #truthFunction, true, true, true);

//macro for syntactic representation, increases readability, single premise inference
#define R1(premise1, _, conclusion, truthFunction) NAL_GenerateRule(#premise1, NULL, #conclusion, #truthFunction, false, false, false);

//macro for bidirectional transformation rules
#define R1Bidirectional(rep1, _, rep2, truthFunction) NAL_GenerateRule(#rep1, NULL, #rep2, #truthFunction, false, false, false); NAL_GenerateRule(#rep2, NULL, #rep1, #truthFunction, false, false, false);

//macro for term reductions
#define ReduceTerm(pattern, replacement) NAL_GenerateReduction("(" #pattern " --> M) ", "(" #replacement " --> M)"); NAL_GenerateReduction("(M --> " #pattern ")", "(M --> " #replacement ")");

//macro for statement reductions
#define ReduceStatement(pattern, replacement) NAL_GenerateReduction(#pattern, #replacement);

//Inference rules//

//!Syllogistic rules for Inheritance:
R2( (S --> M), (M --> P), |-, (S --> P), Truth_Deduction )
R2( (A --> B), (A --> C), |-, (C --> B), Truth_Induction )
R2( (A --> C), (B --> C), |-, (B --> A), Truth_Abduction )
R2( (A --> B), (B --> C), |-, (C --> A), Truth_Exemplification )
R2( S, (S --> P), |-, P, Truth_Deduction )
R2( P, (S --> P), |-, S, Truth_Abduction )

//!Rules for Similarity:
R1( (S <-> P), |-, (P <-> S), Truth_StructuralIntersection )
R2( (M <-> P), (S <-> M), |-, (S <-> P), Truth_Resemblance )
R2( (P --> M), (S --> M), |-, (S <-> P), Truth_Comparison )
R2( (M --> P), (M --> S), |-, (S <-> P), Truth_Comparison )
R2( (M --> P), (S <-> M), |-, (S --> P), Truth_Analogy )
R2( (P --> M), (S <-> M), |-, (P --> S), Truth_Analogy )
R2( S, (S <-> P), |-, P, Truth_Analogy )
R2( S, (P <-> S), |-, P, Truth_Analogy )

//!Dealing with properties and instances:
R1( (S --> {P}), |-, (S <-> {P}), Truth_StructuralIntersection )
R1( ([S] --> P), |-, ([S] <-> P), Truth_StructuralIntersection )
R2( ({M} --> P), (S <-> M), |-, ({S} --> P), Truth_Analogy )
R2( (P --> [M]), (S <-> M), |-, (P --> [S]), Truth_Analogy )
R1( ({A} <-> {B}), |-, (A <-> B), Truth_StructuralIntersection )
R1( ([A] <-> [B]), |-, (A <-> B), Truth_StructuralIntersection )

//!Set decomposition:
R1( ({A B} --> M), |-, <{A} --> M>, Truth_StructuralDeduction )
R1( ({A B} --> M), |-, <{B} --> M>, Truth_StructuralDeduction )
R1( (M --> [A B]), |-, [A]>, Truth_StructuralDeduction )
R1( (M --> [A B]), |-, [B]>, Truth_StructuralDeduction )

//!Extensional and intensional intersection decomposition:
R1( ((S | P) --> M), |-, (S --> M), Truth_StructuralDeduction )
R1( (M --> (S & P)), |-, (M --> S), Truth_StructuralDeduction )
R1( ((S | P) --> M), |-, (P --> M), Truth_StructuralDeduction )
R1( (M --> (S & P)), |-, (M --> P), Truth_StructuralDeduction )
R1( ((A ~ S) --> M), |-, (A --> M), Truth_StructuralDeduction )
R1( (M --> (B - S)), |-, (M --> B), Truth_StructuralDeduction )
R1( ((A ~ S) --> M), |-, (S --> M), Truth_StructuralDeductionNegated )
R1( (M --> (B - S)), |-, (M --> S), Truth_StructuralDeductionNegated )

//!Extensional and intensional intersection composition: (sets via reductions)
R2( (P --> M), (S --> M), |-, ((P | S) --> M), Truth_Intersection )
R2( (P --> M), (S --> M), |-, ((P & S) --> M), Truth_Union )
R2( (P --> M), (S --> M), |-, ((P ~ S) --> M), Truth_Difference )
R2( (M --> P), (M --> S), |-, (M --> (P & S)), Truth_Intersection )
R2( (M --> P), (M --> S), |-, (M --> (P | S)), Truth_Union )
R2( (M --> P), (M --> S), |-, (M --> (P - S)), Truth_Difference )

//!Extensional and intensional intersection decomposition:
R2( (S --> M), ((S | P) --> M), |-, (P --> M), Truth_DecomposePNN )
R2( (P --> M), ((S | P) --> M), |-, (S --> M), Truth_DecomposePNN )
R2( (S --> M), ((S & P) --> M), |-, (P --> M), Truth_DecomposeNPP )
R2( (P --> M), ((S & P) --> M), |-, (S --> M), Truth_DecomposeNPP )
R2( (S --> M), ((S ~ P) --> M), |-, (P --> M), Truth_DecomposePNP )
R2( (S --> M), ((P ~ S) --> M), |-, (P --> M), Truth_DecomposeNNN )
R2( (M --> S), (M --> (S & P)), |-, (M --> P), Truth_DecomposePNN )
R2( (M --> P), (M --> (S & P)), |-, (M --> S), Truth_DecomposePNN )
R2( (M --> S), (M --> (S | P)), |-, (M --> P), Truth_DecomposeNPP )
R2( (M --> P), (M --> (S | P)), |-, (M --> S), Truth_DecomposeNPP )
R2( (M --> S), (M --> (S - P)), |-, (M --> P), Truth_DecomposePNP )
R2( (M --> S), (M --> (P - S)), |-, (M --> P), Truth_DecomposeNNN )

//!Transformation rules between product and image:
R1Bidirectional( ((A * B) --> R), -|-, (A --> (R /1 B)), Truth_StructuralIntersection )
R1Bidirectional( ((A * B) --> R), -|-, (B --> (R /2 A)), Truth_StructuralIntersection )
R1Bidirectional( (R --> (A * B)), -|-, ((R \\1 B) --> A), Truth_StructuralIntersection )
R1Bidirectional( (R --> (A * B)), -|-, ((R \\2 A) --> B), Truth_StructuralIntersection )

//!Comparative relations
R2( ({R} |-> [P]), ({S} |-> [P]), |-, (({R} * {S}) --> (+ P)), Truth_FrequencyGreater )
R2( ((A * B) --> (+ P)), ((B * C) --> (+ P)), |-, ((A * C) --> (+ P)), Truth_Deduction )
R2( ({R} |-> [P]), ({S} |-> [P]), |-, (({R} * {S}) --> (= P)), Truth_FrequencyEqual )
R2( ((A * B) --> (= P)), ((B * C) --> (= P)), |-, ((A * C) --> (= P)), Truth_Deduction )
R1( ((A * B) --> (= P)), |-, ((B * A) --> (= P)), Truth_StructuralIntersection )
R2( ({A} |-> [P]), (({A} * {B}) --> (= P)), |-, ({B} |-> [P]), Truth_Intersection )

//!Optional rules for more efficient reasoning about relation components:
R2( ((A * B) --> R), ((C * B) --> R), |-, (C --> A), Truth_Abduction )
R2( ((A * B) --> R), ((A * C) --> R), |-, (C --> B), Truth_Abduction )
R2( (R --> (A * B)), (R --> (C * B)), |-, (C --> A), Truth_Induction )
R2( (R --> (A * B)), (R --> (A * C)), |-, (C --> B), Truth_Induction )
R2( ((A * B) --> R), (C --> A), |-, ((C * B) --> R), Truth_Deduction )
R2( ((A * B) --> R), (A --> C), |-, ((C * B) --> R), Truth_Induction )
R2( ((A * B) --> R), (C <-> A), |-, ((C * B) --> R), Truth_Analogy )
R2( ((A * B) --> R), (C --> B), |-, ((A * C) --> R), Truth_Deduction )
R2( ((A * B) --> R), (B --> C), |-, ((A * C) --> R), Truth_Induction )
R2( ((A * B) --> R), (C <-> B), |-, ((A * C) --> R), Truth_Analogy )
R2( (R --> (A * B)), (A --> C), |-, (R --> (C * B)), Truth_Deduction )
R2( (R --> (A * B)), (C --> A), |-, (R --> (C * B)), Truth_Abduction )
R2( (R --> (A * B)), (C <-> A), |-, (R --> (C * B)), Truth_Analogy )
R2( (R --> (A * B)), (B --> C), |-, (R --> (A * C)), Truth_Deduction )
R2( (R --> (A * B)), (C --> B), |-, (R --> (A * C)), Truth_Abduction )
R2( (R --> (A * B)), (C <-> B), |-, (R --> (A * C)), Truth_Analogy )
R2( ((A * B) --> R), ((C * B) --> R), |-, (A <-> C), Truth_Comparison )
R2( ((A * B) --> R), ((A * C) --> R), |-, (B <-> C), Truth_Comparison )
R2( (R --> (A * B)), (R --> (C * B)), |-, (A <-> C), Truth_Comparison )
R2( (R --> (A * B)), (R --> (A * C)), |-, (B <-> C), Truth_Comparison )

//!Negation conjunction and disjunction decomposition:
R1( (! A), |-, A, Truth_Negation )
R1( (A && B), |-, A, Truth_StructuralDeduction )
R1( (A && B), |-, B, Truth_StructuralDeduction )
R1( (A && B), |-, (B && A), Truth_StructuralIntersection )
R2( S, (&& S A), |-, A, Truth_DecomposePNN ) //Truth_AnonymousAnalogy in Cycle_SpecialInferences for var elimination
R2( S, (|| S A), |-, A, Truth_DecomposeNPP )
R2( S, (&& (! S) A), |-, A, Truth_DecomposeNNN )
R2( S, (|| (! S) A), |-, A, Truth_DecomposePPP )

//!Syllogistic rules for Implication:
R2( (S ==> M), (M ==> P), |-, (S ==> P), Truth_Deduction )
R2( (A ==> B), (A ==> C), |-, (C ==> B), Truth_Induction )
R2( (A ==> C), (B ==> C), |-, (B ==> A), Truth_Abduction )
R2( (A ==> B), (B ==> C), |-, (C ==> A), Truth_Exemplification )

//!Conditional composition for conjunction and disjunction:
R2( (A ==> C), (B ==> C), |-, ((A && B) ==> C), Truth_Union )
R2( (A ==> C), (B ==> C), |-, ((A || B) ==> C), Truth_Intersection )
R2( (C ==> A), (C ==> B), |-, (C ==> (A && B)), Truth_Intersection )
R2( (C ==> A), (C ==> B), |-, (C ==> (A || B)), Truth_Union )

//!Multi-conditional inference:
R2( ((S && P) ==> M), (S ==> M), |-, P, Truth_Abduction )
R2( ((C && M) ==> P), (S ==> M), |-, ((C && S) ==> P), Truth_Deduction )
R2( ((C && P) ==> M), ((C && S) ==> M), |-, (S ==> P), Truth_Abduction )
R2( ((C && M) ==> P), (M ==> S), |-, ((C && S) ==> P), Truth_Induction )

//!Rules for equivalence:
R1( (S <=> P), |-, (P <=> S), Truth_StructuralIntersection )
R2( (S ==> P), (P ==> S), |-, (S <=> P), Truth_Intersection )
R2( (P ==> M), (S ==> M), |-, (S <=> P), Truth_Comparison )
R2( (M ==> P), (M ==> S), |-, (S <=> P), Truth_Comparison )
R2( (M ==> P), (S <=> M), |-, (S ==> P), Truth_Analogy )
R2( (P ==> M), (S <=> M), |-, (P ==> S), Truth_Analogy )
R2( (M <=> P), (S <=> M), |-, (S <=> P), Truth_Resemblance )

//!Higher-order decomposition in Cycle_SpecialInferences (with var elimination in Cycle_SpecialInferences)
R2( A, (A ==> B), |-, B, Truth_Deduction )
R2( A, ((A && B) ==> C), |-, (B ==> C), Truth_Deduction )
R2( B, (A ==> B), |-, A, Truth_Abduction )
R2( A, (A <=> B), |-, B, Truth_Analogy )

//!First var intro step:
R2VarIntro( (C --> A), (C --> B), |-, ((C --> B) ==> (C --> A)), Truth_Induction )
R2VarIntro( (A --> C), (B --> C), |-, ((B --> C) ==> (A --> C)), Truth_Induction )
R2VarIntro( (C --> A), (C --> B), |-, ((C --> B) <=> (C --> A)), Truth_Comparison )
R2VarIntro( (A --> C), (B --> C), |-, ((B --> C) <=> (A --> C)), Truth_Comparison )
R2VarIntro( (! (C --> A)), (C --> B), |-, ((C --> B) ==> (! (C --> A))), Truth_Induction )
R2VarIntro( (! (A --> C)), (B --> C), |-, ((B --> C) ==> (! (A --> C))), Truth_Induction )
R2VarIntro( (! (C --> A)), (C --> B), |-, ((C --> B) <=> (! (C --> A))), Truth_Comparison )
R2VarIntro( (! (A --> C)), (B --> C), |-, ((B --> C) <=> (! (A --> C))), Truth_Comparison )
R2VarIntro( (C --> A), (! (C --> B)), |-, ((! (C --> B)) ==> (C --> A)), Truth_Induction )
R2VarIntro( (A --> C), (! (B --> C)), |-, ((! (B --> C)) ==> (A --> C)), Truth_Induction )
R2VarIntro( (C --> A), (! (C --> B)), |-, ((! (C --> B)) <=> (C --> A)), Truth_Comparison )
R2VarIntro( (A --> C), (! (B --> C)), |-, ((! (B --> C)) <=> (A --> C)), Truth_Comparison )
R2VarIntro( (C --> A), (C --> B), |-, ((C --> B) && (C --> A)), Truth_Intersection )
R2VarIntro( (A --> C), (B --> C), |-, ((B --> C) && (A --> C)), Truth_Intersection )
R2VarIntro( (! (C --> A)), (C --> B), |-, ((C --> B) && (! (C --> A))), Truth_Intersection )
R2VarIntro( (! (A --> C)), (B --> C), |-, ((B --> C) && (! (A --> C))), Truth_Intersection )
R2VarIntro( (C --> A), (! (C --> B)), |-, ((! (C --> B)) && (C --> A)), Truth_Intersection )
R2VarIntro( (A --> C), (! (B --> C)), |-, ((! (B --> C)) && (A --> C)), Truth_Intersection )

//!Second var intro step:
R2VarIntro( (<$1 --> B> ==> <$1 --> C>), A, |-, (A && (<$1 --> B> ==> <$1 --> C>)), Truth_Intersection )
R2VarIntro( (<#1 --> B> && <#1 --> C>), A, |-, (A ==> (<#1 --> B> && <#1 --> C>)), Truth_Induction )
R2VarIntro( (B ==> C), A, |-, ((A && B) ==> C), Truth_Induction )

//!Relation symmetry, asymmetry, and transitivity:
R2VarIntro( ((A * B) --> R), ((B * A) --> S), |-, (((B * A) --> S) ==> ((A * B) --> R)), Truth_Induction )
R2VarIntro( (! ((B * A) --> R)), ((A * B) --> S), |-, (((A * B) --> S) ==> (! ((B * A) --> R))), Truth_Induction )
R2VarIntro( ((B * A) --> R), (! ((A * B) --> S)), |-, ((! ((A * B) --> S)) ==> ((B * A) --> R)), Truth_Induction )
R2( ((A * B) --> R), ((B * C) --> S), |-, (((A * B) --> R) && ((B * C) --> S)), Truth_Intersection )
R2VarIntro( ((A * C) --> M), (((A * B) --> R) && ((B * C) --> S)), |-, ((((A * B) --> R) && ((B * C) --> S)) ==> ((A * C) --> M)), Truth_Induction )

//!Variable elimination in Cycle_SpecialInferences

//Mandatory NAL7/8 is not optional and handled by sensorimotor inference, see Inference.h!

//NAL term reductions

//!Extensional intersection, union, conjunction reductions:
ReduceTerm( (A & A), A )
ReduceTerm( (A | A), A )
ReduceStatement( (A && A), A )

//!Extensional set reductions:
ReduceTerm( ({A} | {B}), {A B} )
ReduceTerm( ({A B} | {C}), {(A . B) C} )
ReduceTerm( ({C} | {A B}), {C (A . B)} )

//!Intensional set reductions:
ReduceTerm( ([A] & [B]), [A B] )
ReduceTerm( ([A B] & [C]), [(A . B) C] )
ReduceTerm( ([A] & [B C]), [A (B . C)] )

//!Reduction for set element copula:
ReduceTerm( {(A . B)}, {A B} )
ReduceTerm( [(A . B)], [A B] )

Module: NAR



// NAR - The main reasoner module //

//The API to send events to the reaasoner

//and to register operations it can invoke

//plus initialization and execution of inference steps

//Parameters//
#define NAR_DEFAULT_TRUTH ((Truth) { .frequency = NAR_DEFAULT_FREQUENCY, .confidence = NAR_DEFAULT_CONFIDENCE })
extern long currentTime;
extern double QUESTION_PRIMING;

//Callback function types//

//typedef Feedback (*Action)(Term); //already defined in Memory

//Methods//

//Init/Reset system
void NAR_INIT();

//Run the system for a certain amount of cycles
void NAR_Cycles(int cycles);

//Add input
Event NAR_AddInput(Term term, char type, Truth truth, bool eternal, double occurrenceTimeOffset);
Event NAR_AddInputBelief(Term term);
Event NAR_AddInputGoal(Term term);

//Add an operation
void NAR_AddOperation(char *atomname, Action procedure);

//Add an Narsese sentence:
void NAR_AddInputNarsese(char *narsese_sentence);

//Add an Narsese sentence with query functionality for questions:
void NAR_AddInputNarsese2(char *narsese_sentence, bool queryCommand, double answerTruthExpThreshold);

Module: NARSESE



// Narsese encoder //

//Supports converting Narsese strings to compound terms

//and dictates the format of the internal compound term encoding

//TODO add grammar

//Data structure//

//Atomic term names:
extern char Narsese_atomNames[ATOMS_MAX][ATOMIC_TERM_LEN_MAX];
extern char Narsese_operatorNames[OPERATIONS_MAX][ATOMIC_TERM_LEN_MAX];
extern Atom SELF;
#define Narsese_RuleTableVars "ABCMRSPXYZ"
#define Naresese_CanonicalCopulas "@*&|;:=$'\"/\\.-%#~+!?^_,"
#define PRODUCT '*'
#define EXT_INTERSECTION '&'
#define INT_INTERSECTION '|'
#define CONJUNCTION ';'
#define INHERITANCE ':'
#define SIMILARITY '='
#define TEMPORAL_IMPLICATION '$'
#define INT_SET '\''
#define EXT_SET '"'
#define EXT_IMAGE1 '/'
#define INT_IMAGE1 '\\'
#define SET_ELEMT '.'
#define EXT_DIFFERENCE '-'
#define EXT_IMAGE2 '%'
#define INT_IMAGE2 '#'
#define INT_DIFFERENCE '~'
#define SEQUENCE '+'
#define NEGATION '!'
#define IMPLICATION '?'
#define EQUIVALENCE '^'
#define DISJUNCTION '_'
#define HAS_CONTINUOUS_PROPERTY ','
#define SET_TERMINATOR '@'

//Methods//

//Initializes encoder
void Narsese_INIT();

//Expands Narsese into by strtok(str," ") tokenizable string with canonical copulas
char* Narsese_Expand(char *narsese);

//Tokenize expanded Narsese in prefix copula order
char** Narsese_PrefixTransform(char* narsese_expanded);

//Parses a Narsese string to a compound term
Term Narsese_Term(char *narsese);

//Parses a Narsese string to a compound term and a tv, tv is default if not present
void Narsese_Sentence(char *narsese, Term *destTerm, char *punctuation, int *tense, Truth *destTv, double *occurrenceTimeOffset);

//Encodes a sequence
Term Narsese_Sequence(Term *a, Term *b, bool *success);

//Parses an atomic term string to a term
Term Narsese_AtomicTerm(char *name);

//Index of atomic term
int Narsese_AtomicTermIndex(char *name);
int Narsese_CopulaIndex(char name);

//Print an atom
void Narsese_PrintAtom(Atom atom);

//Print a term
void Narsese_PrintTerm(Term *term);

//Whether it is a certain copula:
bool Narsese_copulaEquals(Atom atom, char name);

//Whether it is an operator
bool Narsese_isOperator(Atom atom);

//Get operator id
Atom Narsese_getOperationAtom(Term *term);

//Get operation term
Term Narsese_getOperationTerm(Term *term);

//Is an operation
bool Narsese_isOperation(Term *term);

//Is an executable op (has {SELF} or variable as first arg)
bool Narsese_isExecutableOperation(Term *term);

//Get precondition without operation
Term Narsese_GetPreconditionWithoutOp(Term *precondition);

//Get whether something is a true atom, not a copula or variable
bool Narsese_IsSimpleAtom(Atom atom);

//Whether the term has a simple atom
bool Narsese_HasSimpleAtom(Term *term);

//Whether two Narsese strings are equal
bool Narsese_StringEqual(char *name1, char *name2);

//The hash code of a string
HASH_TYPE Narsese_StringHash(char *name);

//Whether the term has an operation
bool Term_HasOperation(Term *term);

//Append a sequence in left-nested way:
bool Narsese_OperationSequenceAppendLeftNested(Term *start, Term *sequence);

Module: OCCURRENCETIMEINDEX



// Occurrence time index //

//The occurrence time OccurrenceTimeIndex for efficient query of to an event temporally related concepts

//used for event sequencing, and overrides the oldest concept reference when full on Add

//Data structure//

typedef struct
{
int itemsAmount;
int currentIndex;
Concept* array[OCCURRENCE_TIME_INDEX_SIZE];
} OccurrenceTimeIndex;

//Methods//

//Add an event to the OccurrenceTimeIndex
void OccurrenceTimeIndex_Add(Concept *concept, OccurrenceTimeIndex *fifo);

//Get the k-th newest OccurrenceTimeIndex element
Concept* OccurrenceTimeIndex_GetKthNewestElement(OccurrenceTimeIndex *fifo, int k);

Module: PRIORITYQUEUE



// Priority queue //

//The priority queue for concepts

//In the system concepts are ranked by usefulness for forgetting using this structure

//Also event PQ's are ranked by priority for attention and forgetting

//Note: Concept attention is not done using this structure, it's done by taking the priority-max of a concept chain of event-related concepts returned by InvertedAtomIndex.

//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.

//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

//Data structure//

typedef struct
{
double priority;
void *address;
} Item;

typedef struct
{
Item *items;
int itemsAmount;
int maxElements;
} PriorityQueue;

typedef struct
{
bool added;
Item addedItem;
bool evicted;
Item evictedItem;
} PriorityQueue_Push_Feedback;

//Methods//

//Resets the priority queue
void PriorityQueue_INIT(PriorityQueue *queue, Item *items, int maxElements);

//Push element of a certain priority into the queue.

//If successful, addedItem will point to the item in the data structure, with address of the evicted item, if eviction happened
PriorityQueue_Push_Feedback PriorityQueue_Push(PriorityQueue *queue, double priority);

//use this function and add again if maybe lower!
bool PriorityQueue_PopAt(PriorityQueue *queue, int i, void** returnItemAddress);

//Rebuilds the data structure by re-inserting all elements:
void PriorityQueue_Rebuild(PriorityQueue *queue);

//Pops minimum element
bool PriorityQueue_PopMin(PriorityQueue *queue, void** returnItemAddress, double* returnItemPriority);

//Pops maximum element
bool PriorityQueue_PopMax(PriorityQueue *queue, void** returnItemAddress, double* returnItemPriority);

Module: RULETABLE



// RuleTable //

//The rule table which .c is generated at compile time

//by NAL_GenerateRuleTable

//The C code in RuleTable.c which implements the methods of this header

//is generated from the inference rules specified in

//NAL.h using the code generation code in NAL.c

//Methods//
void RuleTable_Apply(Term term1, Term term2, Truth truth1, Truth truth2, long conclusionOccurrence, double occurrenceTimeOffset, Stamp conclusionStamp,
long currentTime, double parentPriority, double conceptPriority, bool doublePremise, Concept *validation_concept, long validation_cid);
Term RuleTable_Reduce(Term term1);

Module: SHELL



// Shell //

//The shell for interaction with NAR

//It accepts Narsese input and output,

//together with various commands starting with *

//Data structure//
#define SHELL_CONTINUE 0
#define SHELL_RESET 1
#define SHELL_EXIT 2

//Methods//

//Initializes the shell NAR and runs it with stdin/stdout
void Shell_Start();

//Only initializes the shell NAR with the default ops, but can be used differently
void Shell_NARInit();

//Process a shell input line, can be comments, timesteps, Narsese, and commands, returns if system reset was issued
int Shell_ProcessInput(char *line);

Module: STACK



// Stack //

//The stack for use by the hashtable

//Data structure//

typedef struct
{
void** items;
int stackpointer;
int maxElements;
} Stack;

//Methods//
void Stack_INIT(Stack *stack, void **items, int maxElements);

//Add a VMItem on the top of the stack
void Stack_Push(Stack *stack, void *item);

//Remove a VMItem from the top of the stack
void* Stack_Pop(Stack *stack);

//Check if there aren't VMItems left on the stack
bool Stack_IsEmpty(Stack *stack);

Module: STAMP



// Stamp //

//Keeps track of evidental bases

//This ensures that evidence is only counted once in the conclusions the system makes

//Design decisions:

//- Stamps are merged by zipping two existing stamps

//- Stamps have a max. capacity which controls how far the zipping goes

//- Since new inputs have a single stamp entry, new stamp entries will be in the beginning (1. or 2. element) of the stamp after revision

//Data structure//

//Stamp as implemented by all NARS implementations
#define STAMP_FREE 0

typedef struct {
//EvidentalBase of stamp
long evidentalBase[STAMP_SIZE];
} Stamp;

//Methods//

//zip stamp1 and stamp2 into a stamp
Stamp Stamp_make(Stamp *stamp1, Stamp *stamp2);

//true iff there is evidental base overlap between a and b
bool Stamp_checkOverlap(Stamp *a, Stamp *b);

//Whether two stamps are equal
bool Stamp_Equal(Stamp *a, Stamp *b);

//print stamp
void Stamp_print(Stamp *stamp);

Module: STATS



// Runtime stats //

//The stats module serves to collect various random statistics of the reasoner

//Global vars//
extern long Stats_countConceptsMatchedTotal;
extern long Stats_countConceptsMatchedMax;

//From Narsese module, for stats purposes:
extern HashTable HTatoms;

//Methods//
void Stats_Print(long currentTime);

Module: TABLE



// Table //

//A bounded table of temporal implications, ranked by truth expectation

//Also revision and choice is supported in this structure

//Please note: when a new item has lower truth expectation

//than the lowest in the table, it will still replace the lowest.

//This makes sure the system can still adapt when tables are full,

//by giving the new link a place to grow.

//As this isn't ideal yet, later version this might either be extended

//to multiple places at the bottom of the table,

//or the ranking will take the creation time of links into account

//Data structure//

//A truth-expectation-ranked table for Implications, similar as pre- and post-condition table in OpenNARS,

//except that this table supports revision by itself (as in NAR implications don't form concepts).

typedef struct {
Implication array[TABLE_SIZE];
int itemsAmount;
} Table;

//Methods//

//Add implication to table
Implication *Table_Add(Table *table, Implication *imp);

//Add element at index from table
void Table_Remove(Table *table, int index);

//Add implication to table while allowing revision
Implication* Table_AddAndRevise(Table *table, Implication *imp);

Module: TERM



// Term //

//Description//

//A term is a hashed array of atoms (which also includes atoms for copulas)

//The encoding used is that of a binary heap.

//Please note: this encoding is relative space-wasteful for terms of low complexity

//Future versions of this module might utilize an index-sorted array of (index, atom) tuples

//however this will be a major change.

//Data structure//
#define HASH_TYPE_SIZE sizeof(HASH_TYPE)
#define TERM_ATOMS_SIZE (sizeof(Atom)*COMPOUND_TERM_SIZE_MAX)

typedef struct
{
bool hashed;
HASH_TYPE hash;
Atom atoms[COMPOUND_TERM_SIZE_MAX];
}Term;

//Methods//

//Whether two Term's are equal completely
bool Term_Equal(Term *a, Term *b);

//Overwrites a subterm
bool Term_OverrideSubterm(Term *term, int i, Term *subterm);

//Extract a subterm as a term
Term Term_ExtractSubterm(Term *term, int j);

//The complexity of a term
int Term_Complexity(Term *term);

//Hash of a term (needed by the term->concept HashTable)
HASH_TYPE Term_Hash(Term *term);

//Whether the term has the atom
bool Term_HasAtom(Term *term, Atom atom);

Module: TRUTH



// NAL truth value and truth functions //

//Truth functions as specified in the NAL book (2013)

//Data structure//

typedef struct {
//Frequency
double frequency;
//Confidence
double confidence;
} Truth;

//Parameters//
extern double TRUTH_EVIDENTAL_HORIZON;
extern double TRUTH_PROJECTION_DECAY;
#define OCCURRENCE_ETERNAL -1
#define STRUCTURAL_TRUTH (Truth) { .frequency = 1.0, .confidence = RELIANCE }

//Methods//
double Truth_w2c(double w);
double Truth_c2w(double c);
double Truth_Expectation(Truth v);
Truth Truth_Revision(Truth v1, Truth v2);
Truth Truth_Deduction(Truth v1, Truth v2);
Truth Truth_Induction(Truth v1, Truth v2);
Truth Truth_Intersection(Truth v1, Truth v2);
Truth Truth_Eternalize(Truth v);
Truth Truth_Projection(Truth v, long originalTime, long targetTime);
void Truth_Print(Truth *truth);
void Truth_Print2(Truth *truth);
Truth Truth_GoalDeduction(Truth v1, Truth v2);

//not part of sensorimotor inference:
Truth Truth_Abduction(Truth v1, Truth v2);
Truth Truth_Exemplification(Truth v1, Truth v2);
Truth Truth_Comparison(Truth v1, Truth v2);
Truth Truth_Analogy(Truth v1, Truth v2);
Truth Truth_Resemblance(Truth v1, Truth v2);
Truth Truth_StructuralDeduction(Truth v1, Truth v2);
Truth Truth_StructuralDeductionNegated(Truth v1, Truth v2);
Truth Truth_StructuralIntersection(Truth v1, Truth v2);
Truth Truth_Union(Truth v1, Truth v2);
Truth Truth_Difference(Truth v1, Truth v2);
Truth Truth_Conversion(Truth v1, Truth v2);
Truth Truth_Negation(Truth v1, Truth v2);
Truth Truth_DecomposePNN(Truth v1, Truth v2);
Truth Truth_DecomposeNPP(Truth v1, Truth v2);
Truth Truth_DecomposePNP(Truth v1, Truth v2);
Truth Truth_DecomposePPP(Truth v1, Truth v2);
Truth Truth_DecomposeNNN(Truth v1, Truth v2);
Truth Truth_AnonymousAnalogy(Truth v1, Truth v2);
Truth Truth_FrequencyGreater(Truth v1, Truth v2);
Truth Truth_FrequencyEqual(Truth v1, Truth v2);
bool Truth_Equal(Truth *v1, Truth *v2);

Module: USAGE



// concept usefulness value //

//Usefulness value consists of both use count and last used

//since new concepts need a grace period where they

//can prove themselves to be useful

//This is a solution of stability-plasticity dilemma.

//Data structure//

typedef struct {
//use_count, how often it was used in total
long useCount;
//age, how many cycles ago it was last used
long lastUsed;
} Usage;

//Methods//

//how useful it is in respect to the current moment
double Usage_usefulness(Usage usage, long currentTime);

//use the item
Usage Usage_use(Usage usage, long currentTime, bool eternalInput);

//print it
void Usage_Print(Usage *usage);

Module: VARIABLE



// Variable utilities //

//Support for NAL-6 variables

//This includes the ability to:

//- check for variables in terms

//- variable normalization

//- unification returning an unifier

//- substitution using an unifier

//- introduction of variables

//Data structure//

//Substitution, mapping variable atoms to terms

typedef struct {
Term map[27+1]; //there can only be 27 variables: $1 to $9 and #1 to #9 and ?1 to ?9, but it can't be 0
bool success;
} Substitution;

//Methods//

//Whether the atom is an independent variable, $i
bool Variable_isIndependentVariable(Atom atom);

//Whether the atom is a dependent variable, #1
bool Variable_isDependentVariable(Atom atom);

//Whether the atom is a query variable, ?1
bool Variable_isQueryVariable(Atom atom);

//Whether the atom is any variable
bool Variable_isVariable(Atom atom);

//Whether the term has variables of certain kind
bool Variable_hasVariable(Term *term, bool independent, bool dependent, bool query);

//Unify two terms, returning the substitution/unifier
Substitution Variable_Unify(Term *general, Term *specific);
Substitution Variable_Unify2(Term *general, Term *specific, bool unifyQueryVarOnly);

//Applying the substitution to a term, returning success
Term Variable_ApplySubstitute(Term term, Substitution substitution, bool *success);

//Introduce variables in an implication
Term Variable_IntroduceImplicationVariables(Term implication, bool *success, bool extensionally);

//Introduce var in conjunction
Term Variable_IntroduceConjunctionVariables(Term conjunction, bool *success, bool extensionally);

//Normalize variables, transforming ?what to ?1 for instance.
void Variable_Normalize(Term *term);

Module: GLOBALS



// Globals //

//Various macros and utility functions which turned out to be necessary.

//Macros//

//Whether debug mode should be on
#define DEBUG false

//Exit with stats output
#define EXIT_STATS false

//Whether input should be printed
#define PRINT_INPUT_INITIAL true

//Whether derivations should be printed
#define PRINT_DERIVATIONS_INITIAL false

//Whether control information should be printed
#define PRINT_CONTROL_INFO false

//Whether surprisingness of events should be printed
#define PRINT_SURPRISE false

//Priority threshold for printing derivations
#define PRINT_EVENTS_PRIORITY_THRESHOLD_INITIAL 0.0

//Debug macros, debug printing, assert:
#define IN_DEBUG(x) {if(DEBUG){ x } }

//assert, printing message and exiting if b=false
void Globals_assert(bool b, char* message);
#define assert Globals_assert
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

//Number of elements of compile time allocated array:
#define NUM_ELEMENTS(array) (sizeof(array)/sizeof(array[0]))

//Generic hash function on byte array
#define HASH_TYPE long
HASH_TYPE Globals_Hash(HASH_TYPE *data, int pieces);

//Random number generator for reproducibility across platforms
int myrand(void);
void mysrand(unsigned int seed);
#define MY_RAND_MAX 32767

//Stringification macro:
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)