SLIPS API

Complete Reference

Index

CLIPS (Public Facade)

The main class for interacting with SLIPS.

createEnvironment()

static func createEnvironment() -> Environment

Creates and initializes a new SLIPS environment.

let env = CLIPS.createEnvironment()

load(_:)

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

Loads and executes a CLIPS file.

let success = CLIPS.load("rules.clp")

eval(expr:)

static func eval(expr: String) -> Value

Evaluates a CLIPS expression and returns the result.

let result = CLIPS.eval(expr: "(+ 2 3)")
// result: .int(5)

reset()

static func reset()

Resets the current environment, removing facts but keeping rules and templates.

run(limit:)

static func run(limit: Int?) -> Int

Executes rules in the agenda. Returns the number of fired rules.

let fired = CLIPS.run(limit: nil)  // Run all
let fired = CLIPS.run(limit: 10)   // Run max 10

assert(fact:)

static func assert(fact: String) -> Int

Asserts a fact, returns its ID.

let id = CLIPS.assert(fact: "(person (name \"John\") (age 30))")

retract(id:)

static func retract(id: Int) -> Bool

Removes a fact from the environment.

CLIPS.retract(id: 1)

commandLoop()

static func commandLoop()

Starts an interactive REPL.

CLIPS.commandLoop()
// SLIPS> (facts)
// SLIPS> (run)

Environment

Execution context that maintains system state.

Structure

public struct Environment {
    var facts: [Int: FactRec]
    var rules: [Rule]
    var templates: [String: Template]
    var agendaQueue: AgendaQueue
    var rete: ReteNetwork
    var localBindings: [String: Value]
    var globalBindings: [String: Value]
    var functionTable: [String: FunctionDefinitionSwift]
    var watchFacts: Bool
    var watchRules: Bool
    var experimentalJoinCheck: Bool
}

FactRec

public struct FactRec {
    let id: Int
    let name: String
    var slots: [String: Value]
}

Template

public struct Template {
    let name: String
    var slots: [String: SlotDefinition]
}

public struct SlotDefinition {
    let name: String
    let isMultifield: Bool
    let defaultType: DefaultType
    var defaultStatic: Value?
    var defaultDynamicExpr: ExpressionNode?
    var constraints: SlotConstraints?
}

Value

Represents data types in SLIPS.

Enum

public 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

let v1 = Value.int(42)
let v2 = Value.string("hello")
let v3 = Value.symbol("ok")
let v4 = Value.boolean(true)
let v5 = Value.multifield([.int(1), .int(2), .int(3)])

Conversions

// Swift to Value
func toValue(_ x: Int) -> Value { .int(Int64(x)) }
func toValue(_ x: Double) -> Value { .float(x) }
func toValue(_ x: String) -> Value { .string(x) }
func toValue(_ x: Bool) -> Value { .boolean(x) }

// Value to Swift
if case .int(let i) = value { print(i) }
if case .string(let s) = value { print(s) }

Rule & Pattern

Rule

public struct Rule {
    let name: String
    let patterns: [Pattern]
    let rhs: [ExpressionNode]
    let salience: Int
    let tests: [ExpressionNode]
}

Pattern

public struct Pattern {
    let name: String
    let slots: [String: PatternTest]
    let negated: Bool
}

public struct PatternTest {
    public enum Kind {
        case constant(Value)
        case variable(String)
        case predicate(ExpressionNode)
    }
    let kind: Kind
}

Agenda

Manages the rule activation queue.

AgendaQueue

public struct AgendaQueue {
    var strategy: Strategy = .depth
    
    mutating func add(_ activation: Activation)
    mutating func next() -> Activation?
    mutating func clear()
    func contains(_ act: Activation) -> Bool
    mutating func setStrategy(_ s: Strategy)
}

Strategy

public enum Strategy: String {
    case depth      // New activations at front
    case breadth    // New activations at back
    case lex        // By salience, then recency
    case mea        // By salience, then age
}

Activation

public struct Activation {
    let priority: Int            // salience
    let ruleName: String
    var bindings: [String: Value]?
    var factIDs: Set = []
    var timestamp: Int = 0
}

Usage

// Set strategy
CLIPS.eval(expr: "(set-strategy lex)")

// Check current strategy
let strategy = CLIPS.eval(expr: "(get-strategy)")
// Returns: .symbol("lex")

Router

Flexible I/O system with customizable callbacks.

Constants

public enum Router {
    public static let STDOUT = "stdout"
    public static let STDERR = "stderr"
    public static let STDIN = "stdin"
}

Functions

// Write to a router
public static func WriteString(
    _ env: inout Environment,
    _ logicalName: String,
    _ str: String
)

// Write with newline
public static func Writeln(
    _ env: inout Environment,
    _ str: String
)

// Add callback
public static func AddCallback(
    _ env: inout Environment,
    name: String,
    priority: Int,
    callback: @escaping (inout Environment, String, String) -> Bool
)

Custom Router Example

var buffer: [String] = []

Router.AddCallback(&env, name: "buffer", priority: 20) { _, _, text in
    buffer.append(text)
    return true
}

