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)