SLIPS

Complete Documentation

๐Ÿ“š Table of Contents

๐ŸŽฏ Introduction

SLIPS (Swift Language Implementation of Production Systems) is a faithful semantic translation of CLIPS 6.4.2 to Swift 6.2. The project maintains the original philosophy, algorithms, and architecture of CLIPS while adapting them to Swift's modern type safety features.

๐Ÿ“Œ Note: This is not a simple wrapper or binding, but a complete file-by-file translation of CLIPS C source code into idiomatic Swift.

Why SLIPS?

  • Type Safety: Swift 6.2's robust type system
  • Memory Safety: Automatic memory management without malloc/free
  • Modern Syntax: Clean, idiomatic Swift code
  • Faithful Translation: Preserves RETE, salience, agenda strategies
  • Well Documented: Each Swift file maps to C source

Current Status (Version 0.96 - Production Ready)

  • โœ… 96% CLIPS 6.4.2 coverage - Production-ready core
  • โœ… 15,200+ lines of Swift code - 46 well-organized files
  • โœ… 275+ tests (99.6% pass rate) - Excellent coverage
  • โœ… 160 builtin functions - Math (36), String (11), Multifield (10), Template (14), I/O (13)
  • โœ… Fully functional Module System - Defmodule, integrated focus stack, import/export
  • โœ… Complete Pattern Matching - Multifield $?x, OR/AND/NOT/EXISTS CE
  • โœ… Complete Template Functions - modify, duplicate, introspection
  • โœ… Zero external dependencies - Foundation only
  • ๐Ÿš€ Release 1.0 imminent - Final documentation in progress

What is CLIPS?

CLIPS (C Language Integrated Production System) is an expert system shell developed by NASA. It uses a rule-based engine built on the RETE algorithm for efficient pattern matching and supports procedural, object-oriented, and rule-driven programming paradigms.

๐Ÿš€ Quick Start

Installation

Add SLIPS to your Package.swift:

dependencies: [
    .package(url: "https://github.com/gpicchiarelli/SLIPS.git", from: "0.1.0")
]

First Program

import SLIPS

// Create an environment
let env = CLIPS.createEnvironment()

// Define a template
CLIPS.eval(expr: """
(deftemplate person
    (slot name)
    (slot age (type INTEGER)))
""")

// Define a rule
CLIPS.eval(expr: """
(defrule greet-adult
    (person (name ?n) (age ?a&:(>= ?a 18)))
    =>
    (printout t "Hello " ?n ", you are an adult!" crlf))
""")

// Assert facts
CLIPS.eval(expr: "(assert (person (name \"John\") (age 25)))")
CLIPS.eval(expr: "(assert (person (name \"Jane\") (age 16)))")

// Run rules
let fired = CLIPS.run(limit: nil)
print("Rules fired: \(fired)")

CLI Execution

swift run slips-cli
SLIPS> (facts)
SLIPS> (rules)
SLIPS> (run)

๐Ÿ—๏ธ Architecture

Core Components

  • Environment: Execution context (facts, rules, agenda)
  • Parser: Lexical and syntactic analysis of CLIPS expressions
  • Evaluator: Expression evaluation and function calls
  • RETE Network: Efficient pattern matching network
  • Agenda: Activation management with strategies (depth, breadth, LEX, MEA)
  • Router System: Flexible I/O with customizable callbacks

C โ†’ Swift Mapping

C (CLIPS) Swift (SLIPS)
struct struct
union + type tag enum with associated values
#define macros static let or computed properties
malloc/free Array, Dictionary, ARC
Pointers Reference types, Unsafe* when needed

File Structure