CLIPS.eval(expr: "(printout buffer \"Test\" crlf)")
print(buffer)  // ["Test\n"]

Evaluator

Evaluates expressions and executes functions.

Main Functions

public enum Evaluator {
    public static func EvaluateExpression(
        _ env: inout Environment,
        _ node: ExpressionNode
    ) -> Value
    
    public static func eval(
        _ env: inout Environment,
        _ node: ExpressionNode
    ) throws -> Value
}

ExpressionNode

public final class ExpressionNode {
    public enum NodeType {
        case fcall, integer, float, string
        case symbol, boolean
        case variable, mfVariable
        case gblVariable, mfGblVariable
        case instanceName
    }
    
    public var type: NodeType
    public var value: ValueHolder?
    public var argList: ExpressionNode?
    public var nextArg: ExpressionNode?
}

Built-in Functions (160 functions)

Mathematical Operators (15):

  • +, -, *, /
  • =, <>, <, <=, >, >=
  • and, or, not, eq, neq

Math Functions (36):

  • Trigonometric: sin, cos, tan, sec, csc, cot
  • Inverse: asin, acos, atan, atan2, asec, acsc, acot
  • Hyperbolic: sinh, cosh, tanh, sech, csch, coth
  • Inverse hyperbolic: asinh, acosh, atanh, asech, acsch, acoth
  • Exponential: exp, log, log10, sqrt, **
  • Utility: abs, mod, round, pi, deg-rad, rad-deg

String Functions (11):

  • str-cat, sym-cat - Concatenation
  • str-length, str-byte-length - Length
  • upcase, lowcase - Case conversion
  • sub-string, str-index - Manipulation
  • str-replace, str-compare - Operations
  • string-to-field - Parsing

Multifield Functions (10):

  • nth$, length$, first$, rest$
  • subseq$, member$, insert$, delete$
  • explode$, implode$

Template Functions (14) ๐Ÿ†•:

  • modify, duplicate - Fact manipulation
  • deftemplate-slot-names - List slots
  • deftemplate-slot-default-value - Default value
  • deftemplate-slot-cardinality - 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

I/O Functions (13):

  • read, readline, read-number, get-char
  • printout, print, println, put-char
  • open, close, flush, remove, rename

Fact Query Functions (7):

  • find-fact, find-all-facts
  • do-for-fact, do-for-all-facts
  • any-factp, fact-existp, fact-index

Utility Functions (6):

  • gensym, gensym* - Symbol generation
  • random, seed - Random numbers
  • time - Timestamp
  • funcall - Dynamic call

Module Functions (6):

  • defmodule - Define module
  • focus - Set focus
  • get-current-module, set-current-module
  • list-defmodules, get-defmodule-list

Pretty Print Functions (4):

  • ppdefmodule, ppdeffacts
  • ppdefrule, ppdeftemplate

Core Constructs:

  • deftemplate, deffacts, defrule
  • assert, retract
  • bind, printout, progn
  • facts, rules, agenda
  • watch, unwatch
  • reset, clear, run
  • set-strategy, get-strategy

See FUNZIONI_REFERENCE.md for complete documentation of all 160 functions.

Template Functions API ๐Ÿ†•

modify

(modify <fact-id> (<slot-name> <value>)*)

; Example
(modify 1 (age 31) (city "Rome"))

Modifies one or more slots of an existing fact. Returns the new fact-id.

duplicate

(duplicate <fact-id> (<slot-name> <value>)*)

; Example
(duplicate 1 (name "Copy") (age 25))

Duplicates a fact with optional slot modifications. Returns the new fact-id.

deftemplate-slot-names

(deftemplate-slot-names <template-name>)

; Example
(deftemplate-slot-names person)
; Returns: (create$ name age city)

Returns a multifield with the names of all template slots.

deftemplate-slot-default-value

(deftemplate-slot-default-value <template-name> <slot-name>)

; Example
(deftemplate-slot-default-value person age)
; Returns: 0 (or specified default)

Returns the default value of a slot.

deftemplate-slot-multip / deftemplate-slot-singlep

(deftemplate-slot-multip <template-name> <slot-name>)
(deftemplate-slot-singlep <template-name> <slot-name>)

; Example
(deftemplate-slot-multip project team-members)
; Returns: TRUE

(deftemplate-slot-singlep person name)
; Returns: TRUE

Check whether a slot is multifield or single-field respectively.

deftemplate-slot-existp

(deftemplate-slot-existp <template-name> <slot-name>)

; Example
(deftemplate-slot-existp person salary)
; Returns: FALSE (if slot doesn't exist)

Checks if a slot exists in the template.

Custom Functions

FunctionDefinitionSwift

public final class FunctionDefinitionSwift {
    public let name: String
    public let impl: (inout Environment, [Value]) throws -> Value
}

Registration

var env = CLIPS.createEnvironment()

env.functionTable["square"] = FunctionDefinitionSwift(
    name: "square"
) { _, args in
    guard let arg = args.first,
          case .int(let i) = arg else {
        return .none
    }
    return .int(i * i)
}

// Usage
CLIPS.eval(expr: "(printout t (square 7) crlf)")
// Output: 49