Complete Reference
The main class for interacting with SLIPS.
static func createEnvironment() -> Environment
Creates and initializes a new SLIPS environment.
let env = CLIPS.createEnvironment()
static func load(_ path: String) -> Bool
Loads and executes a CLIPS file.
let success = CLIPS.load("rules.clp")
static func eval(expr: String) -> Value
Evaluates a CLIPS expression and returns the result.
let result = CLIPS.eval(expr: "(+ 2 3)")
// result: .int(5)
static func reset()
Resets the current environment, removing facts but keeping rules and templates.
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
static func assert(fact: String) -> Int
Asserts a fact, returns its ID.
let id = CLIPS.assert(fact: "(person (name \"John\") (age 30))")
static func retract(id: Int) -> Bool
Removes a fact from the environment.
CLIPS.retract(id: 1)
static func commandLoop()
Starts an interactive REPL.
CLIPS.commandLoop()
// SLIPS> (facts)
// SLIPS> (run)
Execution context that maintains system state.
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
}
public struct FactRec {
let id: Int
let name: String
var slots: [String: Value]
}
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?
}
Represents data types in SLIPS.
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)
}
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)])
// 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) }
public struct Rule {
let name: String
let patterns: [Pattern]
let rhs: [ExpressionNode]
let salience: Int
let tests: [ExpressionNode]
}
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
}
Manages the rule activation queue.
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)
}
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
}
public struct Activation {
let priority: Int // salience
let ruleName: String
var bindings: [String: Value]?
var factIDs: Set = []
var timestamp: Int = 0
}
// Set strategy
CLIPS.eval(expr: "(set-strategy lex)")
// Check current strategy
let strategy = CLIPS.eval(expr: "(get-strategy)")
// Returns: .symbol("lex")
Flexible I/O system with customizable callbacks.
public enum Router {
public static let STDOUT = "stdout"
public static let STDERR = "stderr"
public static let STDIN = "stdin"
}
// 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
)
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"]
Evaluates expressions and executes 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
}
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?
}
Mathematical Operators (15):
+, -, *, /=, <>, <, <=, >, >=and, or, not, eq, neqMath Functions (36):
sin, cos, tan, sec, csc, cotasin, acos, atan, atan2, asec, acsc, acotsinh, cosh, tanh, sech, csch, cothasinh, acosh, atanh, asech, acsch, acothexp, log, log10, sqrt, **abs, mod, round, pi, deg-rad, rad-degString Functions (11):
str-cat, sym-cat - Concatenationstr-length, str-byte-length - Lengthupcase, lowcase - Case conversionsub-string, str-index - Manipulationstr-replace, str-compare - Operationsstring-to-field - ParsingMultifield Functions (10):
nth$, length$, first$, rest$subseq$, member$, insert$, delete$explode$, implode$Template Functions (14) ๐:
modify, duplicate - Fact manipulationdeftemplate-slot-names - List slotsdeftemplate-slot-default-value - Default valuedeftemplate-slot-cardinality - Cardinalitydeftemplate-slot-types - Allowed typesdeftemplate-slot-range - Value rangedeftemplate-slot-multip - Test multifielddeftemplate-slot-singlep - Test single-fielddeftemplate-slot-existp - Test existenceI/O Functions (13):
read, readline, read-number, get-charprintout, print, println, put-charopen, close, flush, remove, renameFact Query Functions (7):
find-fact, find-all-factsdo-for-fact, do-for-all-factsany-factp, fact-existp, fact-indexUtility Functions (6):
gensym, gensym* - Symbol generationrandom, seed - Random numberstime - Timestampfuncall - Dynamic callModule Functions (6):
defmodule - Define modulefocus - Set focusget-current-module, set-current-modulelist-defmodules, get-defmodule-listPretty Print Functions (4):
ppdefmodule, ppdeffactsppdefrule, ppdeftemplateCore Constructs:
deftemplate, deffacts, defruleassert, retractbind, printout, prognfacts, rules, agendawatch, unwatchreset, clear, runset-strategy, get-strategySee FUNZIONI_REFERENCE.md for complete documentation of all 160 functions.
(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 <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 <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 <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 <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 <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.
public final class FunctionDefinitionSwift {
public let name: String
public let impl: (inout Environment, [Value]) throws -> Value
}
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