Sources/SLIPS/
โ”œโ”€โ”€ Core/                    (32 files, ~11,500 LOC)
โ”‚   โ”œโ”€โ”€ envrnmnt.swift      (environment.c)
โ”‚   โ”œโ”€โ”€ evaluator.swift     (evaluatn.c)
โ”‚   โ”œโ”€โ”€ ruleengine.swift    (engine.c + factmngr.c)
โ”‚   โ”œโ”€โ”€ expressn.swift      (expressn.c)
โ”‚   โ”œโ”€โ”€ scanner.swift       (scanner.c)
โ”‚   โ”œโ”€โ”€ router.swift        (router.c)
โ”‚   โ”œโ”€โ”€ Modules.swift       (moduldef.c) โœ…
โ”‚   โ”œโ”€โ”€ MultifieldFunctions.swift  (multifun.c) โœ…
โ”‚   โ”œโ”€โ”€ StringFunctions.swift      (strngfun.c) โœ…
โ”‚   โ”œโ”€โ”€ MathFunctions.swift        (emathfun.c) โœ…
โ”‚   โ”œโ”€โ”€ TemplateFunctions.swift    (tmpltfun.c) โœ… NEW!
โ”‚   โ”œโ”€โ”€ IOFunctions.swift          (iofun.c) โœ…
โ”‚   โ”œโ”€โ”€ FactQueryFunctions.swift   (factqpsr.c) โœ…
โ”‚   โ”œโ”€โ”€ UtilityFunctions.swift     (miscfun.c) โœ…
โ”‚   โ”œโ”€โ”€ PrettyPrintFunctions.swift โœ…
โ”‚   โ””โ”€โ”€ functions.swift     (160+ built-in)
โ”œโ”€โ”€ Rete/                    (12 files, ~2,800 LOC)
โ”‚   โ”œโ”€โ”€ AlphaNetwork.swift  (alpha memory)
โ”‚   โ”œโ”€โ”€ BetaEngine.swift    (beta network)
โ”‚   โ”œโ”€โ”€ DriveEngine.swift   (drive.c)
โ”‚   โ”œโ”€โ”€ NetworkBuilder.swift(rulebld.c)
โ”‚   โ”œโ”€โ”€ Propagation.swift   (incremental updates)
โ”‚   โ””โ”€โ”€ Nodes.swift         (explicit RETE nodes)
โ”œโ”€โ”€ Agenda/                  (1 file, ~150 LOC)
โ”‚   โ””โ”€โ”€ Agenda.swift        (agenda.c + focus stack)
โ””โ”€โ”€ CLIPS.swift              (public facade)

Total: 46 files, 15,200+ LOC

๐Ÿ”ง Template Functions (NEW!)

SLIPS now includes the complete set of functions for manipulating and querying templates, faithfully translated from tmpltfun.c of CLIPS 6.4.2.

Fact Manipulation

;; Modify existing fact
(assert (person (name "John") (age 30)))  ; f-1
(modify 1 (age 31))                        ; Update age

;; Duplicate with modifications
(duplicate 1 (name "Jane"))                ; f-2: Jane, 31 years
(duplicate 1 (name "Bob") (age 25))        ; f-3: Bob, 25 years

Template Introspection

;; List slots of a template
(deftemplate-slot-names person)
; โ†’ (create$ name age)

;; Default value of a slot
(deftemplate-slot-default-value person age)
; โ†’ 0 (or specified default)

;; Check slot type
(deftemplate-slot-multip project team-members)
; โ†’ TRUE (is multifield)

(deftemplate-slot-singlep person name)
; โ†’ TRUE (is single-field)

