Implementing Neuro-Symbolic Reasoning on the Edge
Loxation Team
- 11 minutes read - 2144 wordsImplementing Neuro-Symbolic Reasoning on the Edge
How we built a fuzzy description logic reasoner in Rust, paired it with a local LLM, and shipped a neuro-symbolic stack that runs entirely on-device.
Neural networks are remarkably good at pattern recognition. They can classify images, transcribe speech, and generate plausible text. But ask a neural network why it arrived at a conclusion, and you get silence. Ask it to guarantee it won’t contradict a known medical fact, and you get a shrug. For applications where correctness, explainability, and domain knowledge matter — healthcare, child safety, trust scoring — pattern matching alone isn’t enough.
This is where neuro-symbolic AI enters the picture: combining the perceptual strength of neural models with the logical rigor of symbolic reasoning. And increasingly, the most interesting place to run these hybrid systems isn’t in the cloud. It’s on the device in your hand.
We built DEALER — a Description Logic reasoner implementing the OWL 2 EL++ profile with fuzzy extensions — specifically to bring formal ontological reasoning to edge devices. Written in Rust, it compiles to native code on iOS, Android, macOS, and Linux, runs saturation-based classification in milliseconds, and exposes a C FFI that any mobile framework can call. In Loxation, our decentralized messaging app, DEALER runs alongside a Rust-based graph database (Rukuzu) and Apple’s on-device Foundation Models to form a complete neuro-symbolic pipeline — one where the LLM speaks natural language, the reasoner enforces formal logic, and the graph database holds the ground truth. All of it on the phone. None of it touches a server.
Here’s what we learned building it.
Why the Edge?
The standard architecture for intelligent applications is to ship data to a cloud endpoint, run inference, and return results. This works — until it doesn’t. Three constraints push reasoning to the device.
Latency. A trust classifier that takes 800ms to round-trip to a server makes a real-time chat app feel sluggish. The same reasoning running locally in 0.3ms feels invisible. When you’re scoring every contact in a mesh network as peers connect and disconnect, the difference between cloud and local is the difference between reactive and interactive.
Privacy. Encrypted messages, behavioral patterns, and social graphs are exactly the kind of information you don’t want leaving the device. Loxation uses end-to-end encryption (Noise Protocol for 1:1, MLS for groups) — sending decrypted content to a cloud AI would defeat the entire security model. On-device reasoning means the data never crosses a network boundary. The ontology ships as a downloadable asset. The personal facts stay local.
Availability. Edge devices go offline. Bluetooth mesh networks exist specifically because internet connectivity isn’t guaranteed. A reasoner that works without a network connection isn’t a nice-to-have; it’s a requirement.
The Architecture: EL++ Saturation in Rust
DEALER implements the EL++ fragment of OWL 2, the same profile targeted by the ELK reasoner in the Java ecosystem. EL++ is expressive enough to represent the SNOMED CT medical ontology (over 350,000 concepts) while remaining tractable — classification is polynomial in the size of the ontology.
The reasoning algorithm is saturation-based. Every named concept gets a context — a set of concepts it’s known to be subsumed by. The reasoner applies completion rules (CR1 through CR9) that propagate subsumption relationships until no new inferences can be drawn. At fixpoint, you can read off the full subsumption hierarchy.
The system is structured as a pipeline of seven Rust crates:
parser → normalizer → reasoner → taxonomy
↑ ↑
core (shared types) store / CLI
Parsing handles OWL 2 Functional Syntax with a hand-written recursive descent parser — no parser generator dependencies, no runtime allocation for the grammar. Normalization decomposes arbitrary axioms into eight normal forms (NF1–NF8), allocating fresh concept names where needed. Reasoning runs the saturation loop. Taxonomy extracts the final DAG with equivalence classes and performs transitive reduction to get direct parent/child edges.
Every identifier — concepts, roles, IRIs — is interned as an integer handle. ConceptId(0) is always owl:Thing, ConceptId(1) is always owl:Nothing. Hash maps use FxHashMap (the same hash function used inside the Rust compiler) for performance. The entire pipeline is zero-copy where possible and allocation-conscious throughout.
Fuzzy Reasoning: When Certainty Is a Spectrum
Classical description logic deals in absolutes: either a contact is trusted or isn’t. But real-world signals are rarely that clean. A peer might have some mutual connections but an unusual messaging pattern. A patient might present with symptoms that partially match a condition.
DEALER extends EL++ with fuzzy degree support. Every axiom can carry a degree between 0.0 and 1.0, and the reasoner propagates these degrees through the saturation process using configurable triangular norms (t-norms).
Three t-norms are built in:
- Zadeh (Gödel): conjunction is
min(a, b), the conservative choice. A conclusion is only as strong as the weakest premise. - Łukasiewicz: conjunction is
max(0, a + b - 1), which penalizes the accumulation of uncertain evidence more aggressively. - Crisp: all degrees are 1.0. This compiles down to classical EL++ with zero overhead — the compiler eliminates all degree-tracking code paths through monomorphization.
The t-norm is a type parameter on the Reasoner<T> struct, so the compiler generates specialized code for each variant. When you’re running a crisp ontology, you pay nothing for the fuzzy machinery. When you need fuzzy degrees — for trust scoring, clinical classification, or graded assessment — you get them with the same saturation algorithm.
The Reference Implementation: Loxation’s Three-Layer Stack
Theory is cheap. What does neuro-symbolic reasoning on the edge actually look like in production? In Loxation, we run three systems in concert — each doing what it’s best at, all on-device, all offline-capable.
Layer 1: Rukuzu (Graph Database). A Rust-based graph database stores the ground truth: who has messaged whom, how often, which groups they share, which contacts are mutual favorites, who’s blocked. Cypher queries extract behavioral signals — message frequency over 7 and 30 days, initiation ratios, shared group membership. Rukuzu also handles formula evaluation for survey scoring, using SIMD-optimized vector dot products (NEON on Apple Silicon, AVX2 on x86) to compute composite personality dimensions from answer vectors.
Layer 2: DEALER (Fuzzy Reasoner). The OWL ontology defines what the signals mean. Eighteen behavioral signals — Favorited, MutualFavorite, FrequentContact7d, IsolatedContact, FrequencyAccelerating, and so on — are asserted as class memberships for each peer. DEALER’s saturation propagates these through the trust ontology, producing inferred categories (HighTrust, LowTrust, GroomingRisk, StrangerDanger) with fuzzy degree scores. The trust score is computed from the degree: floor + degree × (ceiling − floor) within the category’s band.
Layer 3: Apple Foundation Models (Local LLM). On iOS 26+, Apple’s on-device language model provides the conversational interface. It can’t see the raw messages or the graph directly — instead, it has access to tools that query the graph and the reasoner on its behalf. AnalyzeContactTool retrieves a contact’s trust score, message frequency, and behavioral flags. FlaggedContactsSearchTool identifies contacts with low trust, frequency acceleration, or social isolation. The LLM synthesizes these structured results into natural language explanations for a parent reviewing their child’s contacts.
The data flow looks like this:
Behavioral signals (collected from Rukuzu graph queries)
↓
DEALER fuzzy reasoner (EL++ saturation → trust categories + risk flags)
↓
Rukuzu graph (cached trust scores, communication patterns)
↓
Tool providers (structured queries for the LLM)
↓
Foundation Models (on-device LLM → natural language response)
↓
GraphAssistantView (conversational UI, FaceID-gated)
Each layer does one thing well. The graph stores facts. The reasoner draws conclusions. The LLM explains them. No layer tries to do another’s job.
Incremental Classification: 0.3ms Per Peer
The key to making this stack feel responsive is DEALER’s incremental ABox reasoning. The TBox — the general trust ontology — is classified once at app startup. After that, classifying a new peer takes roughly 0.3 milliseconds: reset the ABox to the TBox checkpoint, assert the peer’s signals, and saturate.
The FFI layer exposes this as straightforward C calls:
dealer_reasoner_reset_abox(reasoner); // restore TBox-only state
dealer_reasoner_add_class_assertion(reasoner, // assert: this peer is Favorited
concept_iri, individual_iri, degree);
dealer_reasoner_individual_labels(reasoner, iri); // query: what categories apply?
Because saturation is monotonic — labels and edges only grow, never shrink — existing contexts remain valid after each incremental assertion. Only the new facts and their downstream effects are processed.
In Loxation’s trust UI, this means the slider on the Signals page gives near-instantaneous feedback. Drag a contact’s explicit trust level, and the bidirectional propagation — through their shared groups, to other group members — ripples through the graph and the reasoner in real time. Nodes visibly shift between trust rings as you adjust.
Concurrency: Saturating Large Ontologies in Parallel
Edge devices are multi-core. Even a phone has 6–8 cores. DEALER’s parallel saturation follows the ELK concurrency model, adapted for Rust’s ownership system.
Each concept’s context is wrapped in a slot with a parking_lot::RwLock for data access and an AtomicBool for exclusive processing rights. Workers compete to acquire contexts from a shared activation queue, apply completion rules, and push inferences across contexts (triggering re-activation of the target).
Quiescence detection uses monotonic counter pairs: count_activated and count_deactivated are only ever incremented, never decremented. The system is quiescent when both counters are equal and the activation queue is empty. This avoids the subtle bugs that plague decrement-based active counters, where a race between decrement and re-activation can cause premature termination.
Workers use crossbeam_utils::Backoff with 50-microsecond park timeouts instead of busy-waiting — critical on battery-powered devices where spinning cores drain power. The parallel path activates automatically for ontologies with 1,000 or more concepts; smaller ones run sequentially to avoid thread-pool overhead.
Ontologies as Downloadable Intelligence
One of the most underappreciated advantages of this architecture is that the scoring logic lives in OWL files, not compiled code.
Loxation’s trust ontology defines how behavioral signals combine into trust categories. The survey system uses separate OWL ontologies for MBTI, Big Five, clinical assessments — each downloaded from a CDN alongside its survey definition. Update the ontology on the server, and every device picks up the new scoring logic on its next sync. No app store review. No recompilation. No coordinated release.
This is what “push nonlinearity into the ontology” means in practice. Interaction effects between signals, conditional risk logic, severity thresholds — all of it is encoded as axioms that DEALER’s saturation engine knows how to propagate. The host app (Swift, in this case) is a thin orchestrator: it gathers signals, feeds them to the reasoner, and renders the results.
What We Learned
The LLM needs guardrails, not freedom. A language model with direct access to a social graph and message history is a liability. By interposing structured tools between the LLM and the data, we control exactly what information flows in each direction. The LLM never sees raw messages — it sees trust scores, behavioral flags, and aggregate statistics. The reasoner’s formal conclusions become the ground truth that the LLM explains, not the other way around.
ID spaces are treacherous. Concepts, roles, and IRIs all get interned as integers, but they live in independent numbering schemes. Converting between them (RoleId(iri_id.0)) produces silent, catastrophic bugs. Loxation has its own version of this problem: DeviceID vs. PeerID are different identity domains with different lifetimes and scopes. Strong newtypes and explicit maps between ID spaces are non-negotiable.
Test at every layer. A bug that doesn’t reproduce at the reasoner level may live in the FFI wiring — a stale counter, a wrong ID mapping, a checkpoint that forgot to save a new lookup table. We maintain tests at the Rust API level, the C FFI level, and the Swift integration level. The bugs we’ve caught have been roughly evenly distributed across all three.
Graceful degradation matters. Not every device runs iOS 26. Not every device has Apple Intelligence enabled. Loxation’s GraphAssistantView falls back from Foundation Models to keyword-based tool dispatch on older devices. The reasoner and graph database work identically regardless — the LLM is the presentation layer, not the logic layer. Stripping it away degrades the UX, not the correctness.
Where This Goes
The neuro-symbolic stack on the edge is converging. On-device language models are shipping as OS features. Formal reasoners written in systems languages compile to compact, fast binaries. Embedded graph databases provide the structured memory that both systems need.
The architecture we’ve landed on — graph for facts, reasoner for logic, LLM for language — feels like a pattern that will generalize beyond messaging and trust scoring. Clinical decision support, industrial safety monitoring, educational assessment, accessibility tools — anywhere you need conclusions that are both explainable and uncertainty-aware, and where the data is too sensitive or the environment too unreliable for cloud inference.
The ontology is the interface between the neural and the symbolic. It defines what observations mean, how they combine, and which conclusions follow. The reasoner enforces the logic. The LLM makes it conversational. And it all runs in your pocket, offline, in milliseconds.
DEALER is open-source under the MIT license. Loxation is built by Loxation LLC.