# Syntactic and Semantic Modes of the Symbol Class in SymbolicAI

> Explore the syntactic and semantic modes of the Symbol class in SymbolicAI. Understand how the __semantic__ flag enables raw data processing or LLM-driven reasoning for symbolic AI.

- Repository: [ExtensityAI/symbolicai](https://github.com/extensityai/symbolicai)
- Tags: deep-dive
- Published: 2026-03-01

---

**The `Symbol` class operates in two distinct modes—syntactic (raw Python data processing) and semantic (LLM-driven neuro-symbolic reasoning)—controlled by an internal `__semantic__` flag that determines whether operations execute locally or route through the language model engine.**

The dual-mode architecture in the [extensityai/symbolicai](https://github.com/extensityai/symbolicai) repository allows developers to fluidly switch between deterministic Python execution and AI-augmented symbolic reasoning. Understanding these syntactic and semantic modes is essential for effectively leveraging the library's neuro-symbolic capabilities.

## Understanding Syntactic vs Semantic Modes

The `Symbol` class distinguishes between two operational states through an internal boolean flag:

- **Syntactic mode** (`__semantic__ = False`): The instance behaves as ordinary Python data. Arithmetic operators, string methods, and logical operations execute directly on the raw value without LLM invocation. This mode is ideal for pure data manipulation, performance-critical paths, or when deterministic behavior is required.

- **Semantic mode** (`__semantic__ = True`): The instance becomes a prompt-driven, neuro-symbolic entity. Operations are routed through the configured LLM engine, enabling natural language understanding, contextual reasoning, and AI-augmented transformations. For example, the bitwise negation operator (`~`) sends a prompt to the LLM to semantically negate a statement rather than performing bitwise inversion.

## How the Modes Are Implemented

The mode switching mechanism is implemented across three core components: the constructor flag logic in `Symbol.__new__`, the casting primitives in [`symai/ops/primitives.py`](https://github.com/extensityai/symbolicai/blob/main/symai/ops/primitives.py), and the public property interface.

### Flag Creation in `__new__`

In [`symai/symbol.py`](https://github.com/extensityai/symbolicai/blob/main/symai/symbol.py), the `Symbol` class sets the `__semantic__` flag during instance construction. When `semantic=True` is passed to the constructor and mixin primitives are enabled, the flag is activated:

```python

# symai/symbol.py (line ~395)

if use_mixin and standard_primitives and semantic:
    obj.__semantic__ = True  # Activates semantic mode

```

By default, `Symbol` instances are created in syntactic mode (`__semantic__` is not set or is `False`).

### Mode Conversion with `.syn` and `.sem`

The `CastingPrimitives` mixin (registered in [`symai/ops/primitives.py`](https://github.com/extensityai/symbolicai/blob/main/symai/ops/primitives.py)) provides two properties for runtime mode switching:

```python

# symai/ops/primitives.py (lines ~1314-1332)

@property
def syn(self) -> "Symbol":
    """Return a syntactic (non-semantic) view of this Symbol."""
    if not getattr(self, "__semantic__", False):
        return self
    return self._to_type(self.value, semantic=False)

@property
def sem(self) -> "Symbol":
    """Return a semantic view of this Symbol."""
    if getattr(self, "__semantic__", False):
        return self
    return self._to_type(self.value, semantic=True)

```

The `.syn` property returns a syntactic view by creating a new `Symbol` with `semantic=False`, while `.sem` creates a semantic view with `semantic=True`. These properties enable fluid mode switching without manual flag manipulation.

## Practical Code Examples

### Default Syntactic Behavior

Creating a `Symbol` without the `semantic` flag produces a syntactic instance suitable for standard Python operations:

```python
from symai import Symbol

s = Symbol(42)               # Syntactic mode

print(s.__semantic__)        # False

print(s + Symbol(8))         # 50 (arithmetic on raw values)

```

### Creating a Semantic Symbol

Pass `semantic=True` to enable LLM-driven operations:

```python
from symai import Symbol

s_sem = Symbol("What is the capital of France?", semantic=True)
print(s_sem.__semantic__)    # True

# The ~ operator invokes the LLM for semantic negation

negated = ~s_sem
print(negated)             # "Paris is not the capital of France."

```

### Switching Modes with Properties

Use `.sem` and `.syn` to convert between modes dynamically:

```python
from symai import Symbol

s = Symbol("apple")          # Syntactic

print(s.__semantic__)        # False

# Switch to semantic for LLM processing

s_sem = s.sem
print(s_sem.__semantic__)    # True

# Process semantically, then revert to syntactic

result = s_sem.upper()       # May use LLM for contextual upper-casing

s_back = result.syn
print(s_back.__semantic__)   # False

print(s_back + Symbol(" pie"))  # "apple pie" (syntactic concatenation)

```

## Summary

- The `Symbol` class implements a dual-mode architecture through the `__semantic__` flag, distinguishing between **syntactic** (raw Python data) and **semantic** (LLM-driven) operations.
- **Syntactic mode** is the default state where operators execute locally on raw values, providing deterministic performance without LLM overhead.
- **Semantic mode** activates neuro-symbolic capabilities, routing operations through the configured LLM engine for natural language reasoning and AI-augmented transformations.
- Mode switching is achieved through the `.sem` and `.syn` properties defined in [`symai/ops/primitives.py`](https://github.com/extensityai/symbolicai/blob/main/symai/ops/primitives.py), or by passing `semantic=True` during construction in [`symai/symbol.py`](https://github.com/extensityai/symbolicai/blob/main/symai/symbol.py).

## Frequently Asked Questions

### How do I check if a Symbol instance is in semantic mode?

Inspect the `__semantic__` attribute directly. If the attribute is `True`, the instance operates in semantic mode; otherwise, it is in syntactic mode:

```python
sym = Symbol("test", semantic=True)
print(sym.__semantic__)  # True

```

### Can I switch a Symbol from semantic to syntactic mode without creating a new instance?

The `.syn` property returns a syntactic view, which may be the same instance if already syntactic, or a new `Symbol` with `semantic=False` if converting from semantic mode. The original instance remains unchanged; mode conversion creates a new view rather than mutating the existing object.

### What happens to operators like `+` or `~` when a Symbol is in semantic mode?

In syntactic mode, `+` performs standard arithmetic or string concatenation on the raw value. In semantic mode, operators are overloaded to route through the LLM engine. For example, the bitwise negation operator `~` sends a prompt to the LLM to semantically negate the statement rather than performing bitwise inversion on the value.

### Is there a performance difference between syntactic and semantic modes?

Yes. Syntactic mode executes native Python operations with minimal overhead, suitable for performance-critical paths. Semantic mode incurs latency from LLM API calls or local model inference, making it appropriate for complex reasoning tasks where AI augmentation justifies the computational cost.