diff --git a/CMakeLists.txt b/CMakeLists.txt
index f3d1d478..98d49d5f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,6 +64,9 @@ INCLUDE(TorchExports)
# Torch libraries
ADD_SUBDIRECTORY(lib)
+# OpenCog Multi-Dimensional Tensor Inference Engine
+ADD_SUBDIRECTORY(opencog)
+
CONFIGURE_FILE(paths.lua.in "${CMAKE_CURRENT_BINARY_DIR}/paths.lua")
INCLUDE_DIRECTORIES(BEFORE "${LUA_INCDIR}")
diff --git a/README.md b/README.md
index 9495540c..d55c2c5b 100644
--- a/README.md
+++ b/README.md
@@ -18,14 +18,26 @@ Torch7 community support can be found at the following locations. As of 2019, th
# Torch Package Reference Manual #
-__Torch__ is the main package in [Torch7](http://torch.ch) where data
-structures for multi-dimensional tensors and mathematical operations
-over these are defined. Additionally, it provides many utilities for
-accessing files, serializing objects of arbitrary types and other
-useful utilities.
+__TorCog__ is an enhanced version of [Torch7](http://torch.ch) that implements
+**OpenCog as a Multi-Dimensional Tensor Inference Engine**. It provides the
+original Torch tensor library enhanced with a complete OpenCog cognitive
+architecture using tensors for knowledge representation, inference, and
+attention allocation.
-## Torch Packages ##
+## TorCog Packages ##
+
+### OpenCog Multi-Dimensional Tensor Inference Engine
+
+ * **[OpenCog Tensor Engine](opencog/README.md)** - Complete OpenCog cognitive architecture implementation using multi-dimensional tensors
+ * [Tensor-based Atoms](opencog/atoms/) - Knowledge representation with high-dimensional embeddings
+ * [Inference Engine](opencog/inference/) - Rule-based reasoning with neural components
+ * [Attention Allocation](opencog/attention/) - Neural attention mechanism with tensor dynamics
+ * Pattern matching and similarity using tensor operations
+ * Probabilistic reasoning with uncertainty propagation
+ * Hebbian learning and neural adaptation
+
+### Original Torch Components
* Tensor Library
* [Tensor](doc/tensor.md) defines the _all powerful_ tensor object that provides multi-dimensional numerical arrays with type templating.
diff --git a/opencog/CMakeLists.txt b/opencog/CMakeLists.txt
new file mode 100644
index 00000000..5072c44a
--- /dev/null
+++ b/opencog/CMakeLists.txt
@@ -0,0 +1,72 @@
+# OpenCog Multi-Dimensional Tensor Inference Engine
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
+
+SET(CMAKE_MODULE_PATH
+ "${CMAKE_CURRENT_SOURCE_DIR}/../cmake"
+ "${CMAKE_MODULE_PATH}")
+
+# Source files for OpenCog components
+SET(OPENCOG_ATOMS_SRC
+ atoms/opencog_atoms.c
+)
+
+SET(OPENCOG_INFERENCE_SRC
+ inference/inference_engine.c
+)
+
+SET(OPENCOG_ATTENTION_SRC
+ attention/attention_allocation.c
+)
+
+SET(OPENCOG_CORE_SRC
+ opencog.c
+)
+
+SET(OPENCOG_TEST_SRC
+ test_opencog.c
+)
+
+# Tensor wrapper source
+SET(OPENCOG_TENSOR_SRC
+ tensor_wrapper.c
+)
+
+# All OpenCog sources
+SET(OPENCOG_ALL_SRC
+ ${OPENCOG_TENSOR_SRC}
+ ${OPENCOG_ATOMS_SRC}
+ ${OPENCOG_INFERENCE_SRC}
+ ${OPENCOG_ATTENTION_SRC}
+ ${OPENCOG_CORE_SRC}
+)
+
+# Include directories
+# Include current directory for tensor wrapper
+INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}")
+
+# Create OpenCog library
+ADD_LIBRARY(opencog SHARED ${OPENCOG_ALL_SRC})
+
+# Link with math library (no longer need TH)
+# TARGET_LINK_LIBRARIES(opencog TH)
+
+# Math library for mathematical functions
+TARGET_LINK_LIBRARIES(opencog m)
+
+# Create test executable
+ADD_EXECUTABLE(test_opencog ${OPENCOG_TEST_SRC})
+TARGET_LINK_LIBRARIES(test_opencog opencog m)
+
+# Create demo executable
+ADD_EXECUTABLE(example_opencog_demo example_opencog_demo.c)
+TARGET_LINK_LIBRARIES(example_opencog_demo opencog m)
+
+# Install OpenCog library and headers
+INSTALL(TARGETS opencog DESTINATION lib)
+INSTALL(FILES opencog.h DESTINATION include/opencog)
+INSTALL(FILES atoms/opencog_atoms.h DESTINATION include/opencog/atoms)
+INSTALL(FILES inference/inference_engine.h DESTINATION include/opencog/inference)
+INSTALL(FILES attention/attention_allocation.h DESTINATION include/opencog/attention)
+
+# Install test and demo executables
+INSTALL(TARGETS test_opencog example_opencog_demo DESTINATION bin)
\ No newline at end of file
diff --git a/opencog/README.md b/opencog/README.md
new file mode 100644
index 00000000..056ce886
--- /dev/null
+++ b/opencog/README.md
@@ -0,0 +1,265 @@
+# OpenCog Multi-Dimensional Tensor Inference Engine
+
+This directory contains the implementation of OpenCog as a multi-dimensional tensor inference engine, built on top of the Torch tensor library. This implementation provides a tensor-based cognitive architecture that combines symbolic reasoning with neural computation.
+
+## Overview
+
+The OpenCog Tensor Inference Engine implements the core components of the OpenCog cognitive architecture using multi-dimensional tensors for efficient computation:
+
+- **Tensor-based Atoms**: All knowledge is represented as atoms with high-dimensional tensor embeddings
+- **Truth Value Computations**: Probabilistic truth values computed using tensor operations
+- **Attention Allocation**: Neural attention mechanism with tensor-based dynamics
+- **Pattern Matching**: Efficient pattern matching using tensor similarity computations
+- **Inference Engine**: Rule-based reasoning with neural network components
+- **Learning System**: Hebbian learning and neural adaptation using tensor updates
+
+## Architecture
+
+### Core Components
+
+1. **Atoms and AtomSpace** (`atoms/`)
+ - `OCAtom`: Basic knowledge representation with tensor embeddings
+ - `OCTruthValue`: Probabilistic truth values using tensors
+ - `OCAtomSpace`: Container for all atoms with relationship matrices
+
+2. **Inference Engine** (`inference/`)
+ - `OCInferenceEngine`: Main reasoning engine
+ - `OCInferenceRule`: Configurable inference rules
+ - `OCPattern`: Pattern matching system
+ - Built-in rules: deduction, induction, abduction, revision
+
+3. **Attention Allocation** (`attention/`)
+ - `OCAttentionBank`: Central attention management system
+ - `OCAttentionAgent`: Specialized attention processing agents
+ - Attention dynamics: spreading, decay, competition, novelty detection
+
+4. **Main API** (`opencog.h/c`)
+ - High-level interface for the complete system
+ - Configuration management
+ - Statistics and monitoring
+ - Error handling
+
+### Key Features
+
+#### Tensor-Based Representation
+- Each atom has a high-dimensional embedding vector (default: 128 dimensions)
+- Truth values are represented as tensors enabling batch operations
+- Attention values (STI, LTI, VLTI) stored as tensor components
+- Relationship matrices for efficient graph operations
+
+#### Neural-Symbolic Integration
+- Symbolic atoms with neural embeddings
+- Truth value propagation using tensor mathematics
+- Neural attention mechanisms
+- Hebbian learning for association strengthening
+- Backpropagation for embedding optimization
+
+#### Attention Allocation System
+- Short-Term Importance (STI) for working memory
+- Long-Term Importance (LTI) for episodic memory
+- Very Long-Term Importance (VLTI) for semantic memory
+- Attention spreading through atom connections
+- Economic model with rent collection and resource allocation
+
+#### Inference Capabilities
+- Forward chaining inference
+- Backward chaining (goal-directed reasoning)
+- Pattern matching with tensor similarity
+- Probabilistic reasoning with uncertainty propagation
+- Temporal reasoning support
+
+## Usage Examples
+
+### Basic System Setup
+
+```c
+#include "opencog/opencog.h"
+
+// Create OpenCog system with default configuration
+OpenCog *opencog = OpenCog_new(NULL);
+
+// Add some knowledge
+OCAtom *cat = OpenCog_addConcept(opencog, "cat", 0.9f, 0.8f);
+OCAtom *animal = OpenCog_addConcept(opencog, "animal", 0.95f, 0.9f);
+
+// Create relationship
+OpenCog_associateAtoms(opencog, cat, animal, 0.85f);
+
+// Run inference
+OpenCog_forwardChain(opencog, 10);
+
+// Clean up
+OpenCog_free(opencog);
+```
+
+### Attention and Learning
+
+```c
+// Enable attention and learning
+OCConfig *config = OpenCog_getDefaultConfig();
+config->enable_attention = 1;
+config->enable_hebbian_learning = 1;
+
+OpenCog *opencog = OpenCog_new(config);
+
+// Add concepts
+OCAtom *red = OpenCog_addConcept(opencog, "red", 0.8f, 0.7f);
+OCAtom *apple = OpenCog_addConcept(opencog, "apple", 0.9f, 0.8f);
+
+// Boost attention to activate learning
+OpenCog_boostAttention(opencog, red, 20.0f);
+OpenCog_boostAttention(opencog, apple, 15.0f);
+
+// Run attention cycles
+for (int i = 0; i < 10; i++) {
+ OpenCog_stepAttention(opencog);
+}
+
+// Check attentional focus
+int focus_count;
+OCAtom **focus = OpenCog_getAttentionalFocus(opencog, &focus_count);
+```
+
+### Pattern Matching and Similarity
+
+```c
+// Create atoms
+OCAtom *dog = OpenCog_addConcept(opencog, "dog", 0.85f, 0.75f);
+OCAtom *wolf = OpenCog_addConcept(opencog, "wolf", 0.8f, 0.7f);
+
+// Compute similarity using tensor embeddings
+float similarity = OpenCog_similarity(opencog, dog, wolf);
+printf("Similarity between dog and wolf: %.3f\n", similarity);
+
+// Find similar atoms
+int similar_count;
+OCAtom **similar = OpenCog_findSimilarAtoms(opencog, dog, 0.5f, &similar_count);
+```
+
+## Building
+
+The OpenCog tensor engine is built as part of the main TorCog project:
+
+```bash
+mkdir build
+cd build
+cmake ..
+make opencog
+```
+
+To run tests:
+```bash
+./opencog/test_opencog
+```
+
+## Configuration
+
+The system can be configured using `OCConfig`:
+
+```c
+OCConfig *config = OpenCog_getDefaultConfig();
+
+// Adjust system limits
+config->max_atoms = 50000;
+config->max_inference_steps = 200;
+config->embedding_dimensions = 256;
+
+// Control components
+config->enable_attention = 1;
+config->enable_forgetting = 1;
+config->enable_hebbian_learning = 1;
+
+// Learning parameters
+config->learning_rate = 0.05f;
+config->confidence_threshold = 0.6f;
+config->attention_threshold = 0.2f;
+
+OpenCog *opencog = OpenCog_new(config);
+```
+
+## Performance Considerations
+
+### Memory Usage
+- Each atom requires ~1KB base memory + embedding size
+- Default embedding: 128 dimensions × 4 bytes = 512 bytes per atom
+- Attention matrices: O(N²) where N is max_atoms
+- Inference matrices: O(N²) space for relationship storage
+
+### Computational Complexity
+- Atom similarity: O(D) where D is embedding dimension
+- Attention spreading: O(N×E) where E is average edges per atom
+- Forward chaining: O(R×N²) where R is number of rules
+- Pattern matching: O(N×D) for tensor-based matching
+
+### Optimization Tips
+- Use smaller embedding dimensions for memory-constrained environments
+- Limit max_atoms based on available RAM
+- Adjust attention_threshold to control focus size
+- Use sparse tensors for large, mostly-zero relationship matrices
+
+## Advanced Features
+
+### Custom Inference Rules
+```c
+OCInferenceRule *custom_rule = OCInferenceRule_new(OC_DEDUCTION_RULE, "my_rule");
+// Set custom truth value function
+custom_rule->tv_function = my_custom_tv_function;
+OCInferenceEngine_addRule(opencog->inference, custom_rule);
+```
+
+### Neural Training
+```c
+// Train atom embeddings
+THTensor *target_embedding = THTensor_(newWithSize1d)(128);
+// ... set target values ...
+OpenCog_trainEmbedding(opencog, atom, target_embedding);
+
+// Train attention networks
+OpenCog_trainNeuralComponent(opencog, "attention_network", inputs, targets);
+```
+
+### Monitoring and Analysis
+```c
+// Get system statistics
+char stats[1000];
+OpenCog_getStats(opencog, stats, sizeof(stats));
+
+// Export embeddings for analysis
+THTensor *embeddings = OpenCog_getAtomEmbeddings(opencog);
+
+// Get attention distribution
+THTensor *attention_dist = OCAttentionBank_getAttentionDistribution(opencog->attention);
+```
+
+## Integration with Other Systems
+
+The OpenCog tensor engine can be integrated with:
+
+- **Neural Networks**: Export embeddings for deep learning models
+- **Symbolic Reasoners**: Import/export logical statements
+- **Databases**: Serialize atomspace to persistent storage
+- **Robotics**: Real-time sensor integration and motor control
+- **NLP Systems**: Language understanding and generation
+
+## Future Extensions
+
+Planned enhancements include:
+
+- GPU acceleration using CUDA tensors
+- Distributed atomspace across multiple nodes
+- Quantum-inspired tensor operations
+- Evolutionary optimization of inference rules
+- Integration with large language models
+- Real-time streaming data processing
+
+## References
+
+- OpenCog Framework: https://opencog.org/
+- Torch Tensor Library: https://github.com/torch/torch7
+- "The OpenCog Cognitive Architecture" by Ben Goertzel
+- "Probabilistic Logic Networks" by Ben Goertzel et al.
+- "Attention Allocation in OpenCog" by Nil Geisweiller
+
+## License
+
+This implementation is released under the same license as the parent TorCog project.
\ No newline at end of file
diff --git a/opencog/atoms/opencog_atoms.c b/opencog/atoms/opencog_atoms.c
new file mode 100644
index 00000000..4e8088c4
--- /dev/null
+++ b/opencog/atoms/opencog_atoms.c
@@ -0,0 +1,358 @@
+#include "opencog_atoms.h"
+#include
+#include
+#include
+
+/* Default embedding dimension for atoms */
+#ifndef OC_DEFAULT_EMBEDDING_DIM
+#define OC_DEFAULT_EMBEDDING_DIM 128
+#endif
+#ifndef OC_DEFAULT_ATTENTION_DIM
+#define OC_DEFAULT_ATTENTION_DIM 3 // STI, LTI, VLTI
+#endif
+
+/* Atom Creation and Management */
+OCAtom* OCAtom_new(OCAtomType type, const char *name) {
+ OCAtom *atom = (OCAtom*)malloc(sizeof(OCAtom));
+ if (!atom) return NULL;
+
+ atom->type = type;
+ atom->name = name ? strdup(name) : NULL;
+
+ // Create default embedding tensor
+ atom->embedding = OCTensor_newWithSize1d(OC_DEFAULT_EMBEDDING_DIM);
+ OCTensor_zero(atom->embedding);
+
+ // Create attention tensor (STI, LTI, VLTI)
+ atom->attention = OCTensor_newWithSize1d(OC_DEFAULT_ATTENTION_DIM);
+ OCTensor_zero(atom->attention);
+
+ atom->tv = NULL;
+ atom->incoming = NULL;
+ atom->outgoing = NULL;
+ atom->incoming_count = 0;
+ atom->outgoing_count = 0;
+ atom->atom_id = 0;
+ atom->refcount = 1;
+
+ return atom;
+}
+
+OCAtom* OCAtom_newWithEmbedding(OCAtomType type, const char *name, OCTensor *embedding) {
+ OCAtom *atom = OCAtom_new(type, name);
+ if (!atom) return NULL;
+
+ if (embedding) {
+ OCTensor_free(atom->embedding);
+ atom->embedding = OCTensor_newWithTensor(embedding);
+ }
+
+ return atom;
+}
+
+void OCAtom_retain(OCAtom *atom) {
+ if (atom) {
+ atom->refcount++;
+ }
+}
+
+void OCAtom_free(OCAtom *atom) {
+ if (!atom) return;
+
+ atom->refcount--;
+ if (atom->refcount > 0) return;
+
+ if (atom->name) free(atom->name);
+ if (atom->embedding) OCTensor_free(atom->embedding);
+ if (atom->attention) OCTensor_free(atom->attention);
+ if (atom->tv) OCTruthValue_free(atom->tv);
+
+ if (atom->incoming) free(atom->incoming);
+ if (atom->outgoing) free(atom->outgoing);
+
+ free(atom);
+}
+
+void OCAtom_setTruthValue(OCAtom *atom, OCTruthValue *tv) {
+ if (!atom) return;
+
+ if (atom->tv) OCTruthValue_free(atom->tv);
+ atom->tv = tv;
+}
+
+void OCAtom_addIncoming(OCAtom *atom, OCAtom *incoming) {
+ if (!atom || !incoming) return;
+
+ atom->incoming = (OCAtom**)realloc(atom->incoming,
+ sizeof(OCAtom*) * (atom->incoming_count + 1));
+ atom->incoming[atom->incoming_count] = incoming;
+ atom->incoming_count++;
+ OCAtom_retain(incoming);
+}
+
+void OCAtom_addOutgoing(OCAtom *atom, OCAtom *outgoing) {
+ if (!atom || !outgoing) return;
+
+ atom->outgoing = (OCAtom**)realloc(atom->outgoing,
+ sizeof(OCAtom*) * (atom->outgoing_count + 1));
+ atom->outgoing[atom->outgoing_count] = outgoing;
+ atom->outgoing_count++;
+ OCAtom_retain(outgoing);
+}
+
+/* Truth Value Operations */
+OCTruthValue* OCTruthValue_new(float strength, float confidence) {
+ OCTruthValue *tv = (OCTruthValue*)malloc(sizeof(OCTruthValue));
+ if (!tv) return NULL;
+
+ tv->strength = OCTensor_newWithSize1d(1);
+ tv->confidence = OCTensor_newWithSize1d(1);
+ tv->frequency = OCTensor_newWithSize1d(1);
+ tv->probability = OCTensor_newWithSize1d(1);
+
+ OCTensor_set1d(tv->strength, 0, strength);
+ OCTensor_set1d(tv->confidence, 0, confidence);
+ OCTensor_set1d(tv->frequency, 0, strength); // Default frequency = strength
+ OCTensor_set1d(tv->probability, 0, strength); // Default probability = strength
+
+ return tv;
+}
+
+OCTruthValue* OCTruthValue_newFromTensor(OCTensor *strength, OCTensor *confidence) {
+ OCTruthValue *tv = (OCTruthValue*)malloc(sizeof(OCTruthValue));
+ if (!tv) return NULL;
+
+ tv->strength = OCTensor_newWithTensor(strength);
+ tv->confidence = OCTensor_newWithTensor(confidence);
+ tv->frequency = OCTensor_newWithTensor(strength); // Default frequency = strength
+ tv->probability = OCTensor_newWithTensor(strength); // Default probability = strength
+
+ return tv;
+}
+
+void OCTruthValue_free(OCTruthValue *tv) {
+ if (!tv) return;
+
+ if (tv->strength) OCTensor_free(tv->strength);
+ if (tv->confidence) OCTensor_free(tv->confidence);
+ if (tv->frequency) OCTensor_free(tv->frequency);
+ if (tv->probability) OCTensor_free(tv->probability);
+
+ free(tv);
+}
+
+/* Truth Value Revision Formula: Combines two truth values */
+OCTruthValue* OCTruthValue_revision(OCTruthValue *tv1, OCTruthValue *tv2) {
+ if (!tv1 || !tv2) return NULL;
+
+ OCTruthValue *result = (OCTruthValue*)malloc(sizeof(OCTruthValue));
+ if (!result) return NULL;
+
+ // Initialize result tensors
+ result->strength = OCTensor_newWithSize1d(1);
+ result->confidence = OCTensor_newWithSize1d(1);
+ result->frequency = OCTensor_newWithSize1d(1);
+ result->probability = OCTensor_newWithSize1d(1);
+
+ // Temporary tensors for computation
+ OCTensor *temp1 = OCTensor_newWithSize1d(1);
+ OCTensor *temp2 = OCTensor_newWithSize1d(1);
+ OCTensor *temp3 = OCTensor_newWithSize1d(1);
+
+ // Get values
+ float s1 = OCTensor_get1d(tv1->strength, 0);
+ float c1 = OCTensor_get1d(tv1->confidence, 0);
+ float s2 = OCTensor_get1d(tv2->strength, 0);
+ float c2 = OCTensor_get1d(tv2->confidence, 0);
+
+ // Revision formula: s_rev = (s1*c1 + s2*c2) / (c1 + c2)
+ float c_sum = c1 + c2;
+ float s_rev = (c_sum > 0) ? (s1 * c1 + s2 * c2) / c_sum : 0.5;
+ float c_rev = c_sum;
+
+ OCTensor_set1d(result->strength, 0, s_rev);
+ OCTensor_set1d(result->confidence, 0, c_rev);
+ OCTensor_set1d(result->frequency, 0, s_rev);
+ OCTensor_set1d(result->probability, 0, s_rev);
+
+ OCTensor_free(temp1);
+ OCTensor_free(temp2);
+ OCTensor_free(temp3);
+
+ return result;
+}
+
+/* Truth Value Merge: Simple averaging */
+OCTruthValue* OCTruthValue_merge(OCTruthValue *tv1, OCTruthValue *tv2) {
+ if (!tv1 || !tv2) return NULL;
+
+ OCTruthValue *result = (OCTruthValue*)malloc(sizeof(OCTruthValue));
+ if (!result) return NULL;
+
+ result->strength = OCTensor_newWithTensor(tv1->strength);
+ result->confidence = OCTensor_newWithTensor(tv1->confidence);
+ result->frequency = OCTensor_newWithTensor(tv1->frequency);
+ result->probability = OCTensor_newWithTensor(tv1->probability);
+
+ // Average the values
+ OCTensor_cadd(result->strength, result->strength, 1.0, tv2->strength);
+ OCTensor_mul(result->strength, result->strength, 0.5);
+
+ OCTensor_cadd(result->confidence, result->confidence, 1.0, tv2->confidence);
+ OCTensor_mul(result->confidence, result->confidence, 0.5);
+
+ OCTensor_cadd(result->frequency, result->frequency, 1.0, tv2->frequency);
+ OCTensor_mul(result->frequency, result->frequency, 0.5);
+
+ OCTensor_cadd(result->probability, result->probability, 1.0, tv2->probability);
+ OCTensor_mul(result->probability, result->probability, 0.5);
+
+ return result;
+}
+
+/* AtomSpace Operations */
+OCAtomSpace* OCAtomSpace_new(long max_atoms) {
+ OCAtomSpace *atomspace = (OCAtomSpace*)malloc(sizeof(OCAtomSpace));
+ if (!atomspace) return NULL;
+
+ atomspace->atoms = (OCAtom**)calloc(max_atoms, sizeof(OCAtom*));
+ if (!atomspace->atoms) {
+ free(atomspace);
+ return NULL;
+ }
+
+ // Create atom relationship matrix (max_atoms x max_atoms)
+ atomspace->atom_matrix = OCTensor_newWithSize2d(max_atoms, max_atoms);
+ OCTensor_zero(atomspace->atom_matrix);
+
+ // Create attention allocation matrix
+ atomspace->attention_matrix = OCTensor_newWithSize2d(max_atoms, OC_DEFAULT_ATTENTION_DIM);
+ OCTensor_zero(atomspace->attention_matrix);
+
+ atomspace->atom_count = 0;
+ atomspace->max_atoms = max_atoms;
+ atomspace->next_atom_id = 1;
+
+ return atomspace;
+}
+
+void OCAtomSpace_free(OCAtomSpace *atomspace) {
+ if (!atomspace) return;
+
+ // Free all atoms
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ if (atomspace->atoms[i]) {
+ OCAtom_free(atomspace->atoms[i]);
+ }
+ }
+
+ free(atomspace->atoms);
+ OCTensor_free(atomspace->atom_matrix);
+ OCTensor_free(atomspace->attention_matrix);
+ free(atomspace);
+}
+
+long OCAtomSpace_addAtom(OCAtomSpace *atomspace, OCAtom *atom) {
+ if (!atomspace || !atom || atomspace->atom_count >= atomspace->max_atoms) {
+ return -1;
+ }
+
+ atom->atom_id = atomspace->next_atom_id++;
+ atomspace->atoms[atomspace->atom_count] = atom;
+ OCAtom_retain(atom);
+
+ // Update attention matrix with atom's attention values
+ for (int i = 0; i < OC_DEFAULT_ATTENTION_DIM; i++) {
+ float att_val = OCTensor_get1d(atom->attention, i);
+ OCTensor_set2d(atomspace->attention_matrix, atomspace->atom_count, i, att_val);
+ }
+
+ atomspace->atom_count++;
+ return atom->atom_id;
+}
+
+OCAtom* OCAtomSpace_getAtom(OCAtomSpace *atomspace, long atom_id) {
+ if (!atomspace) return NULL;
+
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ if (atomspace->atoms[i] && atomspace->atoms[i]->atom_id == atom_id) {
+ return atomspace->atoms[i];
+ }
+ }
+ return NULL;
+}
+
+void OCAtomSpace_removeAtom(OCAtomSpace *atomspace, long atom_id) {
+ if (!atomspace) return;
+
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ if (atomspace->atoms[i] && atomspace->atoms[i]->atom_id == atom_id) {
+ OCAtom_free(atomspace->atoms[i]);
+ atomspace->atoms[i] = NULL;
+ break;
+ }
+ }
+}
+
+OCTensor* OCAtomSpace_getAtomMatrix(OCAtomSpace *atomspace) {
+ if (!atomspace) return NULL;
+ return atomspace->atom_matrix;
+}
+
+/* Pattern Matching and Inference */
+OCTensor* OCAtom_computeSimilarity(OCAtom *atom1, OCAtom *atom2) {
+ if (!atom1 || !atom2 || !atom1->embedding || !atom2->embedding) return NULL;
+
+ // Compute cosine similarity using dot product
+ OCTensor *result = OCTensor_newWithSize1d(1);
+
+ // Dot product of embeddings
+ float dot_product = OCTensor_dot(atom1->embedding, atom2->embedding);
+
+ // Compute norms
+ OCTensor *norm1_tensor = OCTensor_newWithSize1d(1);
+ OCTensor *norm2_tensor = OCTensor_newWithSize1d(1);
+
+ OCTensor_norm(norm1_tensor, atom1->embedding, 2, 0, 0); // L2 norm
+ OCTensor_norm(norm2_tensor, atom2->embedding, 2, 0, 0);
+
+ float norm1 = OCTensor_get1d(norm1_tensor, 0);
+ float norm2 = OCTensor_get1d(norm2_tensor, 0);
+
+ float similarity = (norm1 > 0 && norm2 > 0) ? dot_product / (norm1 * norm2) : 0.0;
+ OCTensor_set1d(result, 0, similarity);
+
+ OCTensor_free(norm1_tensor);
+ OCTensor_free(norm2_tensor);
+
+ return result;
+}
+
+OCTensor* OCAtom_tensorProduct(OCAtom *atom1, OCAtom *atom2) {
+ if (!atom1 || !atom2 || !atom1->embedding || !atom2->embedding) return NULL;
+
+ // Create tensor product (outer product) of embeddings
+ long dim1 = OCTensor_size(atom1->embedding, 0);
+ long dim2 = OCTensor_size(atom2->embedding, 0);
+
+ OCTensor *result = OCTensor_newWithSize2d(dim1, dim2);
+
+ for (long i = 0; i < dim1; i++) {
+ for (long j = 0; j < dim2; j++) {
+ float val1 = OCTensor_get1d(atom1->embedding, i);
+ float val2 = OCTensor_get1d(atom2->embedding, j);
+ OCTensor_set2d(result, i, j, val1 * val2);
+ }
+ }
+
+ return result;
+}
+
+void OCAtom_updateAttention(OCAtom *atom, OCTensor *sti_update) {
+ if (!atom || !atom->attention || !sti_update) return;
+
+ // Update Short Term Importance (STI)
+ float current_sti = OCTensor_get1d(atom->attention, 0);
+ float update_val = OCTensor_get1d(sti_update, 0);
+ OCTensor_set1d(atom->attention, 0, current_sti + update_val);
+}
\ No newline at end of file
diff --git a/opencog/atoms/opencog_atoms.h b/opencog/atoms/opencog_atoms.h
new file mode 100644
index 00000000..db796cb3
--- /dev/null
+++ b/opencog/atoms/opencog_atoms.h
@@ -0,0 +1,92 @@
+#ifndef OPENCOG_ATOMS_H
+#define OPENCOG_ATOMS_H
+
+#include "../tensor_wrapper.h"
+
+// Forward declarations
+typedef struct OCAtom OCAtom;
+typedef struct OCAtomSpace OCAtomSpace;
+typedef struct OCTruthValue OCTruthValue;
+
+/* OpenCog Atom Types */
+typedef enum {
+ OC_NODE = 1,
+ OC_LINK,
+ OC_CONCEPT_NODE,
+ OC_PREDICATE_NODE,
+ OC_VARIABLE_NODE,
+ OC_LIST_LINK,
+ OC_AND_LINK,
+ OC_OR_LINK,
+ OC_NOT_LINK,
+ OC_IMPLICATION_LINK,
+ OC_EVALUATION_LINK,
+ OC_EXECUTION_LINK,
+ OC_PATTERN_LINK,
+ OC_BIND_LINK,
+ OC_LAMBDA_LINK
+} OCAtomType;
+
+/* OpenCog Truth Value Structure using Tensors */
+typedef struct OCTruthValue {
+ OCTensor *strength; // Tensor representing confidence/strength
+ OCTensor *confidence; // Tensor representing confidence/count
+ OCTensor *frequency; // Tensor for frequency-based truth values
+ OCTensor *probability; // Tensor for probabilistic reasoning
+} OCTruthValue;
+
+/* OpenCog Atom Structure with Tensor-based Representation */
+typedef struct OCAtom {
+ OCAtomType type;
+ char *name; // Atom name/label
+ OCTensor *embedding; // High-dimensional tensor representation
+ OCTensor *attention; // Attention values (STI, LTI, VLTI)
+ OCTruthValue *tv; // Truth value with tensor components
+ OCAtom **incoming; // Incoming links
+ OCAtom **outgoing; // Outgoing links
+ int incoming_count;
+ int outgoing_count;
+ long atom_id; // Unique identifier
+ int refcount;
+} OCAtom;
+
+/* OpenCog AtomSpace - Container for all atoms */
+typedef struct OCAtomSpace {
+ OCAtom **atoms; // Array of all atoms
+ OCTensor *atom_matrix; // Matrix representation of atom relationships
+ OCTensor *attention_matrix; // Global attention allocation matrix
+ long atom_count;
+ long max_atoms;
+ long next_atom_id;
+} OCAtomSpace;
+
+/* Atom Creation and Management */
+OCAtom* OCAtom_new(OCAtomType type, const char *name);
+OCAtom* OCAtom_newWithEmbedding(OCAtomType type, const char *name, OCTensor *embedding);
+void OCAtom_retain(OCAtom *atom);
+void OCAtom_free(OCAtom *atom);
+void OCAtom_setTruthValue(OCAtom *atom, OCTruthValue *tv);
+void OCAtom_addIncoming(OCAtom *atom, OCAtom *incoming);
+void OCAtom_addOutgoing(OCAtom *atom, OCAtom *outgoing);
+
+/* Truth Value Operations */
+OCTruthValue* OCTruthValue_new(float strength, float confidence);
+OCTruthValue* OCTruthValue_newFromTensor(OCTensor *strength, OCTensor *confidence);
+void OCTruthValue_free(OCTruthValue *tv);
+OCTruthValue* OCTruthValue_merge(OCTruthValue *tv1, OCTruthValue *tv2);
+OCTruthValue* OCTruthValue_revision(OCTruthValue *tv1, OCTruthValue *tv2);
+
+/* AtomSpace Operations */
+OCAtomSpace* OCAtomSpace_new(long max_atoms);
+void OCAtomSpace_free(OCAtomSpace *atomspace);
+long OCAtomSpace_addAtom(OCAtomSpace *atomspace, OCAtom *atom);
+OCAtom* OCAtomSpace_getAtom(OCAtomSpace *atomspace, long atom_id);
+void OCAtomSpace_removeAtom(OCAtomSpace *atomspace, long atom_id);
+OCTensor* OCAtomSpace_getAtomMatrix(OCAtomSpace *atomspace);
+
+/* Pattern Matching and Inference */
+OCTensor* OCAtom_computeSimilarity(OCAtom *atom1, OCAtom *atom2);
+OCTensor* OCAtom_tensorProduct(OCAtom *atom1, OCAtom *atom2);
+void OCAtom_updateAttention(OCAtom *atom, OCTensor *sti_update);
+
+#endif
\ No newline at end of file
diff --git a/opencog/attention/attention_allocation.c b/opencog/attention/attention_allocation.c
new file mode 100644
index 00000000..ca7b5afe
--- /dev/null
+++ b/opencog/attention/attention_allocation.c
@@ -0,0 +1,522 @@
+#include "attention_allocation.h"
+#include
+#include
+#include
+#include
+
+#ifndef OC_DEFAULT_MAX_STI
+#define OC_DEFAULT_MAX_STI 100.0f
+#endif
+#ifndef OC_DEFAULT_MIN_STI
+#define OC_DEFAULT_MIN_STI -100.0f
+#endif
+#ifndef OC_DEFAULT_STI_DECAY
+#define OC_DEFAULT_STI_DECAY 0.01f
+#endif
+#ifndef OC_DEFAULT_LTI_DECAY
+#define OC_DEFAULT_LTI_DECAY 0.001f
+#endif
+#ifndef OC_DEFAULT_SPREAD_RATE
+#define OC_DEFAULT_SPREAD_RATE 0.1f
+#endif
+#ifndef OC_DEFAULT_HEBBIAN_RATE
+#define OC_DEFAULT_HEBBIAN_RATE 0.05f
+#endif
+#ifndef OC_DEFAULT_RENT_RATE
+#define OC_DEFAULT_RENT_RATE 0.02f
+#endif
+#ifndef OC_DEFAULT_NOVELTY_BONUS
+#define OC_DEFAULT_NOVELTY_BONUS 10.0f
+#endif
+#ifndef OC_DEFAULT_FOCUS_SIZE
+#define OC_DEFAULT_FOCUS_SIZE 20
+#endif
+#ifndef OC_DEFAULT_EMBEDDING_DIM
+#define OC_DEFAULT_EMBEDDING_DIM 128
+#endif
+#ifndef OC_DEFAULT_ATTENTION_DIM
+#define OC_DEFAULT_ATTENTION_DIM 3
+#endif
+
+/* Attention Bank Operations */
+OCAttentionBank* OCAttentionBank_new(OCAtomSpace *atomspace) {
+ OCAttentionBank *bank = (OCAttentionBank*)malloc(sizeof(OCAttentionBank));
+ if (!bank) return NULL;
+
+ bank->atomspace = atomspace;
+ bank->max_agents = 50;
+ bank->agents = (OCAttentionAgent**)calloc(bank->max_agents, sizeof(OCAttentionAgent*));
+ bank->agent_count = 0;
+
+ long max_atoms = atomspace ? atomspace->max_atoms : 1000;
+
+ // Initialize attention matrices
+ bank->attention_matrix = OCTensor_newWithSize2d(max_atoms, OC_DEFAULT_ATTENTION_DIM);
+ bank->activity_matrix = OCTensor_newWithSize2d(max_atoms, max_atoms);
+ bank->importance_vector = OCTensor_newWithSize1d(max_atoms);
+ bank->focus_mask = OCTensor_newWithSize1d(max_atoms);
+ bank->attention_history = OCTensor_newWithSize2d(max_atoms, 100); // 100 time steps
+
+ OCTensor_zero(bank->attention_matrix);
+ OCTensor_zero(bank->activity_matrix);
+ OCTensor_zero(bank->importance_vector);
+ OCTensor_zero(bank->focus_mask);
+ OCTensor_zero(bank->attention_history);
+
+ // Neural networks for learned attention
+ bank->attention_network = OCTensor_newWithSize3d(OC_DEFAULT_EMBEDDING_DIM, 64, max_atoms);
+ bank->value_network = OCTensor_newWithSize2d(OC_DEFAULT_EMBEDDING_DIM, 1);
+
+ OCTensor_rand(bank->attention_network, NULL, NULL);
+ OCTensor_rand(bank->value_network, NULL, NULL);
+
+ // Initialize global parameters
+ bank->global_params.max_sti = OC_DEFAULT_MAX_STI;
+ bank->global_params.min_sti = OC_DEFAULT_MIN_STI;
+ bank->global_params.sti_decay_rate = OC_DEFAULT_STI_DECAY;
+ bank->global_params.lti_decay_rate = OC_DEFAULT_LTI_DECAY;
+ bank->global_params.attention_spread_rate = OC_DEFAULT_SPREAD_RATE;
+ bank->global_params.hebbian_learning_rate = OC_DEFAULT_HEBBIAN_RATE;
+ bank->global_params.rent_rate = OC_DEFAULT_RENT_RATE;
+ bank->global_params.novelty_bonus = OC_DEFAULT_NOVELTY_BONUS;
+ bank->global_params.attention_focus_size = OC_DEFAULT_FOCUS_SIZE;
+
+ bank->total_attention = 0;
+ bank->attention_cycles = 0;
+
+ return bank;
+}
+
+void OCAttentionBank_free(OCAttentionBank *bank) {
+ if (!bank) return;
+
+ // Free all agents
+ for (int i = 0; i < bank->agent_count; i++) {
+ if (bank->agents[i]) {
+ OCAttentionAgent_free(bank->agents[i]);
+ }
+ }
+ free(bank->agents);
+
+ OCTensor_free(bank->attention_matrix);
+ OCTensor_free(bank->activity_matrix);
+ OCTensor_free(bank->importance_vector);
+ OCTensor_free(bank->focus_mask);
+ OCTensor_free(bank->attention_history);
+ OCTensor_free(bank->attention_network);
+ OCTensor_free(bank->value_network);
+
+ free(bank);
+}
+
+void OCAttentionBank_addAgent(OCAttentionBank *bank, OCAttentionAgent *agent) {
+ if (!bank || !agent || bank->agent_count >= bank->max_agents) return;
+
+ bank->agents[bank->agent_count] = agent;
+ bank->agent_count++;
+}
+
+void OCAttentionBank_cycle(OCAttentionBank *bank) {
+ if (!bank || !bank->atomspace) return;
+
+ // Run all active attention agents
+ for (int i = 0; i < bank->agent_count; i++) {
+ OCAttentionAgent *agent = bank->agents[i];
+ if (agent && agent->active && agent->process) {
+ // Check if agent should run based on frequency
+ if (bank->attention_cycles % (int)(1.0f / agent->frequency) == 0) {
+ agent->process(agent, bank->atomspace);
+ agent->cycle_count++;
+ }
+ }
+ }
+
+ // Update global attention dynamics
+ OCAttentionBank_spreadAttention(bank);
+ OCAttentionBank_updateImportance(bank);
+ OCAttentionBank_collectRent(bank);
+ OCAttentionBank_updateFocus(bank);
+
+ bank->attention_cycles++;
+}
+
+/* Attention Agent Creation and Management */
+OCAttentionAgent* OCAttentionAgent_new(OCAttentionAgentType type, const char *name) {
+ OCAttentionAgent *agent = (OCAttentionAgent*)malloc(sizeof(OCAttentionAgent));
+ if (!agent) return NULL;
+
+ agent->type = type;
+ agent->name = name ? strdup(name) : NULL;
+
+ // Initialize agent weights
+ agent->agent_weights = OCTensor_newWithSize2d(OC_DEFAULT_EMBEDDING_DIM, OC_DEFAULT_EMBEDDING_DIM);
+ agent->activation_history = OCTensor_newWithSize1d(1000); // Store 1000 activations
+
+ OCTensor_rand(agent->agent_weights, NULL, NULL);
+ OCTensor_zero(agent->activation_history);
+
+ // Set default parameters
+ agent->params.max_sti = OC_DEFAULT_MAX_STI;
+ agent->params.min_sti = OC_DEFAULT_MIN_STI;
+ agent->params.sti_decay_rate = OC_DEFAULT_STI_DECAY;
+ agent->params.lti_decay_rate = OC_DEFAULT_LTI_DECAY;
+ agent->params.attention_spread_rate = OC_DEFAULT_SPREAD_RATE;
+ agent->params.hebbian_learning_rate = OC_DEFAULT_HEBBIAN_RATE;
+ agent->params.rent_rate = OC_DEFAULT_RENT_RATE;
+ agent->params.novelty_bonus = OC_DEFAULT_NOVELTY_BONUS;
+ agent->params.attention_focus_size = OC_DEFAULT_FOCUS_SIZE;
+
+ // Set process function based on type
+ switch (type) {
+ case OC_HEBBIAN_AGENT:
+ agent->process = OCAgent_hebbian;
+ break;
+ case OC_IMPORTANCE_UPDATING_AGENT:
+ agent->process = OCAgent_importanceUpdating;
+ break;
+ case OC_FORGETTING_AGENT:
+ agent->process = OCAgent_forgetting;
+ break;
+ case OC_SPREADING_AGENT:
+ agent->process = OCAgent_spreading;
+ break;
+ case OC_RENT_COLLECTION_AGENT:
+ agent->process = OCAgent_rentCollection;
+ break;
+ case OC_NOVELTY_AGENT:
+ agent->process = OCAgent_novelty;
+ break;
+ default:
+ agent->process = NULL;
+ break;
+ }
+
+ agent->active = 1;
+ agent->frequency = 1.0f; // 1 Hz by default
+ agent->cycle_count = 0;
+
+ return agent;
+}
+
+void OCAttentionAgent_free(OCAttentionAgent *agent) {
+ if (!agent) return;
+
+ if (agent->name) free(agent->name);
+ if (agent->agent_weights) OCTensor_free(agent->agent_weights);
+ if (agent->activation_history) OCTensor_free(agent->activation_history);
+
+ free(agent);
+}
+
+/* Attention Value Operations */
+void OCAtom_setSTI(OCAtom *atom, float sti) {
+ if (!atom || !atom->attention) return;
+ OCTensor_set1d(atom->attention, OC_STI, sti);
+}
+
+void OCAtom_setLTI(OCAtom *atom, float lti) {
+ if (!atom || !atom->attention) return;
+ OCTensor_set1d(atom->attention, OC_LTI, lti);
+}
+
+void OCAtom_setVLTI(OCAtom *atom, float vlti) {
+ if (!atom || !atom->attention) return;
+ OCTensor_set1d(atom->attention, OC_VLTI, vlti);
+}
+
+float OCAtom_getSTI(OCAtom *atom) {
+ if (!atom || !atom->attention) return 0.0f;
+ return OCTensor_get1d(atom->attention, OC_STI);
+}
+
+float OCAtom_getLTI(OCAtom *atom) {
+ if (!atom || !atom->attention) return 0.0f;
+ return OCTensor_get1d(atom->attention, OC_LTI);
+}
+
+float OCAtom_getVLTI(OCAtom *atom) {
+ if (!atom || !atom->attention) return 0.0f;
+ return OCTensor_get1d(atom->attention, OC_VLTI);
+}
+
+void OCAtom_updateAttentionValue(OCAtom *atom, OCAttentionType type, float delta) {
+ if (!atom || !atom->attention) return;
+
+ float current_val = OCTensor_get1d(atom->attention, type);
+ OCTensor_set1d(atom->attention, type, current_val + delta);
+}
+
+/* Attention Spreading and Dynamics */
+void OCAttentionBank_spreadAttention(OCAttentionBank *bank) {
+ if (!bank || !bank->atomspace) return;
+
+ OCTensor *spread_matrix = OCTensor_newWithSize2d(bank->atomspace->max_atoms,
+ bank->atomspace->max_atoms);
+ OCTensor_zero(spread_matrix);
+
+ // Compute attention spreading through atom connections
+ for (long i = 0; i < bank->atomspace->atom_count; i++) {
+ OCAtom *atom = bank->atomspace->atoms[i];
+ if (!atom) continue;
+
+ float sti = OCAtom_getSTI(atom);
+
+ // Spread attention to connected atoms
+ for (int j = 0; j < atom->outgoing_count; j++) {
+ OCAtom *target = atom->outgoing[j];
+ if (target) {
+ // Find target atom index
+ for (long k = 0; k < bank->atomspace->atom_count; k++) {
+ if (bank->atomspace->atoms[k] == target) {
+ float spread_amount = sti * bank->global_params.attention_spread_rate;
+ OCTensor_set2d(spread_matrix, i, k, spread_amount);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Apply spreading updates
+ for (long i = 0; i < bank->atomspace->atom_count; i++) {
+ OCAtom *atom = bank->atomspace->atoms[i];
+ if (!atom) continue;
+
+ float total_incoming = 0.0f;
+ for (long j = 0; j < bank->atomspace->atom_count; j++) {
+ total_incoming += OCTensor_get2d(spread_matrix, j, i);
+ }
+
+ if (total_incoming > 0) {
+ OCAtom_updateAttentionValue(atom, OC_STI, total_incoming);
+ }
+ }
+
+ OCTensor_free(spread_matrix);
+}
+
+void OCAttentionBank_updateImportance(OCAttentionBank *bank) {
+ if (!bank || !bank->atomspace) return;
+
+ // Update importance vector with current STI values
+ for (long i = 0; i < bank->atomspace->atom_count; i++) {
+ OCAtom *atom = bank->atomspace->atoms[i];
+ if (atom) {
+ float sti = OCAtom_getSTI(atom);
+ OCTensor_set1d(bank->importance_vector, i, sti);
+ }
+ }
+}
+
+void OCAttentionBank_collectRent(OCAttentionBank *bank) {
+ if (!bank || !bank->atomspace) return;
+
+ // Collect rent (decay attention) from all atoms
+ for (long i = 0; i < bank->atomspace->atom_count; i++) {
+ OCAtom *atom = bank->atomspace->atoms[i];
+ if (!atom) continue;
+
+ float sti = OCAtom_getSTI(atom);
+ float lti = OCAtom_getLTI(atom);
+
+ // Apply decay
+ float sti_decay = sti * bank->global_params.sti_decay_rate;
+ float lti_decay = lti * bank->global_params.lti_decay_rate;
+
+ OCAtom_setSTI(atom, sti - sti_decay);
+ OCAtom_setLTI(atom, lti - lti_decay);
+
+ // Ensure values stay within bounds
+ if (OCAtom_getSTI(atom) < bank->global_params.min_sti) {
+ OCAtom_setSTI(atom, bank->global_params.min_sti);
+ }
+ if (OCAtom_getSTI(atom) > bank->global_params.max_sti) {
+ OCAtom_setSTI(atom, bank->global_params.max_sti);
+ }
+ }
+}
+
+void OCAttentionBank_updateFocus(OCAttentionBank *bank) {
+ if (!bank || !bank->atomspace) return;
+
+ // Clear current focus
+ OCTensor_zero(bank->focus_mask);
+
+ // Find atoms with highest STI values for focus
+ OCTensor *sti_values = OCTensor_newWithSize1d(bank->atomspace->atom_count);
+ OCTensor *indices = OCTensor_newWithSize1d(bank->atomspace->atom_count);
+
+ for (long i = 0; i < bank->atomspace->atom_count; i++) {
+ OCAtom *atom = bank->atomspace->atoms[i];
+ float sti = atom ? OCAtom_getSTI(atom) : 0.0f;
+ OCTensor_set1d(sti_values, i, sti);
+ OCTensor_set1d(indices, i, (float)i);
+ }
+
+ // Sort by STI (simplified - just mark top atoms)
+ int focus_count = 0;
+ for (long i = 0; i < bank->atomspace->atom_count && focus_count < bank->global_params.attention_focus_size; i++) {
+ OCAtom *atom = bank->atomspace->atoms[i];
+ if (atom && OCAtom_getSTI(atom) > 0) {
+ OCTensor_set1d(bank->focus_mask, i, 1.0f);
+ focus_count++;
+ }
+ }
+
+ OCTensor_free(sti_values);
+ OCTensor_free(indices);
+}
+
+/* Built-in Attention Agents */
+void OCAgent_hebbian(OCAttentionAgent *agent, OCAtomSpace *atomspace) {
+ if (!agent || !atomspace) return;
+
+ // Strengthen connections between co-active atoms
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ OCAtom *atom1 = atomspace->atoms[i];
+ if (!atom1 || OCAtom_getSTI(atom1) <= 0) continue;
+
+ for (long j = i + 1; j < atomspace->atom_count; j++) {
+ OCAtom *atom2 = atomspace->atoms[j];
+ if (!atom2 || OCAtom_getSTI(atom2) <= 0) continue;
+
+ // If both atoms have positive STI, strengthen their connection
+ float sti1 = OCAtom_getSTI(atom1);
+ float sti2 = OCAtom_getSTI(atom2);
+
+ float hebbian_strength = sti1 * sti2 * agent->params.hebbian_learning_rate;
+
+ // Update embeddings to be more similar (simplified hebbian learning)
+ if (atom1->embedding && atom2->embedding) {
+ OCTensor *diff = OCTensor_newWithTensor(atom1->embedding);
+ OCTensor_csub(diff, diff, 1.0, atom2->embedding);
+ OCTensor_mul(diff, diff, hebbian_strength);
+
+ OCTensor_csub(atom1->embedding, atom1->embedding, 0.5, diff);
+ OCTensor_cadd(atom2->embedding, atom2->embedding, 0.5, diff);
+
+ OCTensor_free(diff);
+ }
+ }
+ }
+}
+
+void OCAgent_importanceUpdating(OCAttentionAgent *agent, OCAtomSpace *atomspace) {
+ if (!agent || !atomspace) return;
+
+ // Update importance based on usage and connections
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ OCAtom *atom = atomspace->atoms[i];
+ if (!atom) continue;
+
+ // Increase importance for atoms with many connections
+ float connection_bonus = (atom->incoming_count + atom->outgoing_count) * 0.1f;
+
+ // Increase importance for atoms with high truth value confidence
+ float tv_bonus = 0.0f;
+ if (atom->tv && atom->tv->confidence) {
+ tv_bonus = OCTensor_get1d(atom->tv->confidence, 0) * 5.0f;
+ }
+
+ float total_bonus = connection_bonus + tv_bonus;
+ OCAtom_updateAttentionValue(atom, OC_STI, total_bonus);
+ }
+}
+
+void OCAgent_forgetting(OCAttentionAgent *agent, OCAtomSpace *atomspace) {
+ if (!agent || !atomspace) return;
+
+ // Apply stronger forgetting to atoms with very low attention
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ OCAtom *atom = atomspace->atoms[i];
+ if (!atom) continue;
+
+ float sti = OCAtom_getSTI(atom);
+
+ // Apply exponential decay for very low attention atoms
+ if (sti < agent->params.min_sti * 0.5f) {
+ float decay_factor = 1.0f + agent->params.sti_decay_rate * 2.0f;
+ OCAtom_setSTI(atom, sti / decay_factor);
+ }
+ }
+}
+
+void OCAgent_spreading(OCAttentionAgent *agent, OCAtomSpace *atomspace) {
+ if (!agent || !atomspace) return;
+
+ // This is handled by OCAttentionBank_spreadAttention
+ // Agent-specific spreading could be implemented here
+}
+
+void OCAgent_rentCollection(OCAttentionAgent *agent, OCAtomSpace *atomspace) {
+ if (!agent || !atomspace) return;
+
+ // This is handled by OCAttentionBank_collectRent
+ // Agent-specific rent collection could be implemented here
+}
+
+void OCAgent_novelty(OCAttentionAgent *agent, OCAtomSpace *atomspace) {
+ if (!agent || !atomspace) return;
+
+ // Detect and reward novel patterns
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ OCAtom *atom = atomspace->atoms[i];
+ if (!atom || !atom->embedding) continue;
+
+ // Simple novelty detection: compare with all other atoms
+ float min_similarity = 1.0f;
+
+ for (long j = 0; j < atomspace->atom_count; j++) {
+ if (i == j) continue;
+
+ OCAtom *other = atomspace->atoms[j];
+ if (!other || !other->embedding) continue;
+
+ // Compute similarity
+ float similarity = OCTensor_dot(atom->embedding, other->embedding);
+ if (similarity < min_similarity) {
+ min_similarity = similarity;
+ }
+ }
+
+ // Reward novelty (low similarity means high novelty)
+ float novelty_score = 1.0f - min_similarity;
+ if (novelty_score > 0.5f) {
+ float novelty_bonus = novelty_score * agent->params.novelty_bonus;
+ OCAtom_updateAttentionValue(atom, OC_STI, novelty_bonus);
+ }
+ }
+}
+
+float OCAttentionBank_computeNovelty(OCAttentionBank *bank, OCAtom *atom) {
+ if (!bank || !atom || !atom->embedding) return 0.0f;
+
+ float total_similarity = 0.0f;
+ int comparison_count = 0;
+
+ for (long i = 0; i < bank->atomspace->atom_count; i++) {
+ OCAtom *other = bank->atomspace->atoms[i];
+ if (other == atom || !other || !other->embedding) continue;
+
+ float similarity = OCTensor_dot(atom->embedding, other->embedding);
+ total_similarity += similarity;
+ comparison_count++;
+ }
+
+ float avg_similarity = (comparison_count > 0) ? total_similarity / comparison_count : 0.0f;
+ return 1.0f - avg_similarity; // Novelty is inverse of average similarity
+}
+
+OCTensor* OCAttentionBank_getAttentionDistribution(OCAttentionBank *bank) {
+ if (!bank || !bank->atomspace) return NULL;
+
+ OCTensor *distribution = OCTensor_newWithSize1d(bank->atomspace->atom_count);
+
+ for (long i = 0; i < bank->atomspace->atom_count; i++) {
+ OCAtom *atom = bank->atomspace->atoms[i];
+ float sti = atom ? OCAtom_getSTI(atom) : 0.0f;
+ OCTensor_set1d(distribution, i, sti);
+ }
+
+ return distribution;
+}
\ No newline at end of file
diff --git a/opencog/attention/attention_allocation.h b/opencog/attention/attention_allocation.h
new file mode 100644
index 00000000..95a0e7b0
--- /dev/null
+++ b/opencog/attention/attention_allocation.h
@@ -0,0 +1,146 @@
+#ifndef OPENCOG_ATTENTION_ALLOCATION_H
+#define OPENCOG_ATTENTION_ALLOCATION_H
+
+#include "../atoms/opencog_atoms.h"
+
+/* Forward declarations */
+typedef struct OCAttentionBank OCAttentionBank;
+typedef struct OCAttentionAgent OCAttentionAgent;
+typedef struct OCAttentionParams OCAttentionParams;
+
+/* Attention Value Types */
+typedef enum {
+ OC_STI = 0, // Short Term Importance
+ OC_LTI = 1, // Long Term Importance
+ OC_VLTI = 2 // Very Long Term Importance
+} OCAttentionType;
+
+/* Attention Agent Types */
+typedef enum {
+ OC_HEBBIAN_AGENT, // Strengthens frequently co-activated atoms
+ OC_IMPORTANCE_UPDATING_AGENT, // Updates STI based on activity
+ OC_FORGETTING_AGENT, // Decreases attention over time
+ OC_SPREADING_AGENT, // Spreads attention through links
+ OC_RENT_COLLECTION_AGENT, // Collects rent from atoms
+ OC_NOVELTY_AGENT // Detects and rewards novel patterns
+} OCAttentionAgentType;
+
+/* Attention Parameters */
+typedef struct OCAttentionParams {
+ float max_sti; // Maximum short-term importance
+ float min_sti; // Minimum short-term importance
+ float sti_decay_rate; // Rate of STI decay over time
+ float lti_decay_rate; // Rate of LTI decay over time
+ float attention_spread_rate; // Rate of attention spreading
+ float hebbian_learning_rate; // Hebbian learning rate
+ float rent_rate; // Attention rent collection rate
+ float novelty_bonus; // Bonus for novel patterns
+ int attention_focus_size; // Size of attentional focus
+} OCAttentionParams;
+
+/* Attention Agent */
+typedef struct OCAttentionAgent {
+ OCAttentionAgentType type;
+ char *name;
+ OCTensor *agent_weights; // Neural weights for attention computation
+ OCTensor *activation_history; // History of agent activations
+ OCAttentionParams params; // Agent-specific parameters
+
+ // Agent function pointer
+ void (*process)(struct OCAttentionAgent *agent, OCAtomSpace *atomspace);
+
+ int active; // Whether agent is currently active
+ float frequency; // How often agent runs (cycles per second)
+ int cycle_count; // Number of cycles agent has run
+} OCAttentionAgent;
+
+/* Attention Bank - Central attention allocation system */
+typedef struct OCAttentionBank {
+ OCAtomSpace *atomspace;
+ OCAttentionAgent **agents; // Array of attention agents
+ int agent_count;
+ int max_agents;
+
+ OCTensor *attention_matrix; // Global attention allocation matrix
+ OCTensor *activity_matrix; // Atom co-activation matrix
+ OCTensor *importance_vector; // Current importance values
+ OCTensor *focus_mask; // Mask for attentional focus
+
+ OCAttentionParams global_params; // Global attention parameters
+
+ // Statistics and monitoring
+ OCTensor *attention_history; // History of attention allocations
+ long total_attention; // Total attention in the system
+ long attention_cycles; // Number of attention cycles run
+
+ // Neural components for learned attention
+ OCTensor *attention_network; // Neural network for attention prediction
+ OCTensor *value_network; // Value network for importance estimation
+} OCAttentionBank;
+
+/* Attention Bank Operations */
+OCAttentionBank* OCAttentionBank_new(OCAtomSpace *atomspace);
+void OCAttentionBank_free(OCAttentionBank *bank);
+void OCAttentionBank_addAgent(OCAttentionBank *bank, OCAttentionAgent *agent);
+void OCAttentionBank_removeAgent(OCAttentionBank *bank, const char *agent_name);
+void OCAttentionBank_cycle(OCAttentionBank *bank);
+
+/* Attention Agent Creation and Management */
+OCAttentionAgent* OCAttentionAgent_new(OCAttentionAgentType type, const char *name);
+void OCAttentionAgent_free(OCAttentionAgent *agent);
+void OCAttentionAgent_setParameters(OCAttentionAgent *agent, OCAttentionParams *params);
+void OCAttentionAgent_activate(OCAttentionAgent *agent, OCAtomSpace *atomspace);
+
+/* Attention Value Operations */
+void OCAtom_setSTI(OCAtom *atom, float sti);
+void OCAtom_setLTI(OCAtom *atom, float lti);
+void OCAtom_setVLTI(OCAtom *atom, float vlti);
+float OCAtom_getSTI(OCAtom *atom);
+float OCAtom_getLTI(OCAtom *atom);
+float OCAtom_getVLTI(OCAtom *atom);
+void OCAtom_updateAttentionValue(OCAtom *atom, OCAttentionType type, float delta);
+
+/* Attention Spreading and Dynamics */
+void OCAttentionBank_spreadAttention(OCAttentionBank *bank);
+void OCAttentionBank_updateImportance(OCAttentionBank *bank);
+void OCAttentionBank_collectRent(OCAttentionBank *bank);
+void OCAttentionBank_updateFocus(OCAttentionBank *bank);
+
+/* Hebbian Learning */
+void OCAttentionBank_hebbianUpdate(OCAttentionBank *bank, OCAtom **co_active_atoms, int count);
+OCTensor* OCAttentionBank_computeCoActivation(OCAttentionBank *bank, OCAtom *atom1, OCAtom *atom2);
+
+/* Novelty Detection */
+float OCAttentionBank_computeNovelty(OCAttentionBank *bank, OCAtom *atom);
+void OCAttentionBank_rewardNovelty(OCAttentionBank *bank, OCAtom *atom, float novelty_score);
+
+/* Built-in Attention Agents */
+void OCAgent_hebbian(OCAttentionAgent *agent, OCAtomSpace *atomspace);
+void OCAgent_importanceUpdating(OCAttentionAgent *agent, OCAtomSpace *atomspace);
+void OCAgent_forgetting(OCAttentionAgent *agent, OCAtomSpace *atomspace);
+void OCAgent_spreading(OCAttentionAgent *agent, OCAtomSpace *atomspace);
+void OCAgent_rentCollection(OCAttentionAgent *agent, OCAtomSpace *atomspace);
+void OCAgent_novelty(OCAttentionAgent *agent, OCAtomSpace *atomspace);
+
+/* Attention Allocation Algorithms */
+OCTensor* OCAttention_computeCompetition(OCTensor *importance_vector, float competition_strength);
+OCTensor* OCAttention_computeFocus(OCTensor *attention_values, int focus_size);
+OCTensor* OCAttention_computeSpread(OCTensor *source_attention, OCTensor *connectivity_matrix);
+
+/* Economic Attention Model */
+void OCAttentionBank_marketUpdate(OCAttentionBank *bank);
+float OCAttentionBank_computeUtility(OCAttentionBank *bank, OCAtom *atom);
+void OCAttentionBank_allocateResources(OCAttentionBank *bank);
+
+/* Neural Attention Learning */
+void OCAttentionBank_trainAttentionNetwork(OCAttentionBank *bank,
+ OCTensor *input_features,
+ OCTensor *target_attention);
+OCTensor* OCAttentionBank_predictAttention(OCAttentionBank *bank, OCTensor *atom_features);
+
+/* Attention Statistics and Analysis */
+OCTensor* OCAttentionBank_getAttentionDistribution(OCAttentionBank *bank);
+float OCAttentionBank_getAttentionEntropy(OCAttentionBank *bank);
+OCTensor* OCAttentionBank_getTopAttention(OCAttentionBank *bank, int top_k);
+
+#endif
\ No newline at end of file
diff --git a/opencog/example_opencog_demo.c b/opencog/example_opencog_demo.c
new file mode 100644
index 00000000..db9ac5e6
--- /dev/null
+++ b/opencog/example_opencog_demo.c
@@ -0,0 +1,293 @@
+/*
+ * OpenCog Multi-Dimensional Tensor Inference Engine Demo
+ *
+ * This example demonstrates the key features of the OpenCog tensor-based
+ * cognitive architecture including knowledge representation, inference,
+ * attention allocation, and learning.
+ */
+
+#include "opencog.h"
+#include
+#include
+
+void print_separator(const char *title) {
+ printf("\n" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "="
+ "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "\n");
+ printf("%s\n", title);
+ printf("=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "="
+ "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "=" "\n");
+}
+
+void demo_basic_knowledge() {
+ print_separator("Demo 1: Basic Knowledge Representation");
+
+ // Create OpenCog system
+ printf("Creating OpenCog system...\n");
+ OpenCog *opencog = OpenCog_new(NULL);
+
+ // Add basic concepts
+ printf("\nAdding basic concepts:\n");
+ OCAtom *socrates = OpenCog_addConcept(opencog, "Socrates", 0.95f, 0.9f);
+ OCAtom *plato = OpenCog_addConcept(opencog, "Plato", 0.93f, 0.88f);
+ OCAtom *human = OpenCog_addConcept(opencog, "human", 0.98f, 0.95f);
+ OCAtom *philosopher = OpenCog_addConcept(opencog, "philosopher", 0.92f, 0.85f);
+ OCAtom *mortal = OpenCog_addConcept(opencog, "mortal", 0.99f, 0.98f);
+
+ printf("- %s (strength=%.2f, confidence=%.2f)\n", socrates->name,
+ OCTensor_get1d(socrates->tv->strength, 0),
+ OCTensor_get1d(socrates->tv->confidence, 0));
+ printf("- %s (strength=%.2f, confidence=%.2f)\n", plato->name,
+ OCTensor_get1d(plato->tv->strength, 0),
+ OCTensor_get1d(plato->tv->confidence, 0));
+
+ // Create relationships
+ printf("\nCreating relationships:\n");
+ OpenCog_associateAtoms(opencog, socrates, human, 0.9f);
+ OpenCog_associateAtoms(opencog, socrates, philosopher, 0.95f);
+ OpenCog_associateAtoms(opencog, plato, human, 0.88f);
+ OpenCog_associateAtoms(opencog, plato, philosopher, 0.92f);
+ OpenCog_associateAtoms(opencog, human, mortal, 0.98f);
+
+ printf("- Socrates is human (strength=0.90)\n");
+ printf("- Socrates is philosopher (strength=0.95)\n");
+ printf("- Plato is human (strength=0.88)\n");
+ printf("- Plato is philosopher (strength=0.92)\n");
+ printf("- Humans are mortal (strength=0.98)\n");
+
+ // Display current knowledge base
+ printf("\nCurrent AtomSpace:\n");
+ printf("Total atoms: %ld\n", opencog->atomspace->atom_count);
+
+ OpenCog_free(opencog);
+}
+
+void demo_attention_system() {
+ print_separator("Demo 2: Attention Allocation System");
+
+ // Create system with attention enabled
+ OCConfig *config = OpenCog_getDefaultConfig();
+ config->enable_attention = 1;
+ config->enable_hebbian_learning = 1;
+ config->attention_threshold = 5.0f;
+
+ OpenCog *opencog = OpenCog_new(config);
+ free(config);
+
+ printf("Created OpenCog system with attention enabled\n");
+
+ // Add concepts
+ OCAtom *red = OpenCog_addConcept(opencog, "red", 0.8f, 0.7f);
+ OCAtom *apple = OpenCog_addConcept(opencog, "apple", 0.9f, 0.8f);
+ OCAtom *fire = OpenCog_addConcept(opencog, "fire", 0.85f, 0.75f);
+ OCAtom *color = OpenCog_addConcept(opencog, "color", 0.95f, 0.9f);
+
+ printf("\nInitial attention values:\n");
+ printf("- red: STI=%.2f\n", OCAtom_getSTI(red));
+ printf("- apple: STI=%.2f\n", OCAtom_getSTI(apple));
+ printf("- fire: STI=%.2f\n", OCAtom_getSTI(fire));
+ printf("- color: STI=%.2f\n", OCAtom_getSTI(color));
+
+ // Create associations
+ OpenCog_associateAtoms(opencog, red, apple, 0.8f);
+ OpenCog_associateAtoms(opencog, red, fire, 0.7f);
+ OpenCog_associateAtoms(opencog, red, color, 0.9f);
+
+ // Boost attention to activate learning
+ printf("\nBoosting attention to 'red' and 'apple'...\n");
+ OpenCog_boostAttention(opencog, red, 25.0f);
+ OpenCog_boostAttention(opencog, apple, 20.0f);
+
+ printf("After attention boost:\n");
+ printf("- red: STI=%.2f\n", OCAtom_getSTI(red));
+ printf("- apple: STI=%.2f\n", OCAtom_getSTI(apple));
+
+ // Run attention cycles
+ printf("\nRunning attention cycles...\n");
+ for (int i = 0; i < 5; i++) {
+ OpenCog_stepAttention(opencog);
+ printf("Cycle %d: red STI=%.2f, apple STI=%.2f, fire STI=%.2f\n",
+ i+1, OCAtom_getSTI(red), OCAtom_getSTI(apple), OCAtom_getSTI(fire));
+ }
+
+ // Show attentional focus
+ int focus_count;
+ OCAtom **focus_atoms = OpenCog_getAttentionalFocus(opencog, &focus_count);
+ printf("\nAttentional focus (%d atoms):\n", focus_count);
+ for (int i = 0; i < focus_count; i++) {
+ printf("- %s (STI=%.2f)\n", focus_atoms[i]->name, OCAtom_getSTI(focus_atoms[i]));
+ }
+
+ if (focus_atoms) free(focus_atoms);
+ OpenCog_free(opencog);
+}
+
+void demo_similarity_inference() {
+ print_separator("Demo 3: Similarity and Inference");
+
+ OpenCog *opencog = OpenCog_new(NULL);
+
+ // Create animal concepts
+ OCAtom *cat = OpenCog_addConcept(opencog, "cat", 0.9f, 0.8f);
+ OCAtom *dog = OpenCog_addConcept(opencog, "dog", 0.88f, 0.82f);
+ OCAtom *wolf = OpenCog_addConcept(opencog, "wolf", 0.85f, 0.75f);
+ OCAtom *tiger = OpenCog_addConcept(opencog, "tiger", 0.87f, 0.78f);
+ OCAtom *tree = OpenCog_addConcept(opencog, "tree", 0.8f, 0.7f);
+
+ printf("Testing similarity computation...\n");
+
+ // Modify embeddings to create meaningful similarities
+ if (cat->embedding && dog->embedding && wolf->embedding) {
+ // Make cat and dog more similar (both pets)
+ for (int i = 0; i < 20; i++) {
+ float pet_feature = 0.7f + i * 0.01f;
+ OCTensor_set1d(cat->embedding, i, pet_feature + 0.1f);
+ OCTensor_set1d(dog->embedding, i, pet_feature);
+ }
+
+ // Make dog and wolf similar (both canines)
+ for (int i = 20; i < 40; i++) {
+ float canine_feature = 0.6f + i * 0.005f;
+ OCTensor_set1d(dog->embedding, i, canine_feature);
+ OCTensor_set1d(wolf->embedding, i, canine_feature + 0.05f);
+ }
+
+ // Make cat and tiger similar (both felines)
+ for (int i = 40; i < 60; i++) {
+ float feline_feature = 0.8f + i * 0.003f;
+ OCTensor_set1d(cat->embedding, i, feline_feature);
+ OCTensor_set1d(tiger->embedding, i, feline_feature - 0.02f);
+ }
+
+ // Make tree very different
+ for (int i = 0; i < 60; i++) {
+ OCTensor_set1d(tree->embedding, i, -0.5f + i * 0.01f);
+ }
+ }
+
+ // Compute and display similarities
+ printf("\nSimilarity matrix:\n");
+ OCAtom *animals[] = {cat, dog, wolf, tiger, tree};
+ const char *names[] = {"cat", "dog", "wolf", "tiger", "tree"};
+ int n_animals = 5;
+
+ printf(" ");
+ for (int j = 0; j < n_animals; j++) {
+ printf("%8s", names[j]);
+ }
+ printf("\n");
+
+ for (int i = 0; i < n_animals; i++) {
+ printf("%8s", names[i]);
+ for (int j = 0; j < n_animals; j++) {
+ if (i == j) {
+ printf("%8.3f", 1.0f);
+ } else {
+ float sim = OpenCog_similarity(opencog, animals[i], animals[j]);
+ printf("%8.3f", sim);
+ }
+ }
+ printf("\n");
+ }
+
+ // Run inference
+ printf("\nRunning inference on animal knowledge...\n");
+ long initial_atoms = opencog->atomspace->atom_count;
+
+ OpenCog_forwardChain(opencog, 3);
+
+ long final_atoms = opencog->atomspace->atom_count;
+ printf("Atoms before inference: %ld\n", initial_atoms);
+ printf("Atoms after inference: %ld\n", final_atoms);
+ printf("New atoms inferred: %ld\n", final_atoms - initial_atoms);
+
+ OpenCog_free(opencog);
+}
+
+void demo_system_monitoring() {
+ print_separator("Demo 4: System Monitoring and Statistics");
+
+ OCConfig *config = OpenCog_getDefaultConfig();
+ config->enable_attention = 1;
+
+ OpenCog *opencog = OpenCog_new(config);
+ free(config);
+
+ // Build a small knowledge base
+ printf("Building knowledge base...\n");
+ OCAtom *concepts[10];
+ const char *concept_names[] = {
+ "cat", "dog", "animal", "pet", "mammal",
+ "red", "blue", "color", "apple", "fruit"
+ };
+
+ for (int i = 0; i < 10; i++) {
+ float strength = 0.8f + (i * 0.02f);
+ float confidence = 0.7f + (i * 0.02f);
+ concepts[i] = OpenCog_addConcept(opencog, concept_names[i], strength, confidence);
+ }
+
+ // Create some associations
+ OpenCog_associateAtoms(opencog, concepts[0], concepts[2], 0.9f); // cat -> animal
+ OpenCog_associateAtoms(opencog, concepts[1], concepts[2], 0.85f); // dog -> animal
+ OpenCog_associateAtoms(opencog, concepts[0], concepts[3], 0.8f); // cat -> pet
+ OpenCog_associateAtoms(opencog, concepts[1], concepts[3], 0.9f); // dog -> pet
+ OpenCog_associateAtoms(opencog, concepts[8], concepts[9], 0.95f); // apple -> fruit
+ OpenCog_associateAtoms(opencog, concepts[8], concepts[5], 0.7f); // apple -> red
+
+ // Run some operations
+ OpenCog_forwardChain(opencog, 2);
+
+ for (int i = 0; i < 3; i++) {
+ OpenCog_stepAttention(opencog);
+ }
+
+ // Display system statistics
+ printf("\nSystem Statistics:\n");
+ char stats_buffer[1000];
+ OpenCog_getStats(opencog, stats_buffer, sizeof(stats_buffer));
+ printf("%s\n", stats_buffer);
+
+ // Show version information
+ printf("OpenCog Version: %s\n", OpenCog_getVersion());
+
+ // Display embedding matrix info
+ OCTensor *embeddings = OpenCog_getAtomEmbeddings(opencog);
+ if (embeddings) {
+ printf("Embedding matrix size: %ldx%ld\n",
+ OCTensor_size(embeddings, 0),
+ OCTensor_size(embeddings, 1));
+ OCTensor_free(embeddings);
+ }
+
+ OpenCog_free(opencog);
+}
+
+int main() {
+ printf("OpenCog Multi-Dimensional Tensor Inference Engine\n");
+ printf("Demonstration Program\n\n");
+ printf("This demo showcases the key features of the OpenCog tensor-based\n");
+ printf("cognitive architecture including knowledge representation, attention\n");
+ printf("allocation, similarity computation, and inference capabilities.\n");
+
+ // Run demonstrations
+ demo_basic_knowledge();
+ demo_attention_system();
+ demo_similarity_inference();
+ demo_system_monitoring();
+
+ print_separator("Demo Complete");
+ printf("OpenCog tensor inference engine demonstration finished successfully!\n\n");
+ printf("Key features demonstrated:\n");
+ printf("✓ Knowledge representation with tensor embeddings\n");
+ printf("✓ Truth value computations using tensors\n");
+ printf("✓ Attention allocation with neural dynamics\n");
+ printf("✓ Similarity computation using tensor operations\n");
+ printf("✓ Forward chaining inference\n");
+ printf("✓ Hebbian learning and association strengthening\n");
+ printf("✓ System monitoring and statistics\n\n");
+ printf("The OpenCog tensor inference engine provides a powerful foundation\n");
+ printf("for building intelligent systems that combine symbolic reasoning\n");
+ printf("with neural computation using multi-dimensional tensors.\n");
+
+ return 0;
+}
\ No newline at end of file
diff --git a/opencog/inference/inference_engine.c b/opencog/inference/inference_engine.c
new file mode 100644
index 00000000..379cbae4
--- /dev/null
+++ b/opencog/inference/inference_engine.c
@@ -0,0 +1,493 @@
+#include "inference_engine.h"
+#include
+#include
+#include
+#include
+
+#ifndef OC_MAX_INFERENCE_STEPS
+#define OC_MAX_INFERENCE_STEPS 100
+#endif
+#ifndef OC_DEFAULT_LEARNING_RATE
+#define OC_DEFAULT_LEARNING_RATE 0.01
+#endif
+#ifndef OC_DEFAULT_CONFIDENCE_THRESHOLD
+#define OC_DEFAULT_CONFIDENCE_THRESHOLD 0.5
+#endif
+#ifndef OC_DEFAULT_EMBEDDING_DIM
+#define OC_DEFAULT_EMBEDDING_DIM 128
+#endif
+
+/* Inference Engine Operations */
+OCInferenceEngine* OCInferenceEngine_new(OCAtomSpace *atomspace) {
+ OCInferenceEngine *engine = (OCInferenceEngine*)malloc(sizeof(OCInferenceEngine));
+ if (!engine) return NULL;
+
+ engine->atomspace = atomspace;
+ engine->max_rules = 100;
+ engine->rules = (OCInferenceRule**)calloc(engine->max_rules, sizeof(OCInferenceRule*));
+ engine->rule_count = 0;
+
+ // Initialize inference matrix (atoms x atoms)
+ long max_atoms = atomspace ? atomspace->max_atoms : 1000;
+ engine->inference_matrix = OCTensor_newWithSize2d(max_atoms, max_atoms);
+ OCTensor_zero(engine->inference_matrix);
+
+ // Rule activation tensor
+ engine->rule_activations = OCTensor_newWithSize1d(engine->max_rules);
+ OCTensor_zero(engine->rule_activations);
+
+ // Neural network components
+ engine->embedding_weights = OCTensor_newWithSize2d(OC_DEFAULT_EMBEDDING_DIM, OC_DEFAULT_EMBEDDING_DIM);
+ engine->attention_weights = OCTensor_newWithSize2d(OC_DEFAULT_ATTENTION_DIM, OC_DEFAULT_ATTENTION_DIM);
+ engine->inference_weights = OCTensor_newWithSize2d(max_atoms, max_atoms);
+
+ // Initialize weights randomly (simplified initialization)
+ OCTensor_rand(engine->embedding_weights, NULL, NULL);
+ OCTensor_rand(engine->attention_weights, NULL, NULL);
+ OCTensor_rand(engine->inference_weights, NULL, NULL);
+
+ // Scale weights to [-0.1, 0.1]
+ OCTensor_mul(engine->embedding_weights, engine->embedding_weights, 0.2);
+ OCTensor_sub(engine->embedding_weights, engine->embedding_weights, 0.1);
+
+ engine->learning_rate = OC_DEFAULT_LEARNING_RATE;
+ engine->max_inference_steps = OC_MAX_INFERENCE_STEPS;
+ engine->confidence_threshold = OC_DEFAULT_CONFIDENCE_THRESHOLD;
+
+ return engine;
+}
+
+void OCInferenceEngine_free(OCInferenceEngine *engine) {
+ if (!engine) return;
+
+ // Free all rules
+ for (int i = 0; i < engine->rule_count; i++) {
+ if (engine->rules[i]) {
+ OCInferenceRule_free(engine->rules[i]);
+ }
+ }
+ free(engine->rules);
+
+ OCTensor_free(engine->inference_matrix);
+ OCTensor_free(engine->rule_activations);
+ OCTensor_free(engine->embedding_weights);
+ OCTensor_free(engine->attention_weights);
+ OCTensor_free(engine->inference_weights);
+
+ free(engine);
+}
+
+void OCInferenceEngine_addRule(OCInferenceEngine *engine, OCInferenceRule *rule) {
+ if (!engine || !rule || engine->rule_count >= engine->max_rules) return;
+
+ engine->rules[engine->rule_count] = rule;
+ engine->rule_count++;
+}
+
+void OCInferenceEngine_removeRule(OCInferenceEngine *engine, const char *rule_name) {
+ if (!engine || !rule_name) return;
+
+ for (int i = 0; i < engine->rule_count; i++) {
+ if (engine->rules[i] && engine->rules[i]->name &&
+ strcmp(engine->rules[i]->name, rule_name) == 0) {
+ OCInferenceRule_free(engine->rules[i]);
+
+ // Shift remaining rules
+ for (int j = i; j < engine->rule_count - 1; j++) {
+ engine->rules[j] = engine->rules[j + 1];
+ }
+ engine->rule_count--;
+ break;
+ }
+ }
+}
+
+/* Pattern Matching */
+OCPattern* OCPattern_new(OCAtom **pattern_atoms, int count) {
+ OCPattern *pattern = (OCPattern*)malloc(sizeof(OCPattern));
+ if (!pattern) return NULL;
+
+ pattern->pattern_atoms = (OCAtom**)malloc(sizeof(OCAtom*) * count);
+ pattern->pattern_count = count;
+
+ // Copy pattern atoms
+ for (int i = 0; i < count; i++) {
+ pattern->pattern_atoms[i] = pattern_atoms[i];
+ OCAtom_retain(pattern_atoms[i]);
+ }
+
+ // Create pattern tensor (average of all atom embeddings)
+ pattern->pattern_tensor = OCTensor_newWithSize1d(OC_DEFAULT_EMBEDDING_DIM);
+ OCTensor_zero(pattern->pattern_tensor);
+
+ for (int i = 0; i < count; i++) {
+ if (pattern_atoms[i]->embedding) {
+ OCTensor_cadd(pattern->pattern_tensor, pattern->pattern_tensor,
+ 1.0 / count, pattern_atoms[i]->embedding);
+ }
+ }
+
+ pattern->required_types = NULL;
+ pattern->type_count = 0;
+
+ return pattern;
+}
+
+void OCPattern_free(OCPattern *pattern) {
+ if (!pattern) return;
+
+ for (int i = 0; i < pattern->pattern_count; i++) {
+ OCAtom_free(pattern->pattern_atoms[i]);
+ }
+ free(pattern->pattern_atoms);
+
+ if (pattern->pattern_tensor) OCTensor_free(pattern->pattern_tensor);
+ if (pattern->required_types) free(pattern->required_types);
+
+ free(pattern);
+}
+
+OCTensor* OCPattern_match(OCPattern *pattern, OCAtomSpace *atomspace) {
+ if (!pattern || !atomspace) return NULL;
+
+ // Create similarity tensor for all atoms in atomspace
+ OCTensor *similarity_scores = OCTensor_newWithSize1d(atomspace->atom_count);
+ OCTensor_zero(similarity_scores);
+
+ for (long i = 0; i < atomspace->atom_count; i++) {
+ OCAtom *atom = atomspace->atoms[i];
+ if (atom && atom->embedding) {
+ // Compute similarity with pattern
+ float similarity = OCTensor_dot(pattern->pattern_tensor, atom->embedding);
+ OCTensor_set1d(similarity_scores, i, similarity);
+ }
+ }
+
+ return similarity_scores;
+}
+
+/* Query Processing */
+OCQuery* OCQuery_new(OCPattern *pattern, OCAtom **variables, int var_count) {
+ OCQuery *query = (OCQuery*)malloc(sizeof(OCQuery));
+ if (!query) return NULL;
+
+ query->pattern = pattern;
+ query->variables = (OCAtom**)malloc(sizeof(OCAtom*) * var_count);
+ query->variable_count = var_count;
+
+ for (int i = 0; i < var_count; i++) {
+ query->variables[i] = variables[i];
+ OCAtom_retain(variables[i]);
+ }
+
+ query->constraint_tensor = OCTensor_newWithSize1d(var_count);
+ OCTensor_ones(query->constraint_tensor, NULL);
+
+ query->min_confidence = OC_DEFAULT_CONFIDENCE_THRESHOLD;
+
+ return query;
+}
+
+void OCQuery_free(OCQuery *query) {
+ if (!query) return;
+
+ for (int i = 0; i < query->variable_count; i++) {
+ OCAtom_free(query->variables[i]);
+ }
+ free(query->variables);
+
+ if (query->constraint_tensor) OCTensor_free(query->constraint_tensor);
+
+ free(query);
+}
+
+/* Inference Rule Creation */
+OCInferenceRule* OCInferenceRule_new(OCInferenceRuleType type, const char *name) {
+ OCInferenceRule *rule = (OCInferenceRule*)malloc(sizeof(OCInferenceRule));
+ if (!rule) return NULL;
+
+ rule->type = type;
+ rule->name = name ? strdup(name) : NULL;
+ rule->premise_pattern = NULL;
+ rule->conclusion_pattern = NULL;
+
+ // Create rule weights tensor
+ rule->rule_weights = OCTensor_newWithSize2d(OC_DEFAULT_EMBEDDING_DIM, OC_DEFAULT_EMBEDDING_DIM);
+ OCTensor_rand(rule->rule_weights, NULL, NULL);
+
+ // Set default functions based on rule type
+ switch (type) {
+ case OC_DEDUCTION_RULE:
+ rule->tv_function = OCInferenceRule_deduction;
+ break;
+ case OC_INDUCTION_RULE:
+ rule->tv_function = OCInferenceRule_induction;
+ break;
+ case OC_ABDUCTION_RULE:
+ rule->tv_function = OCInferenceRule_abduction;
+ break;
+ case OC_REVISION_RULE:
+ rule->tv_function = OCInferenceRule_revision;
+ break;
+ default:
+ rule->tv_function = NULL;
+ break;
+ }
+
+ rule->rule_function = NULL;
+
+ return rule;
+}
+
+void OCInferenceRule_free(OCInferenceRule *rule) {
+ if (!rule) return;
+
+ if (rule->name) free(rule->name);
+ if (rule->premise_pattern) OCPattern_free(rule->premise_pattern);
+ if (rule->conclusion_pattern) OCPattern_free(rule->conclusion_pattern);
+ if (rule->rule_weights) OCTensor_free(rule->rule_weights);
+
+ free(rule);
+}
+
+/* Built-in Inference Rules */
+OCTruthValue* OCInferenceRule_deduction(OCTruthValue **premise_tvs, int count) {
+ if (!premise_tvs || count < 2) return NULL;
+
+ // Deduction: If A->B and A, then B
+ // TV(B) = TV(A->B) * TV(A)
+ OCTruthValue *result = OCTruthValue_new(1.0, 0.0);
+
+ float s1 = OCTensor_get1d(premise_tvs[0]->strength, 0);
+ float c1 = OCTensor_get1d(premise_tvs[0]->confidence, 0);
+ float s2 = OCTensor_get1d(premise_tvs[1]->strength, 0);
+ float c2 = OCTensor_get1d(premise_tvs[1]->confidence, 0);
+
+ float result_strength = s1 * s2;
+ float result_confidence = c1 * c2;
+
+ OCTensor_set1d(result->strength, 0, result_strength);
+ OCTensor_set1d(result->confidence, 0, result_confidence);
+
+ return result;
+}
+
+OCTruthValue* OCInferenceRule_induction(OCTruthValue **premise_tvs, int count) {
+ if (!premise_tvs || count < 1) return NULL;
+
+ // Simple induction: generalize from specific instances
+ OCTruthValue *result = OCTruthValue_new(0.0, 0.0);
+
+ float avg_strength = 0.0;
+ float avg_confidence = 0.0;
+
+ for (int i = 0; i < count; i++) {
+ avg_strength += OCTensor_get1d(premise_tvs[i]->strength, 0);
+ avg_confidence += OCTensor_get1d(premise_tvs[i]->confidence, 0);
+ }
+
+ avg_strength /= count;
+ avg_confidence /= count;
+
+ // Reduce confidence for generalization
+ avg_confidence *= 0.8;
+
+ OCTensor_set1d(result->strength, 0, avg_strength);
+ OCTensor_set1d(result->confidence, 0, avg_confidence);
+
+ return result;
+}
+
+OCTruthValue* OCInferenceRule_abduction(OCTruthValue **premise_tvs, int count) {
+ if (!premise_tvs || count < 2) return NULL;
+
+ // Abduction: If A->B and B, then A (with reduced confidence)
+ OCTruthValue *result = OCTruthValue_new(1.0, 0.0);
+
+ float s1 = OCTensor_get1d(premise_tvs[0]->strength, 0);
+ float c1 = OCTensor_get1d(premise_tvs[0]->confidence, 0);
+ float s2 = OCTensor_get1d(premise_tvs[1]->strength, 0);
+ float c2 = OCTensor_get1d(premise_tvs[1]->confidence, 0);
+
+ // Abduction has lower confidence than deduction
+ float result_strength = s2 * s1;
+ float result_confidence = c1 * c2 * 0.5;
+
+ OCTensor_set1d(result->strength, 0, result_strength);
+ OCTensor_set1d(result->confidence, 0, result_confidence);
+
+ return result;
+}
+
+OCTruthValue* OCInferenceRule_revision(OCTruthValue **premise_tvs, int count) {
+ if (!premise_tvs || count < 2) return NULL;
+
+ // Use the revision formula from atoms module
+ return OCTruthValue_revision(premise_tvs[0], premise_tvs[1]);
+}
+
+/* Tensor-based Logical Operations */
+OCTensor* OCLogic_and(OCTensor *tensor1, OCTensor *tensor2) {
+ if (!tensor1 || !tensor2) return NULL;
+
+ OCTensor *result = OCTensor_newWithTensor(tensor1);
+ OCTensor_cmul(result, result, tensor2); // Element-wise multiplication
+
+ return result;
+}
+
+OCTensor* OCLogic_or(OCTensor *tensor1, OCTensor *tensor2) {
+ if (!tensor1 || !tensor2) return NULL;
+
+ // OR = tensor1 + tensor2 - tensor1 * tensor2
+ OCTensor *result = OCTensor_newWithTensor(tensor1);
+ OCTensor *product = OCTensor_newWithTensor(tensor1);
+
+ OCTensor_cmul(product, product, tensor2);
+ OCTensor_cadd(result, result, 1.0, tensor2);
+ OCTensor_csub(result, result, 1.0, product);
+
+ OCTensor_free(product);
+ return result;
+}
+
+OCTensor* OCLogic_not(OCTensor *tensor) {
+ if (!tensor) return NULL;
+
+ OCTensor *result = OCTensor_newWithTensor(tensor);
+ OCTensor *ones = OCTensor_newWithSize1d(OCTensor_size(tensor, 0));
+ OCTensor_ones(ones, NULL);
+
+ OCTensor_csub(result, ones, 1.0, tensor);
+
+ OCTensor_free(ones);
+ return result;
+}
+
+OCTensor* OCLogic_implication(OCTensor *antecedent, OCTensor *consequent) {
+ if (!antecedent || !consequent) return NULL;
+
+ // Implication: NOT antecedent OR consequent
+ OCTensor *not_antecedent = OCLogic_not(antecedent);
+ OCTensor *result = OCLogic_or(not_antecedent, consequent);
+
+ OCTensor_free(not_antecedent);
+ return result;
+}
+
+/* Core Inference Operations */
+void OCInferenceEngine_forwardChain(OCInferenceEngine *engine, int max_steps) {
+ if (!engine || !engine->atomspace) return;
+
+ for (int step = 0; step < max_steps && step < engine->max_inference_steps; step++) {
+ int new_atoms_created = 0;
+
+ // Apply each rule to all matching atom combinations
+ for (int rule_idx = 0; rule_idx < engine->rule_count; rule_idx++) {
+ OCInferenceRule *rule = engine->rules[rule_idx];
+ if (!rule || !rule->tv_function) continue;
+
+ // Simple pattern matching - look for atoms that match rule premises
+ // This is a simplified implementation
+ for (long i = 0; i < engine->atomspace->atom_count; i++) {
+ OCAtom *atom1 = engine->atomspace->atoms[i];
+ if (!atom1 || !atom1->tv) continue;
+
+ for (long j = i + 1; j < engine->atomspace->atom_count; j++) {
+ OCAtom *atom2 = engine->atomspace->atoms[j];
+ if (!atom2 || !atom2->tv) continue;
+
+ // Apply rule if confidence is above threshold
+ float conf1 = OCTensor_get1d(atom1->tv->confidence, 0);
+ float conf2 = OCTensor_get1d(atom2->tv->confidence, 0);
+
+ if (conf1 > engine->confidence_threshold &&
+ conf2 > engine->confidence_threshold) {
+
+ OCTruthValue *premise_tvs[] = {atom1->tv, atom2->tv};
+ OCTruthValue *result_tv = rule->tv_function(premise_tvs, 2);
+
+ if (result_tv) {
+ float result_conf = OCTensor_get1d(result_tv->confidence, 0);
+
+ // Only create new inference if confidence is significant
+ if (result_conf > engine->confidence_threshold * 0.5) {
+ // Create new atom with inferred truth value
+ char inferred_name[256];
+ snprintf(inferred_name, sizeof(inferred_name),
+ "inferred_%d_%ld_%ld", rule_idx,
+ atom1->atom_id, atom2->atom_id);
+
+ OCAtom *new_atom = OCAtom_new(OC_CONCEPT_NODE, inferred_name);
+ OCAtom_setTruthValue(new_atom, result_tv);
+
+ // Add relationships to source atoms
+ OCAtom_addIncoming(new_atom, atom1);
+ OCAtom_addIncoming(new_atom, atom2);
+
+ // Add to atomspace if there's room
+ if (OCAtomSpace_addAtom(engine->atomspace, new_atom) > 0) {
+ new_atoms_created++;
+ }
+ } else {
+ OCTruthValue_free(result_tv);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Stop if no new atoms were created
+ if (new_atoms_created == 0) break;
+ }
+}
+
+OCTensor* OCInferenceEngine_computeInferenceMatrix(OCInferenceEngine *engine) {
+ if (!engine || !engine->atomspace) return NULL;
+
+ // Update the inference matrix based on current atom relationships
+ OCTensor_zero(engine->inference_matrix);
+
+ for (long i = 0; i < engine->atomspace->atom_count; i++) {
+ OCAtom *atom = engine->atomspace->atoms[i];
+ if (!atom) continue;
+
+ // Set diagonal to atom's confidence
+ if (atom->tv) {
+ float confidence = OCTensor_get1d(atom->tv->confidence, 0);
+ OCTensor_set2d(engine->inference_matrix, i, i, confidence);
+ }
+
+ // Set relationships based on incoming/outgoing connections
+ for (int j = 0; j < atom->incoming_count; j++) {
+ OCAtom *incoming = atom->incoming[j];
+ if (incoming) {
+ // Find incoming atom's index
+ for (long k = 0; k < engine->atomspace->atom_count; k++) {
+ if (engine->atomspace->atoms[k] == incoming) {
+ float weight = 0.8; // Default relationship strength
+ OCTensor_set2d(engine->inference_matrix, k, i, weight);
+ break;
+ }
+ }
+ }
+ }
+
+ for (int j = 0; j < atom->outgoing_count; j++) {
+ OCAtom *outgoing = atom->outgoing[j];
+ if (outgoing) {
+ // Find outgoing atom's index
+ for (long k = 0; k < engine->atomspace->atom_count; k++) {
+ if (engine->atomspace->atoms[k] == outgoing) {
+ float weight = 0.8; // Default relationship strength
+ OCTensor_set2d(engine->inference_matrix, i, k, weight);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return engine->inference_matrix;
+}
\ No newline at end of file
diff --git a/opencog/inference/inference_engine.h b/opencog/inference/inference_engine.h
new file mode 100644
index 00000000..b3e2154d
--- /dev/null
+++ b/opencog/inference/inference_engine.h
@@ -0,0 +1,132 @@
+#ifndef OPENCOG_INFERENCE_ENGINE_H
+#define OPENCOG_INFERENCE_ENGINE_H
+
+#include "../atoms/opencog_atoms.h"
+
+/* Forward declarations */
+typedef struct OCInferenceEngine OCInferenceEngine;
+typedef struct OCInferenceRule OCInferenceRule;
+typedef struct OCPattern OCPattern;
+typedef struct OCQuery OCQuery;
+
+/* Inference Rule Types */
+typedef enum {
+ OC_DEDUCTION_RULE,
+ OC_INDUCTION_RULE,
+ OC_ABDUCTION_RULE,
+ OC_MODUS_PONENS_RULE,
+ OC_MODUS_TOLLENS_RULE,
+ OC_AND_RULE,
+ OC_OR_RULE,
+ OC_NOT_RULE,
+ OC_REVISION_RULE,
+ OC_TEMPORAL_RULE
+} OCInferenceRuleType;
+
+/* Pattern for pattern matching */
+typedef struct OCPattern {
+ OCAtom **pattern_atoms; // Pattern template atoms
+ int pattern_count;
+ OCTensor *pattern_tensor; // Tensor representation of pattern
+ OCAtomType *required_types; // Required atom types for matching
+ int type_count;
+} OCPattern;
+
+/* Query structure for pattern matching */
+typedef struct OCQuery {
+ OCPattern *pattern;
+ OCAtom **variables; // Variable atoms in the query
+ int variable_count;
+ OCTensor *constraint_tensor; // Tensor constraints
+ float min_confidence; // Minimum confidence threshold
+} OCQuery;
+
+/* Inference Rule structure */
+typedef struct OCInferenceRule {
+ OCInferenceRuleType type;
+ char *name;
+ OCPattern *premise_pattern; // Pattern for premises
+ OCPattern *conclusion_pattern; // Pattern for conclusion
+ OCTensor *rule_weights; // Neural network weights for rule
+ float (*rule_function)(OCAtom **premises, int premise_count,
+ OCAtom **conclusions, int conclusion_count);
+ OCTruthValue* (*tv_function)(OCTruthValue **premise_tvs, int count);
+} OCInferenceRule;
+
+/* Main Inference Engine */
+typedef struct OCInferenceEngine {
+ OCAtomSpace *atomspace;
+ OCInferenceRule **rules; // Array of inference rules
+ int rule_count;
+ int max_rules;
+
+ OCTensor *inference_matrix; // Global inference state matrix
+ OCTensor *rule_activations; // Current rule activation levels
+
+ // Neural network components for learning
+ OCTensor *embedding_weights; // Weights for atom embeddings
+ OCTensor *attention_weights; // Weights for attention mechanism
+ OCTensor *inference_weights; // Weights for inference decisions
+
+ // Configuration parameters
+ float learning_rate;
+ int max_inference_steps;
+ float confidence_threshold;
+} OCInferenceEngine;
+
+/* Inference Engine Operations */
+OCInferenceEngine* OCInferenceEngine_new(OCAtomSpace *atomspace);
+void OCInferenceEngine_free(OCInferenceEngine *engine);
+void OCInferenceEngine_addRule(OCInferenceEngine *engine, OCInferenceRule *rule);
+void OCInferenceEngine_removeRule(OCInferenceEngine *engine, const char *rule_name);
+
+/* Pattern Matching */
+OCPattern* OCPattern_new(OCAtom **pattern_atoms, int count);
+void OCPattern_free(OCPattern *pattern);
+OCTensor* OCPattern_match(OCPattern *pattern, OCAtomSpace *atomspace);
+OCAtom** OCPattern_findMatches(OCPattern *pattern, OCAtomSpace *atomspace, int *match_count);
+
+/* Query Processing */
+OCQuery* OCQuery_new(OCPattern *pattern, OCAtom **variables, int var_count);
+void OCQuery_free(OCQuery *query);
+OCAtom** OCQuery_execute(OCQuery *query, OCAtomSpace *atomspace, int *result_count);
+
+/* Inference Rule Creation */
+OCInferenceRule* OCInferenceRule_new(OCInferenceRuleType type, const char *name);
+void OCInferenceRule_free(OCInferenceRule *rule);
+void OCInferenceRule_setPremisePattern(OCInferenceRule *rule, OCPattern *pattern);
+void OCInferenceRule_setConclusionPattern(OCInferenceRule *rule, OCPattern *pattern);
+
+/* Core Inference Operations */
+OCAtom** OCInferenceEngine_infer(OCInferenceEngine *engine, OCAtom **premises,
+ int premise_count, int *result_count);
+void OCInferenceEngine_forwardChain(OCInferenceEngine *engine, int max_steps);
+void OCInferenceEngine_backwardChain(OCInferenceEngine *engine, OCAtom *goal);
+OCTensor* OCInferenceEngine_computeInferenceMatrix(OCInferenceEngine *engine);
+
+/* Neural Learning and Adaptation */
+void OCInferenceEngine_updateEmbeddings(OCInferenceEngine *engine,
+ OCAtom **atoms, int count,
+ OCTensor *target_activations);
+void OCInferenceEngine_trainRule(OCInferenceEngine *engine,
+ OCInferenceRule *rule,
+ OCAtom **training_premises, int premise_count,
+ OCAtom **training_conclusions, int conclusion_count);
+
+/* Built-in Inference Rules */
+OCTruthValue* OCInferenceRule_deduction(OCTruthValue **premise_tvs, int count);
+OCTruthValue* OCInferenceRule_induction(OCTruthValue **premise_tvs, int count);
+OCTruthValue* OCInferenceRule_abduction(OCTruthValue **premise_tvs, int count);
+OCTruthValue* OCInferenceRule_revision(OCTruthValue **premise_tvs, int count);
+
+/* Tensor-based Logical Operations */
+OCTensor* OCLogic_and(OCTensor *tensor1, OCTensor *tensor2);
+OCTensor* OCLogic_or(OCTensor *tensor1, OCTensor *tensor2);
+OCTensor* OCLogic_not(OCTensor *tensor);
+OCTensor* OCLogic_implication(OCTensor *antecedent, OCTensor *consequent);
+
+/* Probabilistic Inference */
+OCTensor* OCProbability_bayesianUpdate(OCTensor *prior, OCTensor *likelihood, OCTensor *evidence);
+OCTensor* OCProbability_markovChain(OCTensor *transition_matrix, OCTensor *initial_state, int steps);
+
+#endif
\ No newline at end of file
diff --git a/opencog/opencog.c b/opencog/opencog.c
new file mode 100644
index 00000000..ea21777d
--- /dev/null
+++ b/opencog/opencog.c
@@ -0,0 +1,497 @@
+#include "opencog.h"
+#include
+#include
+#include
+#include
+
+static OCError last_error = OC_SUCCESS;
+
+/* System Initialization and Management */
+OpenCog* OpenCog_new(OCConfig *config) {
+ OpenCog *opencog = (OpenCog*)malloc(sizeof(OpenCog));
+ if (!opencog) {
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ // Use provided config or defaults
+ if (config) {
+ opencog->config = *config;
+ } else {
+ OCConfig *default_config = OpenCog_getDefaultConfig();
+ opencog->config = *default_config;
+ free(default_config);
+ }
+
+ // Initialize core components
+ opencog->atomspace = OCAtomSpace_new(opencog->config.max_atoms);
+ if (!opencog->atomspace) {
+ free(opencog);
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ opencog->inference = OCInferenceEngine_new(opencog->atomspace);
+ if (!opencog->inference) {
+ OCAtomSpace_free(opencog->atomspace);
+ free(opencog);
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ if (opencog->config.enable_attention) {
+ opencog->attention = OCAttentionBank_new(opencog->atomspace);
+ if (!opencog->attention) {
+ OCInferenceEngine_free(opencog->inference);
+ OCAtomSpace_free(opencog->atomspace);
+ free(opencog);
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ // Add default attention agents
+ if (opencog->config.enable_hebbian_learning) {
+ OCAttentionAgent *hebbian = OCAttentionAgent_new(OC_HEBBIAN_AGENT, "hebbian");
+ OCAttentionBank_addAgent(opencog->attention, hebbian);
+ }
+
+ OCAttentionAgent *importance_updater = OCAttentionAgent_new(OC_IMPORTANCE_UPDATING_AGENT, "importance");
+ OCAttentionBank_addAgent(opencog->attention, importance_updater);
+
+ if (opencog->config.enable_forgetting) {
+ OCAttentionAgent *forgetting = OCAttentionAgent_new(OC_FORGETTING_AGENT, "forgetting");
+ OCAttentionBank_addAgent(opencog->attention, forgetting);
+ }
+
+ OCAttentionAgent *spreading = OCAttentionAgent_new(OC_SPREADING_AGENT, "spreading");
+ OCAttentionBank_addAgent(opencog->attention, spreading);
+ } else {
+ opencog->attention = NULL;
+ }
+
+ // Initialize statistics
+ opencog->total_inferences = 0;
+ opencog->total_attention_cycles = 0;
+ opencog->system_time = 0.0;
+
+ // Initialize callbacks to NULL
+ opencog->on_atom_added = NULL;
+ opencog->on_inference_complete = NULL;
+ opencog->on_attention_update = NULL;
+
+ last_error = OC_SUCCESS;
+ return opencog;
+}
+
+void OpenCog_free(OpenCog *opencog) {
+ if (!opencog) return;
+
+ if (opencog->attention) OCAttentionBank_free(opencog->attention);
+ if (opencog->inference) OCInferenceEngine_free(opencog->inference);
+ if (opencog->atomspace) OCAtomSpace_free(opencog->atomspace);
+
+ free(opencog);
+}
+
+OCConfig* OpenCog_getDefaultConfig(void) {
+ OCConfig *config = (OCConfig*)malloc(sizeof(OCConfig));
+ if (!config) return NULL;
+
+ config->max_atoms = 10000;
+ config->max_inference_steps = 100;
+ config->confidence_threshold = 0.5f;
+ config->attention_threshold = 0.1f;
+ config->embedding_dimensions = 128;
+ config->enable_attention = 1;
+ config->enable_forgetting = 1;
+ config->enable_hebbian_learning = 1;
+ config->learning_rate = 0.01f;
+
+ return config;
+}
+
+/* High-level Knowledge Operations */
+OCAtom* OpenCog_addConcept(OpenCog *opencog, const char *name, float strength, float confidence) {
+ if (!opencog || !name) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return NULL;
+ }
+
+ OCAtom *atom = OCAtom_new(OC_CONCEPT_NODE, name);
+ if (!atom) {
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ // Set truth value
+ OCTruthValue *tv = OCTruthValue_new(strength, confidence);
+ OCAtom_setTruthValue(atom, tv);
+
+ // Add to atomspace
+ long atom_id = OCAtomSpace_addAtom(opencog->atomspace, atom);
+ if (atom_id < 0) {
+ OCAtom_free(atom);
+ last_error = OC_ERROR_SYSTEM_LIMIT_REACHED;
+ return NULL;
+ }
+
+ // Initialize attention if enabled
+ if (opencog->attention) {
+ OCAtom_setSTI(atom, confidence * 10.0f); // Initial STI based on confidence
+ OCAtom_setLTI(atom, 0.0f);
+ OCAtom_setVLTI(atom, 0.0f);
+ }
+
+ // Fire callback
+ if (opencog->on_atom_added) {
+ opencog->on_atom_added(atom);
+ }
+
+ last_error = OC_SUCCESS;
+ return atom;
+}
+
+OCAtom* OpenCog_addPredicate(OpenCog *opencog, const char *name) {
+ if (!opencog || !name) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return NULL;
+ }
+
+ OCAtom *atom = OCAtom_new(OC_PREDICATE_NODE, name);
+ if (!atom) {
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ // Add to atomspace
+ long atom_id = OCAtomSpace_addAtom(opencog->atomspace, atom);
+ if (atom_id < 0) {
+ OCAtom_free(atom);
+ last_error = OC_ERROR_SYSTEM_LIMIT_REACHED;
+ return NULL;
+ }
+
+ last_error = OC_SUCCESS;
+ return atom;
+}
+
+OCAtom* OpenCog_addLink(OpenCog *opencog, OCAtomType type, OCAtom **atoms, int count) {
+ if (!opencog || !atoms || count <= 0) {
+ last_error = OC_ERROR_INVALID_ARGUMENT;
+ return NULL;
+ }
+
+ char link_name[256];
+ snprintf(link_name, sizeof(link_name), "link_%d", (int)type);
+
+ OCAtom *link = OCAtom_new(type, link_name);
+ if (!link) {
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ // Add outgoing atoms
+ for (int i = 0; i < count; i++) {
+ OCAtom_addOutgoing(link, atoms[i]);
+ OCAtom_addIncoming(atoms[i], link);
+ }
+
+ // Add to atomspace
+ long atom_id = OCAtomSpace_addAtom(opencog->atomspace, link);
+ if (atom_id < 0) {
+ OCAtom_free(link);
+ last_error = OC_ERROR_SYSTEM_LIMIT_REACHED;
+ return NULL;
+ }
+
+ last_error = OC_SUCCESS;
+ return link;
+}
+
+OCAtom* OpenCog_findAtom(OpenCog *opencog, const char *name) {
+ if (!opencog || !name) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return NULL;
+ }
+
+ for (long i = 0; i < opencog->atomspace->atom_count; i++) {
+ OCAtom *atom = opencog->atomspace->atoms[i];
+ if (atom && atom->name && strcmp(atom->name, name) == 0) {
+ last_error = OC_SUCCESS;
+ return atom;
+ }
+ }
+
+ last_error = OC_ERROR_ATOM_NOT_FOUND;
+ return NULL;
+}
+
+/* Reasoning and Inference */
+void OpenCog_forwardChain(OpenCog *opencog, int max_steps) {
+ if (!opencog) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return;
+ }
+
+ clock_t start_time = clock();
+
+ OCInferenceEngine_forwardChain(opencog->inference, max_steps);
+ opencog->total_inferences++;
+
+ clock_t end_time = clock();
+ opencog->system_time += ((double)(end_time - start_time)) / CLOCKS_PER_SEC;
+
+ last_error = OC_SUCCESS;
+}
+
+/* Learning and Adaptation */
+void OpenCog_associateAtoms(OpenCog *opencog, OCAtom *atom1, OCAtom *atom2, float strength) {
+ if (!opencog || !atom1 || !atom2) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return;
+ }
+
+ // Create an association link
+ OCAtom *atoms[] = {atom1, atom2};
+ OCAtom *association = OpenCog_addLink(opencog, OC_LIST_LINK, atoms, 2);
+
+ if (association) {
+ OCTruthValue *tv = OCTruthValue_new(strength, 0.9f);
+ OCAtom_setTruthValue(association, tv);
+
+ // Update attention for associated atoms
+ if (opencog->attention) {
+ OCAtom_updateAttentionValue(atom1, OC_STI, strength * 5.0f);
+ OCAtom_updateAttentionValue(atom2, OC_STI, strength * 5.0f);
+ }
+ }
+
+ last_error = OC_SUCCESS;
+}
+
+/* Attention and Focus */
+void OpenCog_stepAttention(OpenCog *opencog) {
+ if (!opencog || !opencog->attention) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return;
+ }
+
+ OCAttentionBank_cycle(opencog->attention);
+ opencog->total_attention_cycles++;
+
+ last_error = OC_SUCCESS;
+}
+
+void OpenCog_boostAttention(OpenCog *opencog, OCAtom *atom, float boost) {
+ if (!opencog || !atom) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return;
+ }
+
+ if (opencog->attention) {
+ float old_sti = OCAtom_getSTI(atom);
+ OCAtom_updateAttentionValue(atom, OC_STI, boost);
+ float new_sti = OCAtom_getSTI(atom);
+
+ // Fire callback
+ if (opencog->on_attention_update) {
+ opencog->on_attention_update(atom, old_sti, new_sti);
+ }
+ }
+
+ last_error = OC_SUCCESS;
+}
+
+OCAtom** OpenCog_getAttentionalFocus(OpenCog *opencog, int *count) {
+ if (!opencog || !count) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return NULL;
+ }
+
+ if (!opencog->attention) {
+ *count = 0;
+ return NULL;
+ }
+
+ // Find atoms with highest attention
+ OCAtom **focus_atoms = (OCAtom**)malloc(sizeof(OCAtom*) * opencog->config.max_atoms);
+ if (!focus_atoms) {
+ last_error = OC_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ int focus_count = 0;
+ float min_attention = opencog->config.attention_threshold;
+
+ for (long i = 0; i < opencog->atomspace->atom_count; i++) {
+ OCAtom *atom = opencog->atomspace->atoms[i];
+ if (atom && OCAtom_getSTI(atom) > min_attention) {
+ focus_atoms[focus_count] = atom;
+ focus_count++;
+ }
+ }
+
+ *count = focus_count;
+
+ if (focus_count == 0) {
+ free(focus_atoms);
+ return NULL;
+ }
+
+ // Resize array to actual size
+ focus_atoms = (OCAtom**)realloc(focus_atoms, sizeof(OCAtom*) * focus_count);
+
+ last_error = OC_SUCCESS;
+ return focus_atoms;
+}
+
+/* Pattern Matching and Search */
+float OpenCog_similarity(OpenCog *opencog, OCAtom *atom1, OCAtom *atom2) {
+ if (!opencog || !atom1 || !atom2) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return 0.0f;
+ }
+
+ OCTensor *similarity_tensor = OCAtom_computeSimilarity(atom1, atom2);
+ if (!similarity_tensor) {
+ last_error = OC_ERROR_INFERENCE_FAILED;
+ return 0.0f;
+ }
+
+ float similarity = OCTensor_get1d(similarity_tensor, 0);
+ OCTensor_free(similarity_tensor);
+
+ last_error = OC_SUCCESS;
+ return similarity;
+}
+
+/* System Analysis and Monitoring */
+void OpenCog_getStats(OpenCog *opencog, char *stats_buffer, int buffer_size) {
+ if (!opencog || !stats_buffer) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return;
+ }
+
+ snprintf(stats_buffer, buffer_size,
+ "OpenCog Statistics:\n"
+ "Atoms: %ld/%ld\n"
+ "Inferences: %ld\n"
+ "Attention Cycles: %ld\n"
+ "System Time: %.2fs\n"
+ "Attention Enabled: %s\n"
+ "Hebbian Learning: %s\n",
+ opencog->atomspace->atom_count,
+ opencog->atomspace->max_atoms,
+ opencog->total_inferences,
+ opencog->total_attention_cycles,
+ opencog->system_time,
+ opencog->config.enable_attention ? "Yes" : "No",
+ opencog->config.enable_hebbian_learning ? "Yes" : "No"
+ );
+
+ last_error = OC_SUCCESS;
+}
+
+OCTensor* OpenCog_getAtomEmbeddings(OpenCog *opencog) {
+ if (!opencog) {
+ last_error = OC_ERROR_NULL_POINTER;
+ return NULL;
+ }
+
+ // Create matrix of all atom embeddings
+ OCTensor *embeddings = OCTensor_newWithSize2d(opencog->atomspace->atom_count,
+ opencog->config.embedding_dimensions);
+
+ for (long i = 0; i < opencog->atomspace->atom_count; i++) {
+ OCAtom *atom = opencog->atomspace->atoms[i];
+ if (atom && atom->embedding) {
+ // Copy atom embedding to row i
+ for (long j = 0; j < opencog->config.embedding_dimensions; j++) {
+ float val = OCTensor_get1d(atom->embedding, j);
+ OCTensor_set2d(embeddings, i, j, val);
+ }
+ }
+ }
+
+ last_error = OC_SUCCESS;
+ return embeddings;
+}
+
+/* Utility Functions */
+void OpenCog_printAtom(OCAtom *atom) {
+ if (!atom) {
+ printf("NULL atom\n");
+ return;
+ }
+
+ printf("Atom[%ld]: %s (type=%d)\n", atom->atom_id, atom->name ? atom->name : "unnamed", atom->type);
+
+ if (atom->tv) {
+ float strength = OCTensor_get1d(atom->tv->strength, 0);
+ float confidence = OCTensor_get1d(atom->tv->confidence, 0);
+ printf(" TruthValue: strength=%.3f, confidence=%.3f\n", strength, confidence);
+ }
+
+ if (atom->attention && OCTensor_nDimension(atom->attention) >= 3) {
+ float sti = OCTensor_get1d(atom->attention, 0);
+ float lti = OCTensor_get1d(atom->attention, 1);
+ float vlti = OCTensor_get1d(atom->attention, 2);
+ printf(" Attention: STI=%.3f, LTI=%.3f, VLTI=%.3f\n", sti, lti, vlti);
+ }
+
+ printf(" Incoming: %d, Outgoing: %d\n", atom->incoming_count, atom->outgoing_count);
+}
+
+void OpenCog_printAtomSpace(OpenCog *opencog) {
+ if (!opencog) {
+ printf("NULL OpenCog system\n");
+ return;
+ }
+
+ printf("=== OpenCog AtomSpace ===\n");
+ printf("Total atoms: %ld\n\n", opencog->atomspace->atom_count);
+
+ for (long i = 0; i < opencog->atomspace->atom_count; i++) {
+ OCAtom *atom = opencog->atomspace->atoms[i];
+ if (atom) {
+ OpenCog_printAtom(atom);
+ printf("\n");
+ }
+ }
+}
+
+/* Error Handling */
+OCError OpenCog_getLastError(void) {
+ return last_error;
+}
+
+const char* OpenCog_getErrorString(OCError error) {
+ switch (error) {
+ case OC_SUCCESS: return "Success";
+ case OC_ERROR_NULL_POINTER: return "Null pointer";
+ case OC_ERROR_INVALID_ARGUMENT: return "Invalid argument";
+ case OC_ERROR_OUT_OF_MEMORY: return "Out of memory";
+ case OC_ERROR_ATOM_NOT_FOUND: return "Atom not found";
+ case OC_ERROR_INFERENCE_FAILED: return "Inference failed";
+ case OC_ERROR_SERIALIZATION_FAILED: return "Serialization failed";
+ case OC_ERROR_SYSTEM_LIMIT_REACHED: return "System limit reached";
+ default: return "Unknown error";
+ }
+}
+
+/* Version Information */
+const char* OpenCog_getVersion(void) {
+ return OPENCOG_VERSION_STRING;
+}
+
+int OpenCog_getVersionMajor(void) {
+ return OPENCOG_VERSION_MAJOR;
+}
+
+int OpenCog_getVersionMinor(void) {
+ return OPENCOG_VERSION_MINOR;
+}
+
+int OpenCog_getVersionPatch(void) {
+ return OPENCOG_VERSION_PATCH;
+}
\ No newline at end of file
diff --git a/opencog/opencog.h b/opencog/opencog.h
new file mode 100644
index 00000000..a671de09
--- /dev/null
+++ b/opencog/opencog.h
@@ -0,0 +1,155 @@
+#ifndef OPENCOG_H
+#define OPENCOG_H
+
+/*
+ * OpenCog Multi-Dimensional Tensor Inference Engine
+ *
+ * This library implements OpenCog's cognitive architecture using
+ * multi-dimensional tensors as the underlying representation for
+ * atoms, truth values, attention allocation, and inference.
+ *
+ * Key Components:
+ * - Tensor-based atom representation with embeddings
+ * - Truth value calculations using tensor operations
+ * - Attention allocation with neural dynamics
+ * - Pattern matching and inference using tensor similarity
+ * - Probabilistic reasoning with tensor computations
+ */
+
+#include "atoms/opencog_atoms.h"
+#include "inference/inference_engine.h"
+#include "attention/attention_allocation.h"
+
+/* OpenCog System Configuration */
+typedef struct OCConfig {
+ long max_atoms; // Maximum number of atoms
+ long max_inference_steps; // Maximum inference iterations
+ float confidence_threshold; // Minimum confidence for inference
+ float attention_threshold; // Minimum attention for processing
+ int embedding_dimensions; // Dimensionality of atom embeddings
+ int enable_attention; // Enable attention allocation system
+ int enable_forgetting; // Enable memory decay/forgetting
+ int enable_hebbian_learning; // Enable Hebbian learning
+ float learning_rate; // Global learning rate
+} OCConfig;
+
+/* Complete OpenCog System */
+typedef struct OpenCog {
+ OCAtomSpace *atomspace; // Knowledge base
+ OCInferenceEngine *inference; // Reasoning engine
+ OCAttentionBank *attention; // Attention allocation
+ OCConfig config; // System configuration
+
+ // System statistics
+ long total_inferences; // Total inferences performed
+ long total_attention_cycles; // Total attention cycles
+ double system_time; // System runtime in seconds
+
+ // Event callbacks
+ void (*on_atom_added)(OCAtom *atom);
+ void (*on_inference_complete)(OCAtom **results, int count);
+ void (*on_attention_update)(OCAtom *atom, float old_sti, float new_sti);
+} OpenCog;
+
+/* System Initialization and Management */
+OpenCog* OpenCog_new(OCConfig *config);
+void OpenCog_free(OpenCog *opencog);
+void OpenCog_reset(OpenCog *opencog);
+OCConfig* OpenCog_getDefaultConfig(void);
+
+/* High-level Knowledge Operations */
+OCAtom* OpenCog_addConcept(OpenCog *opencog, const char *name, float strength, float confidence);
+OCAtom* OpenCog_addPredicate(OpenCog *opencog, const char *name);
+OCAtom* OpenCog_addLink(OpenCog *opencog, OCAtomType type, OCAtom **atoms, int count);
+OCAtom* OpenCog_findAtom(OpenCog *opencog, const char *name);
+OCAtom** OpenCog_findSimilarAtoms(OpenCog *opencog, OCAtom *query_atom, float threshold, int *count);
+
+/* Reasoning and Inference */
+OCAtom** OpenCog_query(OpenCog *opencog, const char *pattern, int *result_count);
+OCAtom** OpenCog_infer(OpenCog *opencog, const char *premise, int max_steps, int *result_count);
+void OpenCog_forwardChain(OpenCog *opencog, int max_steps);
+void OpenCog_backwardChain(OpenCog *opencog, const char *goal);
+
+/* Learning and Adaptation */
+void OpenCog_learn(OpenCog *opencog, OCAtom **examples, int count);
+void OpenCog_trainEmbedding(OpenCog *opencog, OCAtom *atom, OCTensor *target_embedding);
+void OpenCog_associateAtoms(OpenCog *opencog, OCAtom *atom1, OCAtom *atom2, float strength);
+
+/* Attention and Focus */
+void OpenCog_setFocus(OpenCog *opencog, OCAtom **atoms, int count);
+OCAtom** OpenCog_getAttentionalFocus(OpenCog *opencog, int *count);
+void OpenCog_boostAttention(OpenCog *opencog, OCAtom *atom, float boost);
+void OpenCog_stepAttention(OpenCog *opencog);
+
+/* Pattern Matching and Search */
+OCAtom** OpenCog_patternMatch(OpenCog *opencog, OCPattern *pattern, int *match_count);
+OCAtom** OpenCog_search(OpenCog *opencog, const char *query, int *result_count);
+float OpenCog_similarity(OpenCog *opencog, OCAtom *atom1, OCAtom *atom2);
+
+/* System Analysis and Monitoring */
+void OpenCog_getStats(OpenCog *opencog, char *stats_buffer, int buffer_size);
+OCTensor* OpenCog_getAtomEmbeddings(OpenCog *opencog);
+OCTensor* OpenCog_getAttentionMatrix(OpenCog *opencog);
+OCTensor* OpenCog_getInferenceMatrix(OpenCog *opencog);
+
+/* Serialization and Persistence */
+int OpenCog_saveToFile(OpenCog *opencog, const char *filename);
+OpenCog* OpenCog_loadFromFile(const char *filename);
+char* OpenCog_serialize(OpenCog *opencog);
+OpenCog* OpenCog_deserialize(const char *data);
+
+/* Probabilistic Reasoning */
+float OpenCog_probability(OpenCog *opencog, OCAtom *atom);
+OCTruthValue* OpenCog_bayesianUpdate(OpenCog *opencog, OCTruthValue *prior,
+ OCTruthValue *likelihood, OCTruthValue *evidence);
+OCTensor* OpenCog_uncertaintyPropagation(OpenCog *opencog, OCAtom **atoms, int count);
+
+/* Temporal Reasoning */
+void OpenCog_addTemporalSequence(OpenCog *opencog, OCAtom **sequence, int count, double *timestamps);
+OCAtom** OpenCog_predictNext(OpenCog *opencog, OCAtom **context, int context_count, int *prediction_count);
+void OpenCog_updateTemporal(OpenCog *opencog, double current_time);
+
+/* Multi-modal Integration */
+void OpenCog_addSensorInput(OpenCog *opencog, OCTensor *sensor_data, const char *modality);
+OCTensor* OpenCog_multimodalFusion(OpenCog *opencog, OCTensor **modality_tensors, int modality_count);
+OCAtom* OpenCog_groundSymbol(OpenCog *opencog, const char *symbol, OCTensor *perceptual_data);
+
+/* Neural Integration */
+void OpenCog_setNeuralWeights(OpenCog *opencog, OCTensor *weights, const char *component);
+OCTensor* OpenCog_getNeuralWeights(OpenCog *opencog, const char *component);
+void OpenCog_trainNeuralComponent(OpenCog *opencog, const char *component,
+ OCTensor *inputs, OCTensor *targets);
+
+/* Utility Functions */
+void OpenCog_printAtom(OCAtom *atom);
+void OpenCog_printAtomSpace(OpenCog *opencog);
+void OpenCog_visualizeAttention(OpenCog *opencog, const char *output_file);
+int OpenCog_validateSystem(OpenCog *opencog);
+
+/* Error Handling */
+typedef enum {
+ OC_SUCCESS = 0,
+ OC_ERROR_NULL_POINTER,
+ OC_ERROR_INVALID_ARGUMENT,
+ OC_ERROR_OUT_OF_MEMORY,
+ OC_ERROR_ATOM_NOT_FOUND,
+ OC_ERROR_INFERENCE_FAILED,
+ OC_ERROR_SERIALIZATION_FAILED,
+ OC_ERROR_SYSTEM_LIMIT_REACHED
+} OCError;
+
+OCError OpenCog_getLastError(void);
+const char* OpenCog_getErrorString(OCError error);
+
+/* Version Information */
+#define OPENCOG_VERSION_MAJOR 1
+#define OPENCOG_VERSION_MINOR 0
+#define OPENCOG_VERSION_PATCH 0
+#define OPENCOG_VERSION_STRING "1.0.0-tensor"
+
+const char* OpenCog_getVersion(void);
+int OpenCog_getVersionMajor(void);
+int OpenCog_getVersionMinor(void);
+int OpenCog_getVersionPatch(void);
+
+#endif
\ No newline at end of file
diff --git a/opencog/tensor_wrapper.c b/opencog/tensor_wrapper.c
new file mode 100644
index 00000000..f6af8717
--- /dev/null
+++ b/opencog/tensor_wrapper.c
@@ -0,0 +1,185 @@
+#include "tensor_wrapper.h"
+#include
+#include
+#include
+
+/* Tensor Creation and Management */
+OCTensor* OCTensor_new(void) {
+ OCTensor *tensor = (OCTensor*)malloc(sizeof(OCTensor));
+ if (!tensor) return NULL;
+
+ tensor->data = NULL;
+ tensor->size = NULL;
+ tensor->stride = NULL;
+ tensor->nDim = 0;
+ tensor->nElements = 0;
+ tensor->refcount = 1;
+
+ return tensor;
+}
+
+OCTensor* OCTensor_newWithSize1d(long size0) {
+ OCTensor *tensor = OCTensor_new();
+ if (!tensor) return NULL;
+
+ tensor->nDim = 1;
+ tensor->nElements = size0;
+
+ tensor->size = (long*)malloc(sizeof(long));
+ tensor->stride = (long*)malloc(sizeof(long));
+ tensor->size[0] = size0;
+ tensor->stride[0] = 1;
+
+ tensor->data = (float*)calloc(size0, sizeof(float));
+
+ if (!tensor->data || !tensor->size || !tensor->stride) {
+ OCTensor_free(tensor);
+ return NULL;
+ }
+
+ return tensor;
+}
+
+OCTensor* OCTensor_newWithSize2d(long size0, long size1) {
+ OCTensor *tensor = OCTensor_new();
+ if (!tensor) return NULL;
+
+ tensor->nDim = 2;
+ tensor->nElements = size0 * size1;
+
+ tensor->size = (long*)malloc(2 * sizeof(long));
+ tensor->stride = (long*)malloc(2 * sizeof(long));
+ tensor->size[0] = size0;
+ tensor->size[1] = size1;
+ tensor->stride[0] = size1; // Row-major order
+ tensor->stride[1] = 1;
+
+ tensor->data = (float*)calloc(size0 * size1, sizeof(float));
+
+ if (!tensor->data || !tensor->size || !tensor->stride) {
+ OCTensor_free(tensor);
+ return NULL;
+ }
+
+ return tensor;
+}
+
+void OCTensor_retain(OCTensor *tensor) {
+ if (tensor) {
+ tensor->refcount++;
+ }
+}
+
+void OCTensor_free(OCTensor *tensor) {
+ if (!tensor) return;
+
+ tensor->refcount--;
+ if (tensor->refcount > 0) return;
+
+ if (tensor->data) free(tensor->data);
+ if (tensor->size) free(tensor->size);
+ if (tensor->stride) free(tensor->stride);
+ free(tensor);
+}
+
+/* Data Access */
+float OCTensor_get1d(OCTensor *tensor, long index) {
+ if (!tensor || !tensor->data || tensor->nDim != 1 || index >= tensor->size[0]) {
+ return 0.0f;
+ }
+ return tensor->data[index];
+}
+
+float OCTensor_get2d(OCTensor *tensor, long x, long y) {
+ if (!tensor || !tensor->data || tensor->nDim != 2 ||
+ x >= tensor->size[0] || y >= tensor->size[1]) {
+ return 0.0f;
+ }
+ return tensor->data[x * tensor->stride[0] + y * tensor->stride[1]];
+}
+
+void OCTensor_set1d(OCTensor *tensor, long index, float value) {
+ if (!tensor || !tensor->data || tensor->nDim != 1 || index >= tensor->size[0]) {
+ return;
+ }
+ tensor->data[index] = value;
+}
+
+void OCTensor_set2d(OCTensor *tensor, long x, long y, float value) {
+ if (!tensor || !tensor->data || tensor->nDim != 2 ||
+ x >= tensor->size[0] || y >= tensor->size[1]) {
+ return;
+ }
+ tensor->data[x * tensor->stride[0] + y * tensor->stride[1]] = value;
+}
+
+/* Tensor Operations */
+void OCTensor_zero(OCTensor *tensor) {
+ if (!tensor || !tensor->data) return;
+ memset(tensor->data, 0, tensor->nElements * sizeof(float));
+}
+
+void OCTensor_fill(OCTensor *tensor, float value) {
+ if (!tensor || !tensor->data) return;
+ for (long i = 0; i < tensor->nElements; i++) {
+ tensor->data[i] = value;
+ }
+}
+
+void OCTensor_copy(OCTensor *dst, OCTensor *src) {
+ if (!dst || !src || !dst->data || !src->data || dst->nElements != src->nElements) {
+ return;
+ }
+ memcpy(dst->data, src->data, src->nElements * sizeof(float));
+}
+
+void OCTensor_cadd(OCTensor *r, OCTensor *a, float scalar, OCTensor *b) {
+ if (!r || !a || !b || !r->data || !a->data || !b->data) return;
+ if (r->nElements != a->nElements || r->nElements != b->nElements) return;
+
+ for (long i = 0; i < r->nElements; i++) {
+ r->data[i] = a->data[i] + scalar * b->data[i];
+ }
+}
+
+void OCTensor_norm(OCTensor *r, OCTensor *a, float p, int dim, int keepdim) {
+ // Simplified norm computation - just L2 norm of entire tensor
+ if (!r || !a || !r->data || !a->data) return;
+
+ float norm_val = 0.0f;
+ for (long i = 0; i < a->nElements; i++) {
+ norm_val += a->data[i] * a->data[i];
+ }
+ norm_val = sqrt(norm_val);
+
+ // Store result in first element
+ if (r->nElements > 0) {
+ r->data[0] = norm_val;
+ }
+}
+
+float OCTensor_dot(OCTensor *a, OCTensor *b) {
+ if (!a || !b || !a->data || !b->data || a->nElements != b->nElements) {
+ return 0.0f;
+ }
+
+ float result = 0.0f;
+ for (long i = 0; i < a->nElements; i++) {
+ result += a->data[i] * b->data[i];
+ }
+ return result;
+}
+
+/* Utility Functions */
+long OCTensor_nElement(OCTensor *tensor) {
+ return tensor ? tensor->nElements : 0;
+}
+
+long OCTensor_size(OCTensor *tensor, int dim) {
+ if (!tensor || dim >= tensor->nDim || dim < 0) return 0;
+ return tensor->size[dim];
+}
+
+int OCTensor_nDimension(OCTensor *tensor) {
+ return tensor ? tensor->nDim : 0;
+}
\ No newline at end of file
diff --git a/opencog/tensor_wrapper.h b/opencog/tensor_wrapper.h
new file mode 100644
index 00000000..9525867c
--- /dev/null
+++ b/opencog/tensor_wrapper.h
@@ -0,0 +1,48 @@
+#ifndef OPENCOG_TENSOR_WRAPPER_H
+#define OPENCOG_TENSOR_WRAPPER_H
+
+#include
+
+/* Simple tensor abstraction to avoid TH template complexity */
+typedef struct OCTensor {
+ float *data; // Raw data array
+ long *size; // Dimensions
+ long *stride; // Strides for each dimension
+ int nDim; // Number of dimensions
+ long nElements; // Total number of elements
+ int refcount; // Reference counting
+} OCTensor;
+
+/* Tensor Creation and Management */
+OCTensor* OCTensor_new(void);
+OCTensor* OCTensor_newWithSize1d(long size0);
+OCTensor* OCTensor_newWithSize2d(long size0, long size1);
+OCTensor* OCTensor_newWithSize3d(long size0, long size1, long size2);
+OCTensor* OCTensor_newWithTensor(OCTensor *tensor);
+void OCTensor_retain(OCTensor *tensor);
+void OCTensor_free(OCTensor *tensor);
+
+/* Data Access */
+float OCTensor_get1d(OCTensor *tensor, long index);
+float OCTensor_get2d(OCTensor *tensor, long x, long y);
+void OCTensor_set1d(OCTensor *tensor, long index, float value);
+void OCTensor_set2d(OCTensor *tensor, long x, long y, float value);
+
+/* Tensor Operations */
+void OCTensor_zero(OCTensor *tensor);
+void OCTensor_fill(OCTensor *tensor, float value);
+void OCTensor_copy(OCTensor *dst, OCTensor *src);
+void OCTensor_add(OCTensor *r, OCTensor *a, OCTensor *b);
+void OCTensor_cadd(OCTensor *r, OCTensor *a, float scalar, OCTensor *b);
+void OCTensor_mul(OCTensor *r, OCTensor *a, float scalar);
+void OCTensor_addmul(OCTensor *r, OCTensor *a, float scalar, OCTensor *b);
+void OCTensor_norm(OCTensor *r, OCTensor *a, float p, int dim, int keepdim);
+float OCTensor_dot(OCTensor *a, OCTensor *b);
+float OCTensor_sum(OCTensor *tensor);
+
+/* Utility Functions */
+long OCTensor_nElement(OCTensor *tensor);
+long OCTensor_size(OCTensor *tensor, int dim);
+int OCTensor_nDimension(OCTensor *tensor);
+
+#endif
\ No newline at end of file
diff --git a/opencog/test_opencog.c b/opencog/test_opencog.c
new file mode 100644
index 00000000..4d13a00b
--- /dev/null
+++ b/opencog/test_opencog.c
@@ -0,0 +1,348 @@
+#include "opencog.h"
+#include
+#include
+#include
+#include
+
+#define TEST_ASSERT(condition, message) \
+ do { \
+ if (!(condition)) { \
+ printf("FAIL: %s\n", message); \
+ return 0; \
+ } \
+ printf("PASS: %s\n", message); \
+ } while(0)
+
+/* Test basic atom creation and truth values */
+int test_basic_atoms() {
+ printf("\n=== Testing Basic Atom Operations ===\n");
+
+ OpenCog *opencog = OpenCog_new(NULL);
+ TEST_ASSERT(opencog != NULL, "OpenCog system creation");
+
+ // Test concept creation
+ OCAtom *cat = OpenCog_addConcept(opencog, "cat", 0.9f, 0.8f);
+ TEST_ASSERT(cat != NULL, "Concept atom creation");
+ TEST_ASSERT(strcmp(cat->name, "cat") == 0, "Atom name setting");
+ TEST_ASSERT(cat->type == OC_CONCEPT_NODE, "Atom type setting");
+
+ // Test predicate creation
+ OCAtom *animal = OpenCog_addPredicate(opencog, "animal");
+ TEST_ASSERT(animal != NULL, "Predicate atom creation");
+
+ // Test finding atoms
+ OCAtom *found_cat = OpenCog_findAtom(opencog, "cat");
+ TEST_ASSERT(found_cat == cat, "Atom retrieval by name");
+
+ // Test truth values
+ if (cat->tv) {
+ float strength = OCTensor_get1d(cat->tv->strength, 0);
+ float confidence = OCTensor_get1d(cat->tv->confidence, 0);
+ TEST_ASSERT(strength == 0.9f, "Truth value strength");
+ TEST_ASSERT(confidence == 0.8f, "Truth value confidence");
+ }
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test link creation and relationships */
+int test_links_and_relationships() {
+ printf("\n=== Testing Links and Relationships ===\n");
+
+ OpenCog *opencog = OpenCog_new(NULL);
+
+ // Create some concepts
+ OCAtom *cat = OpenCog_addConcept(opencog, "cat", 0.9f, 0.8f);
+ OCAtom *animal = OpenCog_addConcept(opencog, "animal", 0.95f, 0.9f);
+ OCAtom *mammal = OpenCog_addConcept(opencog, "mammal", 0.92f, 0.85f);
+
+ TEST_ASSERT(cat && animal && mammal, "Concept atoms creation");
+
+ // Create inheritance links: cat -> mammal -> animal
+ OCAtom *inheritance_atoms1[] = {cat, mammal};
+ OCAtom *inheritance1 = OpenCog_addLink(opencog, OC_LIST_LINK, inheritance_atoms1, 2);
+ TEST_ASSERT(inheritance1 != NULL, "Inheritance link 1 creation");
+
+ OCAtom *inheritance_atoms2[] = {mammal, animal};
+ OCAtom *inheritance2 = OpenCog_addLink(opencog, OC_LIST_LINK, inheritance_atoms2, 2);
+ TEST_ASSERT(inheritance2 != NULL, "Inheritance link 2 creation");
+
+ // Test relationship counting
+ TEST_ASSERT(cat->outgoing_count == 0, "Cat outgoing links");
+ TEST_ASSERT(cat->incoming_count == 1, "Cat incoming links");
+ TEST_ASSERT(mammal->incoming_count == 2, "Mammal incoming links");
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test attention allocation system */
+int test_attention_system() {
+ printf("\n=== Testing Attention Allocation ===\n");
+
+ OCConfig *config = OpenCog_getDefaultConfig();
+ config->enable_attention = 1;
+ config->enable_hebbian_learning = 1;
+
+ OpenCog *opencog = OpenCog_new(config);
+ free(config);
+
+ TEST_ASSERT(opencog->attention != NULL, "Attention bank creation");
+
+ // Create some atoms
+ OCAtom *cat = OpenCog_addConcept(opencog, "cat", 0.9f, 0.8f);
+ OCAtom *dog = OpenCog_addConcept(opencog, "dog", 0.85f, 0.75f);
+ OCAtom *animal = OpenCog_addConcept(opencog, "animal", 0.95f, 0.9f);
+
+ // Test initial attention values
+ float initial_sti = OCAtom_getSTI(cat);
+ TEST_ASSERT(initial_sti > 0, "Initial STI assignment");
+
+ // Test attention boosting
+ OpenCog_boostAttention(opencog, cat, 20.0f);
+ float boosted_sti = OCAtom_getSTI(cat);
+ TEST_ASSERT(boosted_sti > initial_sti, "Attention boosting");
+
+ // Test attention cycling
+ OpenCog_stepAttention(opencog);
+ TEST_ASSERT(opencog->total_attention_cycles == 1, "Attention cycling");
+
+ // Test attentional focus
+ int focus_count;
+ OCAtom **focus_atoms = OpenCog_getAttentionalFocus(opencog, &focus_count);
+ TEST_ASSERT(focus_count > 0, "Attentional focus retrieval");
+
+ if (focus_atoms) {
+ free(focus_atoms);
+ }
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test similarity computation */
+int test_similarity_computation() {
+ printf("\n=== Testing Similarity Computation ===\n");
+
+ OpenCog *opencog = OpenCog_new(NULL);
+
+ // Create atoms with different embeddings
+ OCAtom *cat = OpenCog_addConcept(opencog, "cat", 0.9f, 0.8f);
+ OCAtom *dog = OpenCog_addConcept(opencog, "dog", 0.85f, 0.75f);
+ OCAtom *tree = OpenCog_addConcept(opencog, "tree", 0.8f, 0.7f);
+
+ TEST_ASSERT(cat && dog && tree, "Atoms for similarity testing");
+
+ // Modify embeddings to make cat and dog more similar
+ if (cat->embedding && dog->embedding) {
+ // Set similar values in embeddings
+ for (int i = 0; i < 10; i++) {
+ OCTensor_set1d(cat->embedding, i, 0.5f + i * 0.01f);
+ OCTensor_set1d(dog->embedding, i, 0.5f + i * 0.01f + 0.1f); // Slightly different
+ OCTensor_set1d(tree->embedding, i, -0.5f + i * 0.02f); // Very different
+ }
+ }
+
+ // Test similarity computation
+ float cat_dog_sim = OpenCog_similarity(opencog, cat, dog);
+ float cat_tree_sim = OpenCog_similarity(opencog, cat, tree);
+
+ TEST_ASSERT(cat_dog_sim > cat_tree_sim, "Similarity comparison (cat-dog > cat-tree)");
+ printf(" Cat-Dog similarity: %.3f\n", cat_dog_sim);
+ printf(" Cat-Tree similarity: %.3f\n", cat_tree_sim);
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test inference operations */
+int test_inference_operations() {
+ printf("\n=== Testing Inference Operations ===\n");
+
+ OpenCog *opencog = OpenCog_new(NULL);
+
+ // Create a knowledge base
+ OCAtom *socrates = OpenCog_addConcept(opencog, "Socrates", 0.9f, 0.9f);
+ OCAtom *human = OpenCog_addConcept(opencog, "human", 0.95f, 0.9f);
+ OCAtom *mortal = OpenCog_addConcept(opencog, "mortal", 0.98f, 0.95f);
+
+ TEST_ASSERT(socrates && human && mortal, "Knowledge base atoms creation");
+
+ // Create relationships: Socrates is human, humans are mortal
+ OpenCog_associateAtoms(opencog, socrates, human, 0.9f);
+ OpenCog_associateAtoms(opencog, human, mortal, 0.95f);
+
+ long initial_atom_count = opencog->atomspace->atom_count;
+
+ // Run forward chaining inference
+ OpenCog_forwardChain(opencog, 5);
+
+ long final_atom_count = opencog->atomspace->atom_count;
+ TEST_ASSERT(final_atom_count >= initial_atom_count, "Inference atom generation");
+ TEST_ASSERT(opencog->total_inferences > 0, "Inference counter update");
+
+ printf(" Initial atoms: %ld, Final atoms: %ld\n", initial_atom_count, final_atom_count);
+ printf(" Total inferences: %ld\n", opencog->total_inferences);
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test learning and associations */
+int test_learning_associations() {
+ printf("\n=== Testing Learning and Associations ===\n");
+
+ OCConfig *config = OpenCog_getDefaultConfig();
+ config->enable_hebbian_learning = 1;
+
+ OpenCog *opencog = OpenCog_new(config);
+ free(config);
+
+ // Create some concepts
+ OCAtom *red = OpenCog_addConcept(opencog, "red", 0.8f, 0.7f);
+ OCAtom *apple = OpenCog_addConcept(opencog, "apple", 0.9f, 0.8f);
+ OCAtom *fire = OpenCog_addConcept(opencog, "fire", 0.85f, 0.75f);
+
+ TEST_ASSERT(red && apple && fire, "Learning atoms creation");
+
+ // Create associations
+ OpenCog_associateAtoms(opencog, red, apple, 0.8f);
+ OpenCog_associateAtoms(opencog, red, fire, 0.7f);
+
+ // Test that association created links
+ long atom_count = opencog->atomspace->atom_count;
+ TEST_ASSERT(atom_count > 3, "Association link creation");
+
+ // Run some attention cycles to activate hebbian learning
+ if (opencog->attention) {
+ OpenCog_boostAttention(opencog, red, 15.0f);
+ OpenCog_boostAttention(opencog, apple, 10.0f);
+
+ for (int i = 0; i < 5; i++) {
+ OpenCog_stepAttention(opencog);
+ }
+
+ TEST_ASSERT(opencog->total_attention_cycles == 5, "Hebbian learning cycles");
+ }
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test system statistics and monitoring */
+int test_system_statistics() {
+ printf("\n=== Testing System Statistics ===\n");
+
+ OpenCog *opencog = OpenCog_new(NULL);
+
+ // Add some content
+ OCAtom *cat = OpenCog_addConcept(opencog, "cat", 0.9f, 0.8f);
+ OCAtom *dog = OpenCog_addConcept(opencog, "dog", 0.85f, 0.75f);
+ OpenCog_associateAtoms(opencog, cat, dog, 0.7f);
+
+ // Test statistics retrieval
+ char stats_buffer[1000];
+ OpenCog_getStats(opencog, stats_buffer, sizeof(stats_buffer));
+
+ TEST_ASSERT(strlen(stats_buffer) > 0, "Statistics generation");
+ TEST_ASSERT(strstr(stats_buffer, "OpenCog Statistics") != NULL, "Statistics format");
+
+ printf("System Statistics:\n%s\n", stats_buffer);
+
+ // Test embedding matrix retrieval
+ OCTensor *embeddings = OpenCog_getAtomEmbeddings(opencog);
+ TEST_ASSERT(embeddings != NULL, "Embeddings matrix retrieval");
+
+ if (embeddings) {
+ TEST_ASSERT(OCTensor_size(embeddings, 0) == opencog->atomspace->atom_count,
+ "Embeddings matrix rows");
+ OCTensor_free(embeddings);
+ }
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test error handling */
+int test_error_handling() {
+ printf("\n=== Testing Error Handling ===\n");
+
+ // Test NULL pointer handling
+ OCAtom *result = OpenCog_findAtom(NULL, "test");
+ TEST_ASSERT(result == NULL, "NULL OpenCog handling");
+ TEST_ASSERT(OpenCog_getLastError() == OC_ERROR_NULL_POINTER, "NULL pointer error code");
+
+ OpenCog *opencog = OpenCog_new(NULL);
+
+ // Test atom not found
+ OCAtom *not_found = OpenCog_findAtom(opencog, "nonexistent");
+ TEST_ASSERT(not_found == NULL, "Nonexistent atom handling");
+ TEST_ASSERT(OpenCog_getLastError() == OC_ERROR_ATOM_NOT_FOUND, "Atom not found error");
+
+ // Test error string retrieval
+ const char *error_str = OpenCog_getErrorString(OC_ERROR_NULL_POINTER);
+ TEST_ASSERT(error_str != NULL && strlen(error_str) > 0, "Error string retrieval");
+
+ OpenCog_free(opencog);
+ return 1;
+}
+
+/* Test version information */
+int test_version_info() {
+ printf("\n=== Testing Version Information ===\n");
+
+ const char *version = OpenCog_getVersion();
+ TEST_ASSERT(version != NULL, "Version string retrieval");
+ TEST_ASSERT(strlen(version) > 0, "Version string non-empty");
+
+ int major = OpenCog_getVersionMajor();
+ int minor = OpenCog_getVersionMinor();
+ int patch = OpenCog_getVersionPatch();
+
+ TEST_ASSERT(major == OPENCOG_VERSION_MAJOR, "Version major number");
+ TEST_ASSERT(minor == OPENCOG_VERSION_MINOR, "Version minor number");
+ TEST_ASSERT(patch == OPENCOG_VERSION_PATCH, "Version patch number");
+
+ printf(" Version: %s (%d.%d.%d)\n", version, major, minor, patch);
+
+ return 1;
+}
+
+/* Main test runner */
+int main() {
+ printf("OpenCog Tensor Inference Engine Test Suite\n");
+ printf("==========================================\n");
+
+ int tests_passed = 0;
+ int total_tests = 0;
+
+ #define RUN_TEST(test_func) \
+ do { \
+ total_tests++; \
+ if (test_func()) { \
+ tests_passed++; \
+ } \
+ } while(0)
+
+ RUN_TEST(test_basic_atoms);
+ RUN_TEST(test_links_and_relationships);
+ RUN_TEST(test_attention_system);
+ RUN_TEST(test_similarity_computation);
+ RUN_TEST(test_inference_operations);
+ RUN_TEST(test_learning_associations);
+ RUN_TEST(test_system_statistics);
+ RUN_TEST(test_error_handling);
+ RUN_TEST(test_version_info);
+
+ printf("\n==========================================\n");
+ printf("Test Results: %d/%d passed\n", tests_passed, total_tests);
+
+ if (tests_passed == total_tests) {
+ printf("All tests PASSED!\n");
+ return 0;
+ } else {
+ printf("Some tests FAILED!\n");
+ return 1;
+ }
+}
\ No newline at end of file