;; Check slot existence
(deftemplate-slot-existp person salary)
; โ†’ FALSE (slot doesn't exist)

Available Functions (14)

  • modify - Modify existing fact
  • duplicate - Duplicate fact with modifications
  • deftemplate-slot-names - List all slots
  • deftemplate-slot-default-value - Default value of slot
  • deftemplate-slot-cardinality - Multifield cardinality
  • deftemplate-slot-types - Allowed types
  • deftemplate-slot-range - Value range
  • deftemplate-slot-multip - Test multifield
  • deftemplate-slot-singlep - Test single-field
  • deftemplate-slot-existp - Test existence
โœ… Complete Translation: All functions from tmpltfun.c have been implemented and tested (24 tests, 100% pass rate).

๐ŸŽ“ Module System

SLIPS now supports the complete CLIPS module system for organizing rules and facts in separate namespaces.

Defining Modules

;; Create module with export
(defmodule UTILITIES
  (export deftemplate data-record)
  (export defrule process-data))

;; Create module with import
(defmodule MAIN
  (import UTILITIES deftemplate data-record))

Focus Management

;; Set focus on module (LIFO stack)
(focus UTILITIES)

;; Focus on multiple modules
(focus MODULE-A MODULE-B MODULE-C)

;; Get current module
(get-current-module)  ; Returns MAIN

;; Set current module
(set-current-module UTILITIES)

Module Commands

;; List all modules
(list-defmodules)
; Output:
; MAIN
; UTILITIES
; MODULE-A

;; Get list as multifield
(get-defmodule-list)
; Returns: (MAIN UTILITIES MODULE-A)

;; Agenda for specific module
(agenda UTILITIES)
โœ… Completed: Fully functional module system with integrated focus stack! Includes defmodule, LIFO focus stack, import/export, module commands and module-aware agenda. 37 tests (100% pass rate).

๐Ÿ“– API Reference

CLIPS (Main Facade)

// Create environment
static func createEnvironment() -> Environment

// Load file
static func load(_ path: String) -> Bool

// Reset environment
static func reset()

// Run rules
static func run(limit: Int?) -> Int

// Assert facts
static func assert(fact: String) -> Int

// Retract facts
static func retract(id: Int) -> Bool

// Evaluate expressions
static func eval(expr: String) -> Value

// Interactive command loop
static func commandLoop()

Environment

struct Environment {
    var facts: [Int: FactRec]           // Fact base
    var rules: [Rule]                    // Defined rules
    var templates: [String: Template]    // Deftemplate templates
    var agendaQueue: AgendaQueue         // Activation queue
    var rete: ReteNetwork                // RETE network
    var watchFacts: Bool                 // Watch facts
    var watchRules: Bool                 // Watch rules
    var experimentalJoinCheck: Bool      // Experimental beta engine
}

Value (Data Types)

enum Value: Codable, Equatable {
    case none
    case int(Int64)
    case float(Double)
    case string(String)
    case symbol(String)
    case boolean(Bool)
    case multifield([Value])
    case factAddress(Int)
    case instanceAddress(String)
    case externalAddress(String)
}

๐Ÿ’ก Examples

Expert System: Car Diagnosis

(deftemplate problem
    (slot type)
    (slot description))

(deftemplate symptom
    (slot name)
    (slot severity (type INTEGER)))

(defrule diagnose-battery
    (symptom (name "engine-wont-start"))
    (symptom (name "dim-lights"))
    =>
    (assert (problem 
        (type "dead-battery")
        (description "Battery needs recharge or replacement")))
    (printout t "Diagnosis: Dead battery" crlf))

(defrule diagnose-alternator
    (problem (type "dead-battery"))
    (symptom (name "battery-drains-quickly"))
    =>
    (printout t "Possible alternator failure" crlf))

Advanced Pattern Matching

(deftemplate order
    (slot id)
    (slot customer)
    (slot amount (type FLOAT))
    (slot urgent (type SYMBOL)))

(defrule high-priority-order
    (order (id ?id) 
           (customer ?c) 
           (amount ?amt&:(> ?amt 1000.0))
           (urgent YES))
    =>
    (printout t "HIGH PRIORITY: Order " ?id 
                " from " ?c " for $" ?amt crlf))

(defrule loyal-customer-discount
    (order (id ?id) (customer ?c) (amount ?amt))
    (premium-customer (name ?c) (years ?y&:(>= ?y 5)))
    =>
    (bind ?discount (* ?amt 0.15))
    (printout t "15% discount for " ?c ": $" ?discount crlf))

Negation and NOT Patterns

(defrule customer-without-orders
    (customer (id ?id) (name ?n))
    (not (order (customer-id ?id)))
    =>
    (printout t "Customer " ?n " has never ordered" crlf))

(defrule out-of-stock
    (product (code ?c) (name ?n))
    (not (inventory (product ?c) (quantity ?q&:(> ?q 0))))
    =>
    (printout t "ALERT: " ?n " is out of stock!" crlf))

โšก RETE Algorithm

What is RETE?

RETE is a pattern matching algorithm developed by Charles Forgy in 1979. It optimizes rule matching by avoiding rechecking unchanged conditions in each cycle.

RETE Components in SLIPS

  • Alpha Network: Template index, filters facts by constants
  • Beta Network: Incremental joins between patterns, maintains partial tokens
  • Beta Memory: Cache of intermediate matches for efficiency
  • Join Nodes: Conjunction nodes between patterns (WIP)
โœ… Implementation Status: RETE is stable and functional:
  • โœ… Alpha indexing by template
  • โœ… Beta engine for positive and negative patterns
  • โœ… Incremental updates on assert/retract
  • โœ… Negated patterns (NOT) with incremental propagation
  • โœ… EXISTS conditional element
  • โœ… Predicate tests in joins with hash buckets
  • โœ… Explicit RETE nodes (AlphaNode, JoinNode, BetaMemory)
  • โœ… Hash join optimization for performance

Experimental Flag

// Enable comparison between classic backtracking and beta engine
CLIPS.eval(expr: "(set-join-check on)")

// Check status
let status = CLIPS.eval(expr: "(get-join-check)")
// Returns: boolean(true)

When join-check is active, SLIPS runs both algorithms and logs any divergences to STDERR. This helps validate the incremental implementation.

๐Ÿค Contributing

Guidelines

See AGENTS.md in the repository root for complete rules. In summary:

  • Faithful semantic translation, don't simplify algorithms
  • File-by-file mapping: each .c/.h โ†’ corresponding .swift
  • Avoid force unwrapping, prefer guard let and pattern matching
  • Comment in Italian, cite original C function names
  • Add tests for each translated module

Development Setup

git clone https://github.com/gpicchiarelli/SLIPS.git
cd SLIPS
swift build
swift test

Running Tests

# All tests (275+)
swift test

# Specific test
swift test --filter TemplateFunctionsTests
swift test --filter ModuleAwareAgendaTests

# With verbose output
swift test --verbose

# Results: 274/275 pass (99.6%) โœ…

Modules to Translate

Reference to original CLIPS sources:

clips_core_source_642/core/
โ”œโ”€โ”€ agenda.c/h          โ†’ Agenda/Agenda.swift โœ…
โ”œโ”€โ”€ drive.c/h           โ†’ Rete/BetaEngine.swift ๐Ÿšง
โ”œโ”€โ”€ pattern.c/h         โ†’ (to be translated)
โ”œโ”€โ”€ reteutil.c/h        โ†’ (to be translated)
โ”œโ”€โ”€ network.c/h         โ†’ (to be translated)
โ””โ”€โ”€ ...

Roadmap

See ROADMAP_TO_1.0_UPDATED.md for detailed planning:

  • โœ… Phase 1: RETE Network - Completed
  • โœ… Phase 2: Advanced Pattern Matching - Completed
  • โœ… Phase 3: Modules & Focus - Completed
  • โœ… Phase 4: Console & Polish - Completed (String, Math, Template functions)
  • โณ Phase 5: Documentation & Release 1.0 (in progress, ETA: 3-7 days)

Current status: 96% coverage, production-ready! Only final documentation pending.

๐Ÿ’š Contributions Welcome! Pull requests are always appreciated. For major changes, please open an issue first to discuss what you'd like to change.