Reference Completo
La classe principale per interagire con SLIPS.
static func createEnvironment() -> Environment
Crea e inizializza un nuovo environment SLIPS.
let env = CLIPS.createEnvironment()
static func load(_ path: String) -> Bool
Carica ed esegue un file CLIPS.
let success = CLIPS.load("rules.clp")
static func eval(expr: String) -> Value
Valuta un'espressione CLIPS e ritorna il risultato.
let result = CLIPS.eval(expr: "(+ 2 3)")
// result: .int(5)
static func reset()
Resetta l'environment corrente, rimuovendo fatti ma mantenendo regole e template.
static func run(limit: Int?) -> Int
Esegue le regole nell'agenda. Ritorna il numero di regole eseguite.
let fired = CLIPS.run(limit: nil) // Esegue tutte
let fired = CLIPS.run(limit: 10) // Esegue max 10
static func assert(fact: String) -> Int
Asserisce un fatto, ritorna l'ID.
let id = CLIPS.assert(fact: "(persona (nome \"Mario\") (età 30))")
static func retract(id: Int) -> Bool
Rimuove un fatto dall'environment.
CLIPS.retract(id: 1)
static func commandLoop()
Avvia un REPL interattivo.
CLIPS.commandLoop()
// SLIPS> (facts)
// SLIPS> (run)
Contesto di esecuzione che mantiene lo stato del sistema.
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?
}
Rappresenta i tipi di dato 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)])
// Da Swift a 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) }
// Da Value a 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
}
Gestisce la coda di attivazioni delle regole.
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 // Nuove attivazioni in testa
case breadth // Nuove attivazioni in coda
case lex // Per salience, poi recency
case mea // Per salience, poi età
}
public struct Activation {
let priority: Int // salience
let ruleName: String
var bindings: [String: Value]?
var factIDs: Set = []
var timestamp: Int = 0
}
// Imposta strategia
CLIPS.eval(expr: "(set-strategy lex)")
// Verifica strategia corrente
let strategy = CLIPS.eval(expr: "(get-strategy)")
// Returns: .symbol("lex")
Sistema I/O flessibile con callback personalizzabili.
public enum Router {
public static let STDOUT = "stdout"
public static let STDERR = "stderr"
public static let STDIN = "stdin"
}
// Scrive su un router
public static func WriteString(
_ env: inout Environment,
_ logicalName: String,
_ str: String
)
// Scrive con newline
public static func Writeln(
_ env: inout Environment,
_ str: String
)
// Aggiunge 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"]
Valuta espressioni ed esegue funzioni.
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?
}
Operatori Matematici (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 - Concatenazionestr-length, str-byte-length - Lunghezzaupcase, lowcase - Conversione casosub-string, str-index - Manipolazionestr-replace, str-compare - Operazionistring-to-field - ParsingMultifield Functions (10):
nth$, length$, first$, rest$subseq$, member$, insert$, delete$explode$, implode$Template Functions (14) 🆕:
modify, duplicate - Manipolazione fattideftemplate-slot-names - Lista slotdeftemplate-slot-default-value - Default valuedeftemplate-slot-cardinality - Cardinalitàdeftemplate-slot-types - Tipi consentitideftemplate-slot-range - Range valorideftemplate-slot-multip - Test multifielddeftemplate-slot-singlep - Test single-fielddeftemplate-slot-existp - Test esistenzaI/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* - Generazione simbolirandom, seed - Numeri casualitime - Timestampfuncall - Chiamata dinamicaModule Functions (6):
defmodule - Definisce modulofocus - Imposta focusget-current-module, set-current-modulelist-defmodules, get-defmodule-listPretty Print Functions (4):
ppdefmodule, ppdeffactsppdefrule, ppdeftemplateCostrutti Core:
deftemplate, deffacts, defruleassert, retractbind, printout, prognfacts, rules, agendawatch, unwatchreset, clear, runset-strategy, get-strategyVedi FUNZIONI_REFERENCE.md per la documentazione completa di tutte le 160 funzioni.
(modify <fact-id> (<slot-name> <value>)*)
; Esempio
(modify 1 (age 31) (city "Rome"))
Modifica uno o più slot di un fatto esistente. Ritorna il nuovo fact-id.
(duplicate <fact-id> (<slot-name> <value>)*)
; Esempio
(duplicate 1 (name "Copy") (age 25))
Duplica un fatto con modifiche opzionali agli slot. Ritorna il nuovo fact-id.
(deftemplate-slot-names <template-name>)
; Esempio
(deftemplate-slot-names person)
; Ritorna: (create$ name age city)
Ritorna un multifield con i nomi di tutti gli slot del template.
(deftemplate-slot-default-value <template-name> <slot-name>)
; Esempio
(deftemplate-slot-default-value person age)
; Ritorna: 0 (o il default specificato)
Ritorna il valore di default di uno slot.
(deftemplate-slot-multip <template-name> <slot-name>)
(deftemplate-slot-singlep <template-name> <slot-name>)
; Esempio
(deftemplate-slot-multip project team-members)
; Ritorna: TRUE
(deftemplate-slot-singlep person name)
; Ritorna: TRUE
Verificano se uno slot è rispettivamente multifield o single-field.
(deftemplate-slot-existp <template-name> <slot-name>)
; Esempio
(deftemplate-slot-existp person salary)
; Ritorna: FALSE (se lo slot non esiste)
Verifica se uno slot esiste nel 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)
}
// Uso
CLIPS.eval(expr: "(printout t (square 7) crlf)")
// Output: 49