diff --git a/src/JuNarsese.jl b/src/JuNarsese.jl
index f2c3022..2f48564 100644
--- a/src/JuNarsese.jl
+++ b/src/JuNarsese.jl
@@ -26,9 +26,9 @@ using Reexport
include("Util/Util.jl")
include("Narsese/Narsese.jl")
-@reexport using .Narsese
-
include("Conversion/Conversion.jl")
+
+@reexport using .Narsese
@reexport using .Conversion
diff --git a/src/Narsese/Narsese.jl b/src/Narsese/Narsese.jl
index 7d2c3c6..aab0e62 100644
--- a/src/Narsese/Narsese.jl
+++ b/src/Narsese/Narsese.jl
@@ -34,15 +34,14 @@ export parse_default_float, parse_default_int, parse_default_uint
# 导入&导出 #
+include("Terms/Terms.jl")
+include("Sentences/Sentences.jl")
+include("Tasks/Tasks.jl")
+
using Reexport
-include("Terms/Terms.jl")
@reexport using .Terms
-
-include("Sentences/Sentences.jl")
@reexport using .Sentences
-
-include("Tasks/Tasks.jl")
@reexport using .Tasks
# 严格模式 #
diff --git a/src/Narsese/Sentences/stamp.jl b/src/Narsese/Sentences/stamp.jl
index b80e8b4..cd1e3e7 100644
--- a/src/Narsese/Sentences/stamp.jl
+++ b/src/Narsese/Sentences/stamp.jl
@@ -214,7 +214,7 @@ end
begin "方法集"
# 【20230815 16:33:51】函数「get_tense」已在「methods.jl」中定义
- import ..Narsese: get_tense
+ import ..Terms: get_tense
export is_fixed_occurrence_time
diff --git a/src/Narsese/terms/Terms.jl b/src/Narsese/terms/Terms.jl
index 14e1bdd..6e058d1 100644
--- a/src/Narsese/terms/Terms.jl
+++ b/src/Narsese/terms/Terms.jl
@@ -1,77 +1,3 @@
-#= 📝NAL: 关于「为何没有『外延并/内涵并』的问题」:
-
- - 核心:**外延交=内涵并,外延并=内涵交**
- - 源:《NAL》2012版,定理 7.4
-
- 原文:
-
- > The above definition and theorem show that the duality of extension
- > and intension in NAL corresponds to the duality of intersection and union
- > in set theory — intensional intersection corresponds to extensional union,
- > and extensional intersection corresponds to intensional union. Since set
- > theory is purely extensional, the ‘∪’ is associated to union only. To stress
- > the symmetry between extension and intense in NAL, here it is called “intensional intersection」, rather than “extensional union」, though the latter
- > is also correct, and sounds more natural to people familiar with set theory.
-
- 中译:
-
- > 上述定义和定理证明了NAL中的外延与内涵的对偶性,对应于集合论中的交与并的对偶性——内涵交对应于外延并,而外延交对应于内涵并。
- > 因为集合论是纯外延的,所以'∪'只与并集有关。
- > 为了强调NAL中外延与内涵的对称性,这里称之为「内涵交」,而不是「外延并」,尽管后者也是正确的,对熟悉集合论的人来说听起来更自然。
-
-=#
-
-#= 📝Julia: 泛型类的「类型参数」可以「挂羊头卖狗肉」:s{Int}(a) = s{Float64}(1.0)
- 此即:在调用类构造方法时,返回的「类型参数」与调用时的「类型参数」**可以不一致**
- 通过使用参数化类型和条件约束,Julia可以根据不同的类型参数生成不同的实例,并在必要时进行类型转换。这使得代码更加灵活且具有通用性,能够处理多种类型的数据。
-=#
-
-#= 📝Julia: 面向「唯一标识符」时,使用Symbol替代String
-
- 📌核心:Symbol使用「字符串内联」机制,把每个字符串作为唯一索引,且比对时无需逐个字符比对
- - 因此:Symbol在用作「唯一标识符」时,比String更有效率
-
- 英文维基的「字符串内联」资料:
- > String interning speeds up string comparisons,
- > which are sometimes a performance bottleneck in applications
- > (such as compilers and dynamic programming language runtimes)
- > that rely heavily on associative arrays with string keys to look up the attributes and methods of an object.
- > Without interning, comparing two distinct strings may involve examining every character of both.
-
- GPTの答:
- 在 Julia 中,Symbol 类型通常比 String 类型更具有运行时效率。
- 这是因为 Symbol 是不可变的类型,而 String 是可变的。
- - 每当你使用字符串字面量来创建一个新的字符串时,它都会生成一个新的字符串对象,可能会占用更多的内存并导致额外的性能开销。
- - 而 Symbol 只会创建一个唯一的符号,并且在运行时重复使用相同的符号。这使得 Symbol 比较速度更快,因为可以直接对其进行引用比较。
-
- 另外,当你需要在代码中频繁地进行字符串操作时,使用 Symbol 也可以提高性能。
- 字符串操作通常涉及到分割、拼接、查找等操作,而这些操作在 Symbol 上是更高效的,因为它们不涉及复制和重新分配内存空间的开销。
-
- 但需要注意的是,Symbol 和 String 是不同的数据类型,它们的适用场景也不同。Symbol 主要用于表示标识符、键和常量等不可变概念,而 String 则用于处理文本和字符串操作。
- 因此,在选择使用 Symbol 还是 String 时,需要根据具体的应用场景和需求来决定。
-
- 另可参考如下代码:
- ```julia
- a = "string_symbol"
- @time [
- "string_symbol" == a
- for _ in 1:0xfffff
- ]
- # 0.057884 seconds (31.06 k allocations: 3.075 MiB, 67.64% compilation time)
- a = :string_symbol
- @time [
- :string_symbol == a
- for _ in 1:0xfffff
- ]
- # 0.053276 seconds (38.77 k allocations: 3.656 MiB, 98.21% compilation time)
- ```
-=#
-
-#= 📝Julia: 嵌套数组的二次展开,直接使用「[(arr...)...]」
- 例:对「嵌套数组对象」`a = [(1,2),[3,4,5]]`
- - 有`[(a...)...] == [1,2,3,4,5]`
-=#
-
"""
提供基本的词项定义
@@ -105,675 +31,13 @@
"""
module Terms
-# 导入:前置 #
+# 引入 #
# 时态 【20230804 14:20:50】因为「时序蕴含/等价」的存在,需要引入「时间参数」(参考自OpenNARS)
include("tense.jl")
-# 导出 #
-
-export AbstractVariableType, VariableTypeIndependent, VariableTypeDependent, VariableTypeQuery
-export AbstractStatementType, StatementTypeInheritance, StatementTypeSimilarity, StatementTypeImplication, StatementTypeEquivalence
-export AbstractLogicOperation, And, Or, Not
-export AbstractEI, Extension, Intension
-export AbstractTemporalRelation, Sequential, Parallel
-export AbstractCompoundType, CompoundTypeTermSet, CompoundTypeTermLogicalSet, CompoundTypeTermProduct, CompoundTypeTermImage, CompoundTypeStatementLogicalSet, CompoundTypeStatementTemporalSet
-
-export AbstractTerm, AbstractAtom, AbstractCompound
-
-export terms, ϕ1, ϕ2
-
-export Word, PlaceHolder, Variable, Interval, Operator, CommonCompound, TermImage, Statement
-export placeholder, isplaceholder
-
-
-
-# 作为「类型标记」的类型参数 #
-
-"[NAL-1|NAL-2|NAL-5]陈述类型:继承&相似、蕴含&等价"
-abstract type AbstractStatementType end
-abstract type StatementTypeInheritance <: AbstractStatementType end # NAL-1
-abstract type StatementTypeSimilarity <: AbstractStatementType end # NAL-2
-abstract type StatementTypeImplication{T <: Tense} <: AbstractStatementType end # NAL-5|NAL-7
-abstract type StatementTypeEquivalence{T <: Tense} <: AbstractStatementType end # NAL-5|NAL-7
-
-"[NAL-2]区分「外延」与「内涵」"
-abstract type AbstractEI end # NAL-2
-abstract type Extension <: AbstractEI end
-abstract type Intension <: AbstractEI end
-
-"[NAL-3|NAL-5]集合论/一阶逻辑操作:与或非" # 原创
-abstract type AbstractLogicOperation end
-abstract type And <: AbstractLogicOperation end # 词项→交,陈述→与
-abstract type Or <: AbstractLogicOperation end # 词项→并,陈述→或
-abstract type Not <: AbstractLogicOperation end # 词项→非,陈述→非
-
-"[NAL-6]变量类型" # 【20230724 11:38:25】💭不知道OpenJunars中为何要让「AbstractVariableType」继承AbstractTerm
-abstract type AbstractVariableType end # NAL-6
-abstract type VariableTypeIndependent <: AbstractVariableType end # 独立变量 & 对于
-abstract type VariableTypeDependent <: AbstractVariableType end # 非独变量 # 存在
-abstract type VariableTypeQuery <: AbstractVariableType end # 查询变量 ? 疑问
-
-"[NAL-7]时序合取:区分「序列」与「平行」"
-abstract type AbstractTemporalRelation end
-abstract type Sequential <: AbstractTemporalRelation end
-abstract type Parallel <: AbstractTemporalRelation end
-
-# 复合词项类型
-
-"""
-所有复合词项类型的基类
-"""
-abstract type AbstractCompoundType end
-"[NAL-2]词项集"
-abstract type CompoundTypeTermSet{EI <: AbstractEI} <: AbstractCompoundType end
-"[NAL-2]词项の复合:集合操作⇒复合集"
-abstract type CompoundTypeTermLogicalSet{EIType <: AbstractEI, LogicOperation <: AbstractLogicOperation} <: AbstractCompoundType end
-"[NAL-4]乘积"
-abstract type CompoundTypeTermProduct <: AbstractCompoundType end
-"[NAL-4]像"
-abstract type CompoundTypeTermImage{EIType <: AbstractEI} <: AbstractCompoundType end
-"[NAL-5]陈述逻辑集: {与/或/非}"
-abstract type CompoundTypeStatementLogicalSet{LogicOperation <: AbstractLogicOperation} <: AbstractCompoundType end
-"[NAL-7]陈述时序集 <: 陈述逻辑集{与}"
-abstract type CompoundTypeStatementTemporalSet{TemporalRelation <: AbstractTemporalRelation} <: CompoundTypeStatementLogicalSet{And} end
-
-# 正式对象 #
-
-"一切词项的总基础" # OpenJunars所谓「FOTerm」实际上就是此处的「AbstractTerm」,只因OpenJunars把「变量类型」也定义成了词项
-abstract type AbstractTerm end
-
-
-"[NAL-1]所有的原子词项 | 协议:支持`nameof`方法"
-abstract type AbstractAtom <: AbstractTerm end
-import Base: nameof
-
-"[NAL-2]复合词项の基石 | 协议:支持`terms`方法(无需绑定属性)"
-abstract type AbstractCompound{type <: AbstractCompoundType} <: AbstractTerm end
-function terms end
-
-"[NAL-1]陈述词项の基石 | 协议:支持`terms`、`ϕ1`和`ϕ2`方法(无需绑定属性)"
-abstract type AbstractStatement{type <: AbstractStatementType} <: AbstractTerm end
-function ϕ1 end; function ϕ2 end
-
-# 具体结构定义
-
-begin "单体词项"
-
- """
- [NAL-1]最简单的「词语」词项
-
- 参考:《NAL》定义2.1
- > The basic form of a term is a word, that is, a string of characters from a finite alphabet.
- > There is no additional requirement on the alphabet.
- > In this document the alphabet includes English letters, digits 0 to 9, and a few special signs, such as hyphen (‘-’).
- > In the examples in this book, we often use common English nouns for terms, such as bird and animal, just to make the examples easy to understand.
- > There is no problem to do the same in a different natural language, such as Chinese.On the other hand, it is also fine to use terms that are meaningless to human beings, such as drib and aminal.
-
- 中译:
- > 一个词项的基本形式是一个「词语」,即来自有限字母表的一串字符。
- > 除此之外对字母表没有要求。
- > 本书中字母表包括英文字母、数字0 ~ 9和一些特殊符号,如「-」,并常用常见的英语名词来表示术语,例如bird和animal,只是为了使示例易于理解。
- > 用一种不同的自然语言(如中文)做同样的事情是没有问题的。另一方面,也可以使用对人类没有意义的术语,如drib和aminal。
-
- """
- struct Word <: AbstractAtom
- name::Symbol # 为何不用String?见上文笔记
-
- "加入合法性检查"
- Word(name::Symbol) = check_valid_explainable(
- new(name)
- ) # 增加合法性检查_explainable
- end
-
- """
- 支持从String构造
- - 目的:处理从(AST)解析中返回的字符串参数
- """
- Word(name::Union{AbstractString, AbstractChar}) = name |> Symbol |> Word
-
- raw"""
- [NAL-4]像占位符
- - 现在作为一个独立的类,而非使用Nothing类型
- - 单例模式,只有一个`PlaceHolder()`对象
- - 按照原子词项的原则处理
- - 可以被视作「Narsese中的Nothing」
- - ⚠《NAL》定义中「像占位符不可出现在第一个位置,其为关系词项所保留」的特性,留给构造时合法性检查
- - 实现参考:OpenJunars `terms.jl`;其它NARS实现的处理方式:
- - OpenNARS:设置一个字符串常量为`_`,并在解析「像」时直接识别,作为「占位符位置」存入`ImageXXt`类型中
- - 参见:OpenNARS 3.1.2 `Symbols.java` `StringParser.java`
- - ONA:直接在解析时解析成「占位符位置」``
- - 参见:ONA 0.9.2 `Narsese.c`
- - PyNARS:设置一个名为`_`的词语,在解析时直接识别,作为「占位符位置」存入`XXtensionalImage`类型中
- - 参见:PyNARS `Term.py` `Compound.py`
-
- 参考:《NAL》定义8.4
- > where ‘⋄’ is a special symbol indicating the location of T1 or T2 in the product,
- > and in the component list it can appear in any place, except the first (which is reserved for the relational term).
- > When it appears at the second place, the image can also be written in infix format as (R / T2) or (R \ T2).
-
- 中译:
- > 其中『⋄』是表示T1或T2在乘积中的位置的特殊符号;
- > 在组分列表中,它可以出现在任何位置,除了第一个位置(它是为关系词项保留的)。
- > 当它出现在第二位时,像也可以用中缀格式写成 (R / T2) 或 (R \ T2)。
- """
- struct PlaceHolder <: AbstractAtom end
- "像占位符单例模式下的唯一实例"
- const placeholder::PlaceHolder = PlaceHolder()
- "检测是否为像占位符: 类似`isnothing`"
- isplaceholder(x) = x === PlaceHolder
- isplaceholder(::PlaceHolder) = true
-
- "【!即将弃用:请使用`Base.nameof`方法,而非直接调用属性`name`】兼容`.name`属性:对像占位符的任何属性访问都将返回空字符串"
- Base.getproperty(::PlaceHolder, ::Symbol)::String = ""
- "兼容构造方法`constructor(string|expr|...)`: 直接返回`placeholder`"
- PlaceHolder(::Any) = placeholder
-
- """
- [NAL-6]变量词项(用类型参数包括三种类型)
-
- 参考:《NAL》定义10.1~2
- > A query variable is a variable term in a question that represents a constant term to be found to answer the question,
- > and it is named by ‘?’,
- > optionally followed by a word or a number.
-
- > An independent variable represents any unspecified term under a given restriction,
- > and it is named by a word (or a number) preceded by ‘#’.
- > A dependent variable represents a certain unspecified term under a given restriction,
- > and it is named as an independent variable with a dependency list consisting of independent variables it depends on,
- > which can be empty.
-
- 中译:
- > 查询变量是问题中的一个变量项,
- > 它表示要找到的用于回答问题的常量项,
- > 它被命名为'?',
- > 可选后跟一个单词或数字。
-
- > 独立变量表示给定限制下的任何未指定项,
- > 并以「#」前面的单词(或数字)命名。
- > 非独变量表示给定限制下的某个未指定项,
- > 它被命名为具有由它所依赖的独立变量组成的依赖列表的独立变量,
- > 该列表可以为空。
- """
- struct Variable{T <: AbstractVariableType} <: AbstractAtom
- name::Symbol
-
- "加入合法性检查"
- Variable{T}(name::Symbol) where {T <: AbstractVariableType} = check_valid_explainable(
- new(name)
- ) # 增加合法性检查
- end
- "支持从String构造"
- Variable{T}(name::Union{AbstractString, AbstractChar}) where {T<:AbstractVariableType} = name |> Symbol |> Variable{T}
-
- """
- [NAL-7]间隔(Interval)
-
- 迁移自:PyNARS Interval.py
- - 其中Interval类继承Term
- - ⚠OpenNARS、OpenJunars中没有相关实现
-
- 参考:《NAL》定义11.4
-
- > The real-time experience of a NARS is a sequence of Narsese sentences, separated by non-negative numbers indicating the interval between the arriving time of subsequent sentences, measured by the system’s internal clock.
-
- 中译:
- > NARS的实时经验是一系列的Narsese句子,由非负数分隔,这些非负数表示后续句子到达时间之间的间隔,由系统的内部时钟测量。
-
- 【20230815 17:19:44】因「字符串转换器字典查找问题」与「不同精度区分必要性小」不再区分精度:统一至UInt
- 【20230817 15:03:35】作为NAL-7中的「事件」对象,「该对象为原子词项」只是在「组成结构」上的区分,其仍然可被认作是「事件」
- """
- struct Interval <: AbstractAtom
-
- "【!即将弃用:现在使用`nameof`方法,而非外加属性】(只读as缓存)继承自原子词项"
- name::Symbol # 【20230817 15:02:57】现在与其它原子词项统一使用Symbol
-
- "间隔长度"
- interval::UInt
-
- "内部构造方法:自动获得名称并缓存"
- Interval(interval::UInt) = check_valid_explainable(
- new(
- Symbol(interval), # 缓存名称
- interval # 存储值
- )
- )
- end
-
- "外部构造方法 兼容所有实数(浮点数亦兼容)"
- @inline Interval(interval::Real) = Interval(
- convert(UInt, interval)
- )
-
- "外部构造方法 兼容以自身名称「纯数字」定义的字符串"
- @inline Interval(s::Union{AbstractString, AbstractChar}) = Interval(parse(UInt, s))
-
- "外部构造方法 兼容以自身名称「纯数字」定义的符号"
- @inline Interval(s::Symbol) = Interval(string(s))
-
- """
- [NAL-8]操作词项(Action)
-
- 参考:《NAL》定义12.2
-
- > An atomic operation is represented as an operator (a special term whose name starts with ‘⇑’)
- > followed by an argument list (a sequence of terms, though can be empty).
- > Within the system, operation “(⇑op a₁ ··· aₙ)” is treated as statement “(× self a₁ ··· aₙ) → op」,
- > where op belongs to a special type of term that has a procedural interpretation,
- > and self is a special term referring to the system itself.
-
- 中译:
- > 一个原子操作表示为一个操作符(一个特殊的词项,其名以「⇑」开头)跟一个参数列表(一个词项序列,但可为空)。
- > 在系统内,操作「(⇑op a₁ ··· aₙ)」被视为语句「(× self a₁ ··· aₙ) → op」,
- > 其中op属于具有程序解释的特殊类型词项,【译者注:此「程序解释的特殊类型」即此处定义的类】
- > 而self是指系统本身的特殊词项。【译者注:此即NAL代码中经常出现的`{SELF}`】
- """
- struct Operator <: AbstractAtom
- name::Symbol
-
- "加入合法性检查"
- Operator(name::Symbol) = check_valid_explainable(
- new(name)
- ) # 增加合法性检查
- end
- "支持从String构造"
- Operator(name::Union{AbstractString, AbstractChar}) = name |> Symbol |> Operator
-
- """
- 通用复合词项
-
- 包括:
- - 词项集
- - 外延集
- - 内涵集
- - 词项逻辑集
- - 外延交/内涵交
- - 外延并/内涵并(自动重定向)
- - 外延差/内涵差
- - 陈述集
- - 陈述逻辑集
- - 合取
- - 析取
- - 否定
- - 陈述时序集
-
- 不包括:
- - 外延像/内涵像(需要使用额外的「像占位符索引」)
- - 📄参考:`OpenNARS/ImageExt.java relationIndex`
- - 陈述
-
-
NAL参考
-
- [NAL-2]词项集 {} []
-
- 参考:《NAL》定义6.3、6.5
- > If T is a term, the extensional set with T as the only component, {T}, is defined by (∀x)((x → {T}) ⟺ (x ↔ {T})).
- > If T is a term, the intensional set with T as the only component, [T], is defined by (∀x)(([T] → x) ⟺ ([T] ↔ x)).
-
- 中译:
- > 如果T是一个词项,则以T为唯一组分的外延集 {T} 定义为 (∀x)((x → {T}) ⟺ (x ↔ {T}))。
- > 如果T是一个词项,则以T为唯一组分的内涵集 [T] 定义为 (∀x)(([T] → x) ⟺ ([T] ↔ x))。
-
- [NAL-3]词项逻辑集 {外延/内涵, 交/并/差} # 此处「&」「|」是对应的「外延交&」「外延并|」
- - And: 交集 ∩& ∩|
- - Or : 并集 ∪& ∪|
- - 注意:此处不会使用,会自动转换(见📝「为何不使用外延/内涵 并?」)
- - Not: 差集 - ~
- - 有序(其余皆无序)
-
- 参考:《NAL》定义7.6~9
- > Given terms T1 and T2, their extensional intersection (T1 ∩ T2)
- > is a compound term defined by (∀x)((x → (T1 ∩ T2)) ⟺ ((x → T1) ∧ (x → T2))).
- > Given terms T1 and T2, their intensional intersection (T1∪T2)
- > is a compound term defined by (∀x)(((T1 ∪ T2) → x) ⟺ ((T1 → x) ∧ (T2 → x))).
- > If T1 and T2 are different terms, their extensional difference (T1 - T2)
- > is a compound term defined by (∀x)((x → (T1 - T2)) ⟺((x → T1) ∧ ¬(x → T2))).
- > If T1 and T2 are different terms, their intensional difference (T1⊖T2)
- > is a compound term defined by (∀x)(((T1⊖T2) → x) ⟺ ((T1 → x) ∧ ¬(T2 → x))).
-
-
- 中译:
- > 给定词项T1与T2,它们的外延交(T1∩T2)是一个复合词项,定义为 (∀x)((x → (T1 ∩ T2)) ⟺ ((x → T1) ∧ (x → T2)))。
- > 给定词项T1与T2,它们的内涵交(T1∪T2)是一个复合词项,定义为 (∀x)(((T1 ∪ T2) → x) ⟺ ((T1 → x) ∧ (T2 → x)))。
- > 如果T1和T2是不同的词项,它们的外延差(T1-T2)是一个复合词项,定义为 (∀x)((x → (T1 - T2)) ⟺((x → T1) ∧ ¬(x → T2)))。
- > 如果T1和T2是不同的词项,它们的内涵差(T1 * T2)是一个复合词项,定义为 (∀x)(((T1⊖T2) → x) ⟺ ((T1 → x) ∧ ¬(T2 → x)))。
-
- [NAL-4]乘积 (*, ...)
- - 有序
- - 无内涵外延之分
- - 用于关系词项「(*, 水, 盐) --> 前者可被后者溶解」
-
- 参考:《NAL》定义8.1
- > The product connector ‘×’ takes two or more terms as components,
- > and forms a compound term that satisfies ((× S₁ ··· Sₙ) → (× P₁ ··· Pₙ)) ⟺ ((S₁ → P₁) ∧ ··· ∧ (Sₙ → Pₙ)).
-
- 中译:
- > 乘积连接符「×」采用两个或多个词项作为组分,形成一个复合词项,
- > 满足 ((× S₁ ··· Sₙ) → (× P₁ ··· Pₙ)) ⟺ ((S₁ → P₁) ∧ ··· ∧ (Sₙ → Pₙ))。
-
- [NAL-5]陈述逻辑集:{与/或/非}
- - And: 陈述与 ∧ && Conjunction
- - Or : 陈述或 ∨ || Disjunction
- - Not: 陈述非 ¬ --
-
- 注意:都是「对称」的⇒集合(无序)
-
- 参考:《NAL》定义9.6
-
- > When S1 and S2 are different statements,
- > their conjunction, (S1 ∧ S2), is a compound statement defined by
- > (∀x)((x ⇒ (S1 ∧ S2)) ⟺ ((x ⇒ S1) ∧ (x ⇒ S2))).
- > Their disjunction, (S1 ∨ S2), is a compound statement defined by
- > (∀x)(((S1 ∨ S2) ⇒ x) ⟺ ((S1 ⇒ x) ∧ (S2 ⇒ x))).
-
- 中译:
- > 当S1和S2是不同的陈述时,
- > 它们的合取(S1∧S2)是一个复合陈述,定义为
- > (∀x)((x ⇒ (S1 ∧ S2)) ⟺ ((x ⇒ S1) ∧ (x ⇒ S2))).
- > 它们的析取(S1∨S2)是一个复合陈述,定义为
- > (∀x)(((S1 ∨ S2) ⇒ x) ⟺ ((S1 ⇒ x) ∧ (S2 ⇒ x))).
-
- 【20230817 15:44:10】细节:OpenJunars外其它NARS实现中,对复合词项的对待方法不同——是否要再度合并?
- - 在PyNARS中,陈述逻辑集、陈述时序集对元素类型无所限制,可以混用
- - 在OpenNARS中,所有复合词项统一使用`CompoundTerm`实现,并将连接词用单一的字符串存储
-
- [NAL-7]陈述时序集:{序列/平行} <: 抽象陈述逻辑集{合取}
- - 与 `&/`: 序列合取(有序)
- - 或 `&|`: 平行合取(无序)
-
- 📌技术点: 此中的数据`terms`为一个指向「向量/集合」的引用
- - 即便其类型确定,它仍然是一个「指针」,不会造成效率干扰
-
- 参考:《NAL》定义11.5
- > The conjunction connector (‘∧’) has two temporal variants: 「sequential conjunction」 (‘,’) and “parallel conjunction」 (‘;’).
- > 「(E1, E2)” corresponds to the compound event consisting of E1 followed by E2, and “(E1; E2)” corresponds to the compound event consisting of E1 accompanied by E2.
-
- 中译:
- > 合取连接符 (‘∧’) 有两种时序变体变体:「序列合取」 (‘,’) 和「平行合取」 (‘;’)。
- > 「(E1, E2)」 对应由E1后接E2,「(E1; E2)」 对应由E1伴随E2组成的复合事件。
- """
- struct CommonCompound{type <: AbstractCompoundType} <: AbstractCompound{type}
-
- """
- 有序不可变元组/集合
- - 承继旧`terms`字段
- - 保证词项构造之后不会改变
- - 一切语法上的限制,都交给「合法性检查」函数
- - 例如:陈述逻辑集只能装陈述
- - 例如:
- """
- terms::Tuple{Vararg{<:AbstractTerm}}
-
- """
- 统一的内部构造方法
- - 统一具备合法性检查
- - 根据外部函数「构造器类型」获取构造器(支持重定向)
- - 根据「可重复性」筛选掉重复项
- """
- function CommonCompound{type}(terms::Tuple{Vararg{AbstractTerm}}) where {type <: AbstractCompoundType}
- # 根据「可重复性」筛选掉重复项,根据「可交换性」决定是否排序
-
- # 生成并处理数组
- terms_arr::Vector{AbstractTerm} = collect(terms) # 创建新数组
- is_repeatable(type) || unique!(terms_arr) # 若不可重复,筛选重复项(不会改变内容顺序)
- is_commutative(type) && sort!(terms_arr) # 若可交换,排序(不会改变内容)
-
- terms_tuple::Tuple = Tuple{Vararg{AbstractTerm}}(terms_arr) # 创建新元组
- constructor::Type = constructor_type(type) # 【20230818 0:30:25】注意:new不能当参数传递
- # 增加合法性检查
- return check_valid_explainable(
- constructor <: AbstractCompoundType ?
- new{constructor}(terms_tuple) :
- constructor(terms_tuple)
- )
- end
-
- #= 各个「具体类型」的内部构造方法 =#
-
- # 词项逻辑集
-
- "(有序)差集 Difference{外延/内涵} - ~" # 注意:这是二元的 参数命名参考自OpenJunars
- function CommonCompound{CompoundTypeTermLogicalSet{EIType, Not}}(ϕ₁::AbstractTerm, ϕ₂::AbstractTerm) where EIType # 此EIType构造时还会被检查类型
- ϕ₁ == ϕ₂ && error("不允许重复词项「$ϕ1==$ϕ2」!")
- check_valid_explainable(
- new{CompoundTypeTermLogicalSet{EIType, Not}}(
- (ϕ₁, ϕ₂) # 【20230814 13:21:55】不可交换,直接构造元组,但因「不可重复」需要筛选;参考《NAL》中`different`
- )
- ) # 增加合法性检查
- end
-
- "陈述非 Negation"
- function CommonCompound{CompoundTypeStatementLogicalSet{Not}}(ϕ::AbstractTerm)
- check_valid_explainable(
- new{CompoundTypeStatementLogicalSet{Not}}((ϕ,)) # 只有一个,且不要求是陈述(留给「合法性检查」;PyNARS也兼容「非陈述元素」)
- ) # 增加合法性检查
- end # 内涵并=外延交
-
- end
-
- """
- 统一的「类型重定向」函数:从
- - 避免「方法歧义冲突」`XXX is ambiguous.`
- - 开放给其它自定义复合词项类型
-
- @返回值:构造方法
- @默认逻辑:返回type自身,指导使用默认构造方法
- - 若为「复合词项类型」则指导构造方法重定向至`new{type}`
- """
- @inline constructor_type(type::Type)::Type = type
- @inline (constructor_type(::Type{CompoundTypeTermImage{EI}})::Type) where {EI <: AbstractEI} = @show TermImage{EI}
-
- "(无序,重定向)并集 Union{外延/内涵} ∪& ∪|" # 【20230724 14:12:33】暂且自动转换成交集(返回值类型参数转换不影响)(参考《NAL》定理7.4)
- @inline function constructor_type(::Type{T}) where T <: CompoundTypeTermLogicalSet{Extension, Or}
- CompoundTypeTermLogicalSet{Intension, And}
- end # 外延并=内涵交 【20230818 0:13:02】不知为何,不写成`where`就会报错「syntax: invalid variable expression in "where" around 」
- @inline function constructor_type(::Type{T}) where T <: CompoundTypeTermLogicalSet{Intension, Or}
- CompoundTypeTermLogicalSet{Extension, And}
- end
-
- "外部构造方法:统一的「任意长参数」"
- @inline function CommonCompound{type}(terms::Vararg{AbstractTerm}) where {type <: AbstractCompoundType}
- CommonCompound{type}(terms) # 直接传递封装好的Tuple
- end
-
- "除元组以外的支持的迭代器类型"
- const SUPPORTED_ALIAS_ITERATORS::Type = Union{
- Base.Generator,
- AbstractArray,
- Set,
- }
-
- "外部构造方法:重载各类迭代器"
- @inline function CommonCompound{type}(itr::SUPPORTED_ALIAS_ITERATORS) where {type}
- CommonCompound{type}(
- Tuple{Vararg{AbstractTerm}}(itr)
- )
- end
-
- raw"""
- [NAL-4]像{外延/内涵} (/, a, b, _, c) (\, a, b, _, c)
- - 有序
- - 【20230724 22:06:36】注意:词项在terms中的索引,不代表其在实际情况下的索引
-
- 例:`TermImage{Extension}([a,b,c], 3)` = (/, a, b, _, c)
-
- 参考:《NAL》定义8.4
- > For a relation R and a product (× T1 T2),
- > the extensional image connector, ‘/’, and intensional image connector, ‘\’,
- > of the relation on the product are defined as the following, respectively:
- > ((× T1 T2) → R) ⟺ (T1 → (/ R ⋄ T2)) ⟺ (T2 → (/ R T1 ⋄))
- > (R → (× T1 T2)) ⟺ ((\ R ⋄ T2) → T1) ⟺ ((\ R T1 ⋄) → T2)
-
- 中译:
- > 对于关系R和乘积(× T1 T2),乘积上关系的外延像连接符「/」和内延像连接符「\」分别定义为:
- > ((× T1 T2) → R) ⟺ (T1 → (/ R ⋄ T2)) ⟺ (T2 → (/ R T1 ⋄))
- > (R → (× T1 T2)) ⟺ ((\ R ⋄ T2) → T1) ⟺ ((\ R T1 ⋄) → T2)
-
- """
- struct TermImage{EIType <: AbstractEI} <: AbstractCompound{CompoundTypeTermImage{EIType}}
- terms::Tuple{Vararg{AbstractTerm}}
- relation_index::Unsigned # 「_」的位置(一个占位符,保证词项中只有一个「_」)
-
- """
- 限制占位符位置(0除外)
-
- 📌莫使用`Tuple{Vararg{T}} where T <: AbstractTerm`
- - 理:Julia参数类型的「不变性」,参数类型的子类关系不会反映到整体上
- - 例: `Tuple{Int} <: Tuple{Integer} == false`
- - 因:此用法会限制Tuple中「只能由一种类型」
- - 因而产生「无方法错误」(其中有「!Matched::Tuple{Vararg{T}}」)
- - 解:直接使用`Tuple{AbstractTerm}`
- - 其可以包含任意词项,而不会被限制到某个具体类型中
- - 例如:只用`Tuple{Integer}`而不用`Tuple{Int}`
- """
- function TermImage{EIType}(terms::Tuple{Vararg{AbstractTerm}}, relation_index::Unsigned) where {EIType}
- relation_index == 0 || @assert relation_index ≤ length(terms) + 1 "索引`$relation_index`越界!"
- # 其默认已无序
- check_valid_explainable(
- new{EIType}(terms, relation_index) # 加入合法性检查
- ) # 增加合法性检查
- end
- end
-
- "类型适配:对有符号整数的映射"
- @inline function TermImage{EIType}(terms::Tuple{Vararg{AbstractTerm}}, relation_index::Integer) where {EIType}
- TermImage{EIType}(terms, unsigned(relation_index))
- end
-
- "转换兼容支持:多参数构造(倒过来,占位符位置放在最前面)"
- @inline function TermImage{EIType}(relation_index::Integer, terms::Vararg{AbstractTerm}) where EIType
- TermImage{EIType}(terms, unsigned(relation_index))
- end
-
- "转换兼容支持:多参数构造(兼容「词项序列」,使用新的「像占位符」单例类型)"
- function TermImage{EIType}(terms::Vararg{AbstractTerm}) where EIType
- placeholder_index::Union{Integer, Nothing} = findfirst(isplaceholder, terms)
- isnothing(placeholder_index) && error("在参数「$terms」中未找到像占位符位置!")
- TermImage{EIType}(
- filter(!isplaceholder, terms), # 过滤出所有非占位符词项
- unsigned(placeholder_index),
- )
- end
-
- "转换兼容支持:从元组以外的其它迭代器构造"
- @inline function TermImage{EIType}(array::SUPPORTED_ALIAS_ITERATORS) where EIType
- TermImage{EIType}(array...)
- end
-
-end
-
-begin "陈述词项"
-
- raw"""
- [NAL=1|NAL-5]陈述Statement{继承/相似/蕴含/等价/...} --> <-> ==> <=> ...
- - 现只支持「二元」陈述,只表达两个词项之间的关系
- - ❎【20230804 14:17:30】现增加「时序」参数,以便在词项层面解析「时序关系」
- - 【20230804 14:44:13】现把「时序系词」作为「主系词」(参考自OpenNARS)
- - 【20230812 22:19:20】加入「合法性检查」机制
-
- 参考:《NAL》定义2.2、6.1、9.1、9.5、11.6、11.7
- 继承
- 参考:《NAL》定义2.2
- > The basic form of a statement is an inheritance statement,
- > 「S → P」, where S is the subject term, P is the predicate term, and ‘→’ is the inheritance copula,
- > defined as being a reflexive and transitive relation from one term to another term.
-
- 中译:
- > 陈述的基本形式是继承陈述「S→P」,
- > 其中S为主词项,P为谓词项,「→」为继承系词,
- > 定义为从一个词项到另一个词项的自反传递关系。
- 相似
- 参考:《NAL》定义6.1
- > For any terms S and P, similarity ‘↔’ is a copula defined by
- > (S ↔ P) ⟺ ((S → P) ∧ (P → S)).
-
- 中译:
- > 对于任何词项S和P,相似『↔』是由下者定义之词项:
- > (S ↔ P) ⟺ ((S → P) ∧ (P → S))。
-
- 蕴含
- 参考:《NAL》定义9.1
- > If S1 and S2 are statements, “S1 ⇒ S2” is true if and only if in IL S2 can be derived from S1 in a finite number of inference steps.
- > Here ‘⇒’ is the implication copula. Formally, it means (S1 ⇒ S2) ⟺ {S1} ⊢ S2.
-
- 中译:
- > 如果 S1 和 S2 是陈述,则「S1 ⇒ S2」为真,如果且仅当在 IL 中,S2 可以从 S1 进行有限数量的推理步骤而得出。
- > 这里的『⇒』是「蕴含」系词。形式上,它的意思是 (S1 ⇒ S2) ⟺ {S1} ⊢ S2。
- 等价
- 参考:《NAL》定义9.5
- > The equivalence copula, ‘⇔’, is defined by
- > (A ⇔ C) ⟺ ((A ⇒ C) ∧ (C ⇒ A))
- > As a special type of compound terms, compound statements can be used to summarize existing statements.
-
- 中译:
- > 「等价」系词『⇔』的定义是
- > (A ⇔ C) ⟺ ((A ⇒ C) ∧ (C ⇒ A))
-
- 时序蕴含/等价
-
- 参考:《NAL》定义11.6
- > For an implication statement “S ⇒ T” between events S and T, three different temporal relations can be specified:
- > (1) If S happens before T happens,
- > the statement is called “predictive implication」, and is rewritten as “S /⇒ T」,
- > where S is called a sufficient precondition of T,
- > and T a necessary postcondition of S.
- > (2) If S happens after T happens,
- > the statement is called “retrospective implication」, and is rewritten as “S \⇒ T」,
- > where S is called a sufficient postcondition of T,
- > and T a necessary precondition of S.
- > (3) If S happens when T happens,
- > the statement is called “concurrent implication」, and is rewritten as “S |⇒ T」,
- > where S is called a sufficient co-condition of T,
- > and T a necessary co-condition of S.
-
- 中译:
- > 对于事件S和T之间的蕴含语句「S⇒T」,可以指定三种不同的时间关系:
- > (1)如果S发生在T发生之前,该陈述称为「预测性蕴含」,并重写为「S/⇒T」,
- > 其中S是T的充分前提,T是S的必要后置条件。
- > (2)如果S发生在T发生之后,该陈述称为「回顾性蕴含」,并重写为「S\⇒T」,
- > 其中S是T的充分后置条件,T是S的必要前提。
- > (3)如果T发生时S同时发生,该陈述称为「并发性蕴含」,并重写为「S|⇒T」,
- > 其中S是T的充分协条件,T是S的必要协条件。
-
- 参考:《NAL》定义11.7
- Three “temporal equivalence」 (predictive, retrospective,
- and concurrent) relations are defined as the following:
- > (1) 「S /⇔ T」 (or equivalently, 「T \⇔ S」) means that S is an equivalent precondition of T, and T an equivalent postcondition of S.
- > (2) 「S |⇔ T” means that S and T are equivalent co-conditions of each other.
- > (3) To simplify the language, 「T \⇔ S” is always represented as “S /⇔ T」, so the copula “ \⇔” is not actually included in the grammar of Narsese.
-
- 中译:
- 三个「时间等价」(预测性、回顾性、并发性)关系定义如下:
- > (1)「S /⇔ T」(或等价地,「T \⇔ S」)表示S是T的等价前提,T是S的等价后置条件。
- > (2)「S |⇔ T」表示S和T是彼此的等价共条件。
- > (3)为了简化语言,「T \⇔ S」总是被表示为「S /⇔ T」,所以关联词「\⇔」实际上并不在Narsese语法中。
- > - 译者注:此举与先前的「外延并/内涵并」类似
- """
- struct Statement{type <: AbstractStatementType} <: AbstractStatement{type}
- ϕ1::AbstractTerm # subject 主词
- ϕ2::AbstractTerm # predicate 谓词
-
- """
- 内部构造方法
- - 【20230812 22:20:01】现调用外部定义的「内联可解释合法性检查」函数
- """
- function Statement{type}(
- ϕ1::AbstractTerm, ϕ2::AbstractTerm,
- ) where {type <: AbstractStatementType}
- check_valid_explainable(
- is_commutative(type) ? # 可交换⇒排序
- new{type}(sort!([ϕ1, ϕ2])...) :
- new{type}(ϕ1, ϕ2)
- ) # 增加合法性检查
- end
- end
-
- "转换兼容支持:从迭代器构造"
- Statement{type}(iter) where type = Statement{type}(iter...)
-
-end
-
-# 引入:后置 #
+# 结构
+include("structs.jl")
# 别名
include("aliases.jl")
diff --git a/src/Narsese/terms/structs.jl b/src/Narsese/terms/structs.jl
new file mode 100644
index 0000000..0fbea62
--- /dev/null
+++ b/src/Narsese/terms/structs.jl
@@ -0,0 +1,736 @@
+#= 📝NAL: 关于「为何没有『外延并/内涵并』的问题」:
+
+ - 核心:**外延交=内涵并,外延并=内涵交**
+ - 源:《NAL》2012版,定理 7.4
+
+ 原文:
+
+ > The above definition and theorem show that the duality of extension
+ > and intension in NAL corresponds to the duality of intersection and union
+ > in set theory — intensional intersection corresponds to extensional union,
+ > and extensional intersection corresponds to intensional union. Since set
+ > theory is purely extensional, the ‘∪’ is associated to union only. To stress
+ > the symmetry between extension and intense in NAL, here it is called “intensional intersection」, rather than “extensional union」, though the latter
+ > is also correct, and sounds more natural to people familiar with set theory.
+
+ 中译:
+
+ > 上述定义和定理证明了NAL中的外延与内涵的对偶性,对应于集合论中的交与并的对偶性——内涵交对应于外延并,而外延交对应于内涵并。
+ > 因为集合论是纯外延的,所以'∪'只与并集有关。
+ > 为了强调NAL中外延与内涵的对称性,这里称之为「内涵交」,而不是「外延并」,尽管后者也是正确的,对熟悉集合论的人来说听起来更自然。
+
+=#
+
+#= 📝Julia: 泛型类的「类型参数」可以「挂羊头卖狗肉」:s{Int}(a) = s{Float64}(1.0)
+ 此即:在调用类构造方法时,返回的「类型参数」与调用时的「类型参数」**可以不一致**
+ 通过使用参数化类型和条件约束,Julia可以根据不同的类型参数生成不同的实例,并在必要时进行类型转换。这使得代码更加灵活且具有通用性,能够处理多种类型的数据。
+=#
+
+#= 📝Julia: 面向「唯一标识符」时,使用Symbol替代String
+
+ 📌核心:Symbol使用「字符串内联」机制,把每个字符串作为唯一索引,且比对时无需逐个字符比对
+ - 因此:Symbol在用作「唯一标识符」时,比String更有效率
+
+ 英文维基的「字符串内联」资料:
+ > String interning speeds up string comparisons,
+ > which are sometimes a performance bottleneck in applications
+ > (such as compilers and dynamic programming language runtimes)
+ > that rely heavily on associative arrays with string keys to look up the attributes and methods of an object.
+ > Without interning, comparing two distinct strings may involve examining every character of both.
+
+ GPTの答:
+ 在 Julia 中,Symbol 类型通常比 String 类型更具有运行时效率。
+ 这是因为 Symbol 是不可变的类型,而 String 是可变的。
+ - 每当你使用字符串字面量来创建一个新的字符串时,它都会生成一个新的字符串对象,可能会占用更多的内存并导致额外的性能开销。
+ - 而 Symbol 只会创建一个唯一的符号,并且在运行时重复使用相同的符号。这使得 Symbol 比较速度更快,因为可以直接对其进行引用比较。
+
+ 另外,当你需要在代码中频繁地进行字符串操作时,使用 Symbol 也可以提高性能。
+ 字符串操作通常涉及到分割、拼接、查找等操作,而这些操作在 Symbol 上是更高效的,因为它们不涉及复制和重新分配内存空间的开销。
+
+ 但需要注意的是,Symbol 和 String 是不同的数据类型,它们的适用场景也不同。Symbol 主要用于表示标识符、键和常量等不可变概念,而 String 则用于处理文本和字符串操作。
+ 因此,在选择使用 Symbol 还是 String 时,需要根据具体的应用场景和需求来决定。
+
+ 另可参考如下代码:
+ ```julia
+ a = "string_symbol"
+ @time [
+ "string_symbol" == a
+ for _ in 1:0xfffff
+ ]
+ # 0.057884 seconds (31.06 k allocations: 3.075 MiB, 67.64% compilation time)
+ a = :string_symbol
+ @time [
+ :string_symbol == a
+ for _ in 1:0xfffff
+ ]
+ # 0.053276 seconds (38.77 k allocations: 3.656 MiB, 98.21% compilation time)
+ ```
+=#
+
+#= 📝Julia: 嵌套数组的二次展开,直接使用「[(arr...)...]」
+ 例:对「嵌套数组对象」`a = [(1,2),[3,4,5]]`
+ - 有`[(a...)...] == [1,2,3,4,5]`
+=#
+
+# 导出 #
+
+export AbstractVariableType, VariableTypeIndependent, VariableTypeDependent, VariableTypeQuery
+export AbstractStatementType, StatementTypeInheritance, StatementTypeSimilarity, StatementTypeImplication, StatementTypeEquivalence
+export AbstractLogicOperation, And, Or, Not
+export AbstractEI, Extension, Intension
+export AbstractTemporalRelation, Sequential, Parallel
+export AbstractCompoundType, CompoundTypeTermSet, CompoundTypeTermLogicalSet, CompoundTypeTermProduct, CompoundTypeTermImage, CompoundTypeStatementLogicalSet, CompoundTypeStatementTemporalSet
+
+export AbstractTerm, AbstractAtom, AbstractCompound
+
+export terms, ϕ1, ϕ2
+
+export Word, PlaceHolder, Variable, Interval, Operator, CommonCompound, TermImage, Statement
+export placeholder, isplaceholder
+
+
+
+# 作为「类型标记」的类型参数 #
+
+"[NAL-1|NAL-2|NAL-5]陈述类型:继承&相似、蕴含&等价"
+abstract type AbstractStatementType end
+abstract type StatementTypeInheritance <: AbstractStatementType end # NAL-1
+abstract type StatementTypeSimilarity <: AbstractStatementType end # NAL-2
+abstract type StatementTypeImplication{T <: Tense} <: AbstractStatementType end # NAL-5|NAL-7
+abstract type StatementTypeEquivalence{T <: Tense} <: AbstractStatementType end # NAL-5|NAL-7
+
+"[NAL-2]区分「外延」与「内涵」"
+abstract type AbstractEI end # NAL-2
+abstract type Extension <: AbstractEI end
+abstract type Intension <: AbstractEI end
+
+"[NAL-3|NAL-5]集合论/一阶逻辑操作:与或非" # 原创
+abstract type AbstractLogicOperation end
+abstract type And <: AbstractLogicOperation end # 词项→交,陈述→与
+abstract type Or <: AbstractLogicOperation end # 词项→并,陈述→或
+abstract type Not <: AbstractLogicOperation end # 词项→非,陈述→非
+
+"[NAL-6]变量类型" # 【20230724 11:38:25】💭不知道OpenJunars中为何要让「AbstractVariableType」继承AbstractTerm
+abstract type AbstractVariableType end # NAL-6
+abstract type VariableTypeIndependent <: AbstractVariableType end # 独立变量 & 对于
+abstract type VariableTypeDependent <: AbstractVariableType end # 非独变量 # 存在
+abstract type VariableTypeQuery <: AbstractVariableType end # 查询变量 ? 疑问
+
+"[NAL-7]时序合取:区分「序列」与「平行」"
+abstract type AbstractTemporalRelation end
+abstract type Sequential <: AbstractTemporalRelation end
+abstract type Parallel <: AbstractTemporalRelation end
+
+# 复合词项类型
+
+"""
+所有复合词项类型的基类
+"""
+abstract type AbstractCompoundType end
+"[NAL-2]词项集"
+abstract type CompoundTypeTermSet{EI <: AbstractEI} <: AbstractCompoundType end
+"[NAL-2]词项の复合:集合操作⇒复合集"
+abstract type CompoundTypeTermLogicalSet{EIType <: AbstractEI, LogicOperation <: AbstractLogicOperation} <: AbstractCompoundType end
+"[NAL-4]乘积"
+abstract type CompoundTypeTermProduct <: AbstractCompoundType end
+"[NAL-4]像"
+abstract type CompoundTypeTermImage{EIType <: AbstractEI} <: AbstractCompoundType end
+"[NAL-5]陈述逻辑集: {与/或/非}"
+abstract type CompoundTypeStatementLogicalSet{LogicOperation <: AbstractLogicOperation} <: AbstractCompoundType end
+"[NAL-7]陈述时序集 <: 陈述逻辑集{与}"
+abstract type CompoundTypeStatementTemporalSet{TemporalRelation <: AbstractTemporalRelation} <: CompoundTypeStatementLogicalSet{And} end
+
+# 正式对象 #
+
+"一切词项的总基础" # OpenJunars所谓「FOTerm」实际上就是此处的「AbstractTerm」,只因OpenJunars把「变量类型」也定义成了词项
+abstract type AbstractTerm end
+
+
+"[NAL-1]所有的原子词项 | 协议:支持`nameof`方法"
+abstract type AbstractAtom <: AbstractTerm end
+import Base: nameof
+
+"[NAL-2]复合词项の基石 | 协议:支持`terms`方法(无需绑定属性)"
+abstract type AbstractCompound{type <: AbstractCompoundType} <: AbstractTerm end
+function terms end
+
+"[NAL-1]陈述词项の基石 | 协议:支持`terms`、`ϕ1`和`ϕ2`方法(无需绑定属性)"
+abstract type AbstractStatement{type <: AbstractStatementType} <: AbstractTerm end
+function ϕ1 end; function ϕ2 end
+
+# 具体结构定义
+
+begin "单体词项"
+
+ """
+ [NAL-1]最简单的「词语」词项
+
+ 参考:《NAL》定义2.1
+ > The basic form of a term is a word, that is, a string of characters from a finite alphabet.
+ > There is no additional requirement on the alphabet.
+ > In this document the alphabet includes English letters, digits 0 to 9, and a few special signs, such as hyphen (‘-’).
+ > In the examples in this book, we often use common English nouns for terms, such as bird and animal, just to make the examples easy to understand.
+ > There is no problem to do the same in a different natural language, such as Chinese.On the other hand, it is also fine to use terms that are meaningless to human beings, such as drib and aminal.
+
+ 中译:
+ > 一个词项的基本形式是一个「词语」,即来自有限字母表的一串字符。
+ > 除此之外对字母表没有要求。
+ > 本书中字母表包括英文字母、数字0 ~ 9和一些特殊符号,如「-」,并常用常见的英语名词来表示术语,例如bird和animal,只是为了使示例易于理解。
+ > 用一种不同的自然语言(如中文)做同样的事情是没有问题的。另一方面,也可以使用对人类没有意义的术语,如drib和aminal。
+
+ """
+ struct Word <: AbstractAtom
+ name::Symbol # 为何不用String?见上文笔记
+
+ "加入合法性检查"
+ Word(name::Symbol) = check_valid_explainable(
+ new(name)
+ ) # 增加合法性检查_explainable
+ end
+
+ """
+ 支持从String构造
+ - 目的:处理从(AST)解析中返回的字符串参数
+ """
+ Word(name::Union{AbstractString, AbstractChar}) = name |> Symbol |> Word
+
+ raw"""
+ [NAL-4]像占位符
+ - 现在作为一个独立的类,而非使用Nothing类型
+ - 单例模式,只有一个`PlaceHolder()`对象
+ - 按照原子词项的原则处理
+ - 可以被视作「Narsese中的Nothing」
+ - ⚠《NAL》定义中「像占位符不可出现在第一个位置,其为关系词项所保留」的特性,留给构造时合法性检查
+ - 实现参考:OpenJunars `terms.jl`;其它NARS实现的处理方式:
+ - OpenNARS:设置一个字符串常量为`_`,并在解析「像」时直接识别,作为「占位符位置」存入`ImageXXt`类型中
+ - 参见:OpenNARS 3.1.2 `Symbols.java` `StringParser.java`
+ - ONA:直接在解析时解析成「占位符位置」``
+ - 参见:ONA 0.9.2 `Narsese.c`
+ - PyNARS:设置一个名为`_`的词语,在解析时直接识别,作为「占位符位置」存入`XXtensionalImage`类型中
+ - 参见:PyNARS `Term.py` `Compound.py`
+
+ 参考:《NAL》定义8.4
+ > where ‘⋄’ is a special symbol indicating the location of T1 or T2 in the product,
+ > and in the component list it can appear in any place, except the first (which is reserved for the relational term).
+ > When it appears at the second place, the image can also be written in infix format as (R / T2) or (R \ T2).
+
+ 中译:
+ > 其中『⋄』是表示T1或T2在乘积中的位置的特殊符号;
+ > 在组分列表中,它可以出现在任何位置,除了第一个位置(它是为关系词项保留的)。
+ > 当它出现在第二位时,像也可以用中缀格式写成 (R / T2) 或 (R \ T2)。
+ """
+ struct PlaceHolder <: AbstractAtom end
+ "像占位符单例模式下的唯一实例"
+ const placeholder::PlaceHolder = PlaceHolder()
+ "检测是否为像占位符: 类似`isnothing`"
+ isplaceholder(x) = x === PlaceHolder
+ isplaceholder(::PlaceHolder) = true
+
+ "【!即将弃用:请使用`Base.nameof`方法,而非直接调用属性`name`】兼容`.name`属性:对像占位符的任何属性访问都将返回空字符串"
+ Base.getproperty(::PlaceHolder, ::Symbol)::String = ""
+ "兼容构造方法`constructor(string|expr|...)`: 直接返回`placeholder`"
+ PlaceHolder(::Any) = placeholder
+
+ """
+ [NAL-6]变量词项(用类型参数包括三种类型)
+
+ 参考:《NAL》定义10.1~2
+ > A query variable is a variable term in a question that represents a constant term to be found to answer the question,
+ > and it is named by ‘?’,
+ > optionally followed by a word or a number.
+
+ > An independent variable represents any unspecified term under a given restriction,
+ > and it is named by a word (or a number) preceded by ‘#’.
+ > A dependent variable represents a certain unspecified term under a given restriction,
+ > and it is named as an independent variable with a dependency list consisting of independent variables it depends on,
+ > which can be empty.
+
+ 中译:
+ > 查询变量是问题中的一个变量项,
+ > 它表示要找到的用于回答问题的常量项,
+ > 它被命名为'?',
+ > 可选后跟一个单词或数字。
+
+ > 独立变量表示给定限制下的任何未指定项,
+ > 并以「#」前面的单词(或数字)命名。
+ > 非独变量表示给定限制下的某个未指定项,
+ > 它被命名为具有由它所依赖的独立变量组成的依赖列表的独立变量,
+ > 该列表可以为空。
+ """
+ struct Variable{T <: AbstractVariableType} <: AbstractAtom
+ name::Symbol
+
+ "加入合法性检查"
+ Variable{T}(name::Symbol) where {T <: AbstractVariableType} = check_valid_explainable(
+ new(name)
+ ) # 增加合法性检查
+ end
+ "支持从String构造"
+ Variable{T}(name::Union{AbstractString, AbstractChar}) where {T<:AbstractVariableType} = name |> Symbol |> Variable{T}
+
+ """
+ [NAL-7]间隔(Interval)
+
+ 迁移自:PyNARS Interval.py
+ - 其中Interval类继承Term
+ - ⚠OpenNARS、OpenJunars中没有相关实现
+
+ 参考:《NAL》定义11.4
+
+ > The real-time experience of a NARS is a sequence of Narsese sentences, separated by non-negative numbers indicating the interval between the arriving time of subsequent sentences, measured by the system’s internal clock.
+
+ 中译:
+ > NARS的实时经验是一系列的Narsese句子,由非负数分隔,这些非负数表示后续句子到达时间之间的间隔,由系统的内部时钟测量。
+
+ 【20230815 17:19:44】因「字符串转换器字典查找问题」与「不同精度区分必要性小」不再区分精度:统一至UInt
+ 【20230817 15:03:35】作为NAL-7中的「事件」对象,「该对象为原子词项」只是在「组成结构」上的区分,其仍然可被认作是「事件」
+ """
+ struct Interval <: AbstractAtom
+
+ "【!即将弃用:现在使用`nameof`方法,而非外加属性】(只读as缓存)继承自原子词项"
+ name::Symbol # 【20230817 15:02:57】现在与其它原子词项统一使用Symbol
+
+ "间隔长度"
+ interval::UInt
+
+ "内部构造方法:自动获得名称并缓存"
+ Interval(interval::UInt) = check_valid_explainable(
+ new(
+ Symbol(interval), # 缓存名称
+ interval # 存储值
+ )
+ )
+ end
+
+ "外部构造方法 兼容所有实数(浮点数亦兼容)"
+ @inline Interval(interval::Real) = Interval(
+ convert(UInt, interval)
+ )
+
+ "外部构造方法 兼容以自身名称「纯数字」定义的字符串"
+ @inline Interval(s::Union{AbstractString, AbstractChar}) = Interval(parse(UInt, s))
+
+ "外部构造方法 兼容以自身名称「纯数字」定义的符号"
+ @inline Interval(s::Symbol) = Interval(string(s))
+
+ """
+ [NAL-8]操作词项(Action)
+
+ 参考:《NAL》定义12.2
+
+ > An atomic operation is represented as an operator (a special term whose name starts with ‘⇑’)
+ > followed by an argument list (a sequence of terms, though can be empty).
+ > Within the system, operation “(⇑op a₁ ··· aₙ)” is treated as statement “(× self a₁ ··· aₙ) → op」,
+ > where op belongs to a special type of term that has a procedural interpretation,
+ > and self is a special term referring to the system itself.
+
+ 中译:
+ > 一个原子操作表示为一个操作符(一个特殊的词项,其名以「⇑」开头)跟一个参数列表(一个词项序列,但可为空)。
+ > 在系统内,操作「(⇑op a₁ ··· aₙ)」被视为语句「(× self a₁ ··· aₙ) → op」,
+ > 其中op属于具有程序解释的特殊类型词项,【译者注:此「程序解释的特殊类型」即此处定义的类】
+ > 而self是指系统本身的特殊词项。【译者注:此即NAL代码中经常出现的`{SELF}`】
+ """
+ struct Operator <: AbstractAtom
+ name::Symbol
+
+ "加入合法性检查"
+ Operator(name::Symbol) = check_valid_explainable(
+ new(name)
+ ) # 增加合法性检查
+ end
+ "支持从String构造"
+ Operator(name::Union{AbstractString, AbstractChar}) = name |> Symbol |> Operator
+
+ """
+ 通用复合词项
+
+ 包括:
+ - 词项集
+ - 外延集
+ - 内涵集
+ - 词项逻辑集
+ - 外延交/内涵交
+ - 外延并/内涵并(自动重定向)
+ - 外延差/内涵差
+ - 陈述集
+ - 陈述逻辑集
+ - 合取
+ - 析取
+ - 否定
+ - 陈述时序集
+
+ 不包括:
+ - 外延像/内涵像(需要使用额外的「像占位符索引」)
+ - 📄参考:`OpenNARS/ImageExt.java relationIndex`
+ - 陈述
+
+ NAL参考
+
+ [NAL-2]词项集 {} []
+
+ 参考:《NAL》定义6.3、6.5
+ > If T is a term, the extensional set with T as the only component, {T}, is defined by (∀x)((x → {T}) ⟺ (x ↔ {T})).
+ > If T is a term, the intensional set with T as the only component, [T], is defined by (∀x)(([T] → x) ⟺ ([T] ↔ x)).
+
+ 中译:
+ > 如果T是一个词项,则以T为唯一组分的外延集 {T} 定义为 (∀x)((x → {T}) ⟺ (x ↔ {T}))。
+ > 如果T是一个词项,则以T为唯一组分的内涵集 [T] 定义为 (∀x)(([T] → x) ⟺ ([T] ↔ x))。
+
+ [NAL-3]词项逻辑集 {外延/内涵, 交/并/差} # 此处「&」「|」是对应的「外延交&」「外延并|」
+ - And: 交集 ∩& ∩|
+ - Or : 并集 ∪& ∪|
+ - 注意:此处不会使用,会自动转换(见📝「为何不使用外延/内涵 并?」)
+ - Not: 差集 - ~
+ - 有序(其余皆无序)
+
+ 参考:《NAL》定义7.6~9
+ > Given terms T1 and T2, their extensional intersection (T1 ∩ T2)
+ > is a compound term defined by (∀x)((x → (T1 ∩ T2)) ⟺ ((x → T1) ∧ (x → T2))).
+ > Given terms T1 and T2, their intensional intersection (T1∪T2)
+ > is a compound term defined by (∀x)(((T1 ∪ T2) → x) ⟺ ((T1 → x) ∧ (T2 → x))).
+ > If T1 and T2 are different terms, their extensional difference (T1 - T2)
+ > is a compound term defined by (∀x)((x → (T1 - T2)) ⟺((x → T1) ∧ ¬(x → T2))).
+ > If T1 and T2 are different terms, their intensional difference (T1⊖T2)
+ > is a compound term defined by (∀x)(((T1⊖T2) → x) ⟺ ((T1 → x) ∧ ¬(T2 → x))).
+
+
+ 中译:
+ > 给定词项T1与T2,它们的外延交(T1∩T2)是一个复合词项,定义为 (∀x)((x → (T1 ∩ T2)) ⟺ ((x → T1) ∧ (x → T2)))。
+ > 给定词项T1与T2,它们的内涵交(T1∪T2)是一个复合词项,定义为 (∀x)(((T1 ∪ T2) → x) ⟺ ((T1 → x) ∧ (T2 → x)))。
+ > 如果T1和T2是不同的词项,它们的外延差(T1-T2)是一个复合词项,定义为 (∀x)((x → (T1 - T2)) ⟺((x → T1) ∧ ¬(x → T2)))。
+ > 如果T1和T2是不同的词项,它们的内涵差(T1 * T2)是一个复合词项,定义为 (∀x)(((T1⊖T2) → x) ⟺ ((T1 → x) ∧ ¬(T2 → x)))。
+
+ [NAL-4]乘积 (*, ...)
+ - 有序
+ - 无内涵外延之分
+ - 用于关系词项「(*, 水, 盐) --> 前者可被后者溶解」
+
+ 参考:《NAL》定义8.1
+ > The product connector ‘×’ takes two or more terms as components,
+ > and forms a compound term that satisfies ((× S₁ ··· Sₙ) → (× P₁ ··· Pₙ)) ⟺ ((S₁ → P₁) ∧ ··· ∧ (Sₙ → Pₙ)).
+
+ 中译:
+ > 乘积连接符「×」采用两个或多个词项作为组分,形成一个复合词项,
+ > 满足 ((× S₁ ··· Sₙ) → (× P₁ ··· Pₙ)) ⟺ ((S₁ → P₁) ∧ ··· ∧ (Sₙ → Pₙ))。
+
+ [NAL-5]陈述逻辑集:{与/或/非}
+ - And: 陈述与 ∧ && Conjunction
+ - Or : 陈述或 ∨ || Disjunction
+ - Not: 陈述非 ¬ --
+
+ 注意:都是「对称」的⇒集合(无序)
+
+ 参考:《NAL》定义9.6
+
+ > When S1 and S2 are different statements,
+ > their conjunction, (S1 ∧ S2), is a compound statement defined by
+ > (∀x)((x ⇒ (S1 ∧ S2)) ⟺ ((x ⇒ S1) ∧ (x ⇒ S2))).
+ > Their disjunction, (S1 ∨ S2), is a compound statement defined by
+ > (∀x)(((S1 ∨ S2) ⇒ x) ⟺ ((S1 ⇒ x) ∧ (S2 ⇒ x))).
+
+ 中译:
+ > 当S1和S2是不同的陈述时,
+ > 它们的合取(S1∧S2)是一个复合陈述,定义为
+ > (∀x)((x ⇒ (S1 ∧ S2)) ⟺ ((x ⇒ S1) ∧ (x ⇒ S2))).
+ > 它们的析取(S1∨S2)是一个复合陈述,定义为
+ > (∀x)(((S1 ∨ S2) ⇒ x) ⟺ ((S1 ⇒ x) ∧ (S2 ⇒ x))).
+
+ 【20230817 15:44:10】细节:OpenJunars外其它NARS实现中,对复合词项的对待方法不同——是否要再度合并?
+ - 在PyNARS中,陈述逻辑集、陈述时序集对元素类型无所限制,可以混用
+ - 在OpenNARS中,所有复合词项统一使用`CompoundTerm`实现,并将连接词用单一的字符串存储
+
+ [NAL-7]陈述时序集:{序列/平行} <: 抽象陈述逻辑集{合取}
+ - 与 `&/`: 序列合取(有序)
+ - 或 `&|`: 平行合取(无序)
+
+ 📌技术点: 此中的数据`terms`为一个指向「向量/集合」的引用
+ - 即便其类型确定,它仍然是一个「指针」,不会造成效率干扰
+
+ 参考:《NAL》定义11.5
+ > The conjunction connector (‘∧’) has two temporal variants: 「sequential conjunction」 (‘,’) and “parallel conjunction」 (‘;’).
+ > 「(E1, E2)” corresponds to the compound event consisting of E1 followed by E2, and “(E1; E2)” corresponds to the compound event consisting of E1 accompanied by E2.
+
+ 中译:
+ > 合取连接符 (‘∧’) 有两种时序变体变体:「序列合取」 (‘,’) 和「平行合取」 (‘;’)。
+ > 「(E1, E2)」 对应由E1后接E2,「(E1; E2)」 对应由E1伴随E2组成的复合事件。
+ """
+ struct CommonCompound{type <: AbstractCompoundType} <: AbstractCompound{type}
+
+ """
+ 有序不可变元组/集合
+ - 承继旧`terms`字段
+ - 保证词项构造之后不会改变
+ - 一切语法上的限制,都交给「合法性检查」函数
+ - 例如:陈述逻辑集只能装陈述
+ - 例如:
+ """
+ terms::Tuple{Vararg{<:AbstractTerm}}
+
+ """
+ 统一的内部构造方法
+ - 统一具备合法性检查
+ - 根据外部函数「构造器类型」获取构造器(支持重定向)
+ - 根据「可重复性」筛选掉重复项
+ """
+ function CommonCompound{type}(terms::Tuple{Vararg{AbstractTerm}}) where {type <: AbstractCompoundType}
+ # 根据「可重复性」筛选掉重复项,根据「可交换性」决定是否排序
+
+ # 生成并处理数组
+ terms_arr::Vector{AbstractTerm} = collect(terms) # 创建新数组
+ is_repeatable(type) || unique!(terms_arr) # 若不可重复,筛选重复项(不会改变内容顺序)
+ is_commutative(type) && sort!(terms_arr) # 若可交换,排序(不会改变内容)
+
+ terms_tuple::Tuple = Tuple{Vararg{AbstractTerm}}(terms_arr) # 创建新元组
+ constructor::Type = constructor_type(type) # 【20230818 0:30:25】注意:new不能当参数传递
+ # 增加合法性检查
+ return check_valid_explainable(
+ constructor <: AbstractCompoundType ?
+ new{constructor}(terms_tuple) :
+ constructor(terms_tuple)
+ )
+ end
+
+ #= 各个「具体类型」的内部构造方法 =#
+
+ # 词项逻辑集
+
+ "(有序)差集 Difference{外延/内涵} - ~" # 注意:这是二元的 参数命名参考自OpenJunars
+ function CommonCompound{CompoundTypeTermLogicalSet{EIType, Not}}(ϕ₁::AbstractTerm, ϕ₂::AbstractTerm) where EIType # 此EIType构造时还会被检查类型
+ ϕ₁ == ϕ₂ && error("不允许重复词项「$ϕ1==$ϕ2」!")
+ check_valid_explainable(
+ new{CompoundTypeTermLogicalSet{EIType, Not}}(
+ (ϕ₁, ϕ₂) # 【20230814 13:21:55】不可交换,直接构造元组,但因「不可重复」需要筛选;参考《NAL》中`different`
+ )
+ ) # 增加合法性检查
+ end
+
+ "陈述非 Negation"
+ function CommonCompound{CompoundTypeStatementLogicalSet{Not}}(ϕ::AbstractTerm)
+ check_valid_explainable(
+ new{CompoundTypeStatementLogicalSet{Not}}((ϕ,)) # 只有一个,且不要求是陈述(留给「合法性检查」;PyNARS也兼容「非陈述元素」)
+ ) # 增加合法性检查
+ end # 内涵并=外延交
+
+ end
+
+ """
+ 统一的「类型重定向」函数:从
+ - 避免「方法歧义冲突」`XXX is ambiguous.`
+ - 开放给其它自定义复合词项类型
+
+ @返回值:构造方法
+ @默认逻辑:返回type自身,指导使用默认构造方法
+ - 若为「复合词项类型」则指导构造方法重定向至`new{type}`
+ """
+ @inline constructor_type(type::Type)::Type = type
+ @inline (constructor_type(::Type{CompoundTypeTermImage{EI}})::Type) where {EI <: AbstractEI} = @show TermImage{EI}
+
+ "(无序,重定向)并集 Union{外延/内涵} ∪& ∪|" # 【20230724 14:12:33】暂且自动转换成交集(返回值类型参数转换不影响)(参考《NAL》定理7.4)
+ @inline function constructor_type(::Type{T}) where T <: CompoundTypeTermLogicalSet{Extension, Or}
+ CompoundTypeTermLogicalSet{Intension, And}
+ end # 外延并=内涵交 【20230818 0:13:02】不知为何,不写成`where`就会报错「syntax: invalid variable expression in "where" around 」
+ @inline function constructor_type(::Type{T}) where T <: CompoundTypeTermLogicalSet{Intension, Or}
+ CompoundTypeTermLogicalSet{Extension, And}
+ end
+
+ "外部构造方法:统一的「任意长参数」"
+ @inline function CommonCompound{type}(terms::Vararg{AbstractTerm}) where {type <: AbstractCompoundType}
+ CommonCompound{type}(terms) # 直接传递封装好的Tuple
+ end
+
+ "除元组以外的支持的迭代器类型"
+ const SUPPORTED_ALIAS_ITERATORS::Type = Union{
+ Base.Generator,
+ AbstractArray,
+ Set,
+ }
+
+ "外部构造方法:重载各类迭代器"
+ @inline function CommonCompound{type}(itr::SUPPORTED_ALIAS_ITERATORS) where {type}
+ CommonCompound{type}(
+ Tuple{Vararg{AbstractTerm}}(itr)
+ )
+ end
+
+ raw"""
+ [NAL-4]像{外延/内涵} (/, a, b, _, c) (\, a, b, _, c)
+ - 有序
+ - 【20230724 22:06:36】注意:词项在terms中的索引,不代表其在实际情况下的索引
+
+ 例:`TermImage{Extension}([a,b,c], 3)` = (/, a, b, _, c)
+
+ 参考:《NAL》定义8.4
+ > For a relation R and a product (× T1 T2),
+ > the extensional image connector, ‘/’, and intensional image connector, ‘\’,
+ > of the relation on the product are defined as the following, respectively:
+ > ((× T1 T2) → R) ⟺ (T1 → (/ R ⋄ T2)) ⟺ (T2 → (/ R T1 ⋄))
+ > (R → (× T1 T2)) ⟺ ((\ R ⋄ T2) → T1) ⟺ ((\ R T1 ⋄) → T2)
+
+ 中译:
+ > 对于关系R和乘积(× T1 T2),乘积上关系的外延像连接符「/」和内延像连接符「\」分别定义为:
+ > ((× T1 T2) → R) ⟺ (T1 → (/ R ⋄ T2)) ⟺ (T2 → (/ R T1 ⋄))
+ > (R → (× T1 T2)) ⟺ ((\ R ⋄ T2) → T1) ⟺ ((\ R T1 ⋄) → T2)
+
+ """
+ struct TermImage{EIType <: AbstractEI} <: AbstractCompound{CompoundTypeTermImage{EIType}}
+ terms::Tuple{Vararg{AbstractTerm}}
+ relation_index::Unsigned # 「_」的位置(一个占位符,保证词项中只有一个「_」)
+
+ """
+ 限制占位符位置(0除外)
+
+ 📌莫使用`Tuple{Vararg{T}} where T <: AbstractTerm`
+ - 理:Julia参数类型的「不变性」,参数类型的子类关系不会反映到整体上
+ - 例: `Tuple{Int} <: Tuple{Integer} == false`
+ - 因:此用法会限制Tuple中「只能由一种类型」
+ - 因而产生「无方法错误」(其中有「!Matched::Tuple{Vararg{T}}」)
+ - 解:直接使用`Tuple{AbstractTerm}`
+ - 其可以包含任意词项,而不会被限制到某个具体类型中
+ - 例如:只用`Tuple{Integer}`而不用`Tuple{Int}`
+ """
+ function TermImage{EIType}(terms::Tuple{Vararg{AbstractTerm}}, relation_index::Unsigned) where {EIType}
+ relation_index == 0 || @assert relation_index ≤ length(terms) + 1 "索引`$relation_index`越界!"
+ # 其默认已无序
+ check_valid_explainable(
+ new{EIType}(terms, relation_index) # 加入合法性检查
+ ) # 增加合法性检查
+ end
+ end
+
+ "类型适配:对有符号整数的映射"
+ @inline function TermImage{EIType}(terms::Tuple{Vararg{AbstractTerm}}, relation_index::Integer) where {EIType}
+ TermImage{EIType}(terms, unsigned(relation_index))
+ end
+
+ "转换兼容支持:多参数构造(倒过来,占位符位置放在最前面)"
+ @inline function TermImage{EIType}(relation_index::Integer, terms::Vararg{AbstractTerm}) where EIType
+ TermImage{EIType}(terms, unsigned(relation_index))
+ end
+
+ "转换兼容支持:多参数构造(兼容「词项序列」,使用新的「像占位符」单例类型)"
+ function TermImage{EIType}(terms::Vararg{AbstractTerm}) where EIType
+ placeholder_index::Union{Integer, Nothing} = findfirst(isplaceholder, terms)
+ isnothing(placeholder_index) && error("在参数「$terms」中未找到像占位符位置!")
+ TermImage{EIType}(
+ filter(!isplaceholder, terms), # 过滤出所有非占位符词项
+ unsigned(placeholder_index),
+ )
+ end
+
+ "转换兼容支持:从元组以外的其它迭代器构造"
+ @inline function TermImage{EIType}(array::SUPPORTED_ALIAS_ITERATORS) where EIType
+ TermImage{EIType}(array...)
+ end
+
+end
+
+begin "陈述词项"
+
+ raw"""
+ [NAL=1|NAL-5]陈述Statement{继承/相似/蕴含/等价/...} --> <-> ==> <=> ...
+ - 现只支持「二元」陈述,只表达两个词项之间的关系
+ - ❎【20230804 14:17:30】现增加「时序」参数,以便在词项层面解析「时序关系」
+ - 【20230804 14:44:13】现把「时序系词」作为「主系词」(参考自OpenNARS)
+ - 【20230812 22:19:20】加入「合法性检查」机制
+
+ 参考:《NAL》定义2.2、6.1、9.1、9.5、11.6、11.7
+ 继承
+ 参考:《NAL》定义2.2
+ > The basic form of a statement is an inheritance statement,
+ > 「S → P」, where S is the subject term, P is the predicate term, and ‘→’ is the inheritance copula,
+ > defined as being a reflexive and transitive relation from one term to another term.
+
+ 中译:
+ > 陈述的基本形式是继承陈述「S→P」,
+ > 其中S为主词项,P为谓词项,「→」为继承系词,
+ > 定义为从一个词项到另一个词项的自反传递关系。
+ 相似
+ 参考:《NAL》定义6.1
+ > For any terms S and P, similarity ‘↔’ is a copula defined by
+ > (S ↔ P) ⟺ ((S → P) ∧ (P → S)).
+
+ 中译:
+ > 对于任何词项S和P,相似『↔』是由下者定义之词项:
+ > (S ↔ P) ⟺ ((S → P) ∧ (P → S))。
+
+ 蕴含
+ 参考:《NAL》定义9.1
+ > If S1 and S2 are statements, “S1 ⇒ S2” is true if and only if in IL S2 can be derived from S1 in a finite number of inference steps.
+ > Here ‘⇒’ is the implication copula. Formally, it means (S1 ⇒ S2) ⟺ {S1} ⊢ S2.
+
+ 中译:
+ > 如果 S1 和 S2 是陈述,则「S1 ⇒ S2」为真,如果且仅当在 IL 中,S2 可以从 S1 进行有限数量的推理步骤而得出。
+ > 这里的『⇒』是「蕴含」系词。形式上,它的意思是 (S1 ⇒ S2) ⟺ {S1} ⊢ S2。
+ 等价
+ 参考:《NAL》定义9.5
+ > The equivalence copula, ‘⇔’, is defined by
+ > (A ⇔ C) ⟺ ((A ⇒ C) ∧ (C ⇒ A))
+ > As a special type of compound terms, compound statements can be used to summarize existing statements.
+
+ 中译:
+ > 「等价」系词『⇔』的定义是
+ > (A ⇔ C) ⟺ ((A ⇒ C) ∧ (C ⇒ A))
+
+ 时序蕴含/等价
+
+ 参考:《NAL》定义11.6
+ > For an implication statement “S ⇒ T” between events S and T, three different temporal relations can be specified:
+ > (1) If S happens before T happens,
+ > the statement is called “predictive implication」, and is rewritten as “S /⇒ T」,
+ > where S is called a sufficient precondition of T,
+ > and T a necessary postcondition of S.
+ > (2) If S happens after T happens,
+ > the statement is called “retrospective implication」, and is rewritten as “S \⇒ T」,
+ > where S is called a sufficient postcondition of T,
+ > and T a necessary precondition of S.
+ > (3) If S happens when T happens,
+ > the statement is called “concurrent implication」, and is rewritten as “S |⇒ T」,
+ > where S is called a sufficient co-condition of T,
+ > and T a necessary co-condition of S.
+
+ 中译:
+ > 对于事件S和T之间的蕴含语句「S⇒T」,可以指定三种不同的时间关系:
+ > (1)如果S发生在T发生之前,该陈述称为「预测性蕴含」,并重写为「S/⇒T」,
+ > 其中S是T的充分前提,T是S的必要后置条件。
+ > (2)如果S发生在T发生之后,该陈述称为「回顾性蕴含」,并重写为「S\⇒T」,
+ > 其中S是T的充分后置条件,T是S的必要前提。
+ > (3)如果T发生时S同时发生,该陈述称为「并发性蕴含」,并重写为「S|⇒T」,
+ > 其中S是T的充分协条件,T是S的必要协条件。
+
+ 参考:《NAL》定义11.7
+ Three “temporal equivalence」 (predictive, retrospective,
+ and concurrent) relations are defined as the following:
+ > (1) 「S /⇔ T」 (or equivalently, 「T \⇔ S」) means that S is an equivalent precondition of T, and T an equivalent postcondition of S.
+ > (2) 「S |⇔ T” means that S and T are equivalent co-conditions of each other.
+ > (3) To simplify the language, 「T \⇔ S” is always represented as “S /⇔ T」, so the copula “ \⇔” is not actually included in the grammar of Narsese.
+
+ 中译:
+ 三个「时间等价」(预测性、回顾性、并发性)关系定义如下:
+ > (1)「S /⇔ T」(或等价地,「T \⇔ S」)表示S是T的等价前提,T是S的等价后置条件。
+ > (2)「S |⇔ T」表示S和T是彼此的等价共条件。
+ > (3)为了简化语言,「T \⇔ S」总是被表示为「S /⇔ T」,所以关联词「\⇔」实际上并不在Narsese语法中。
+ > - 译者注:此举与先前的「外延并/内涵并」类似
+ """
+ struct Statement{type <: AbstractStatementType} <: AbstractStatement{type}
+ ϕ1::AbstractTerm # subject 主词
+ ϕ2::AbstractTerm # predicate 谓词
+
+ """
+ 内部构造方法
+ - 【20230812 22:20:01】现调用外部定义的「内联可解释合法性检查」函数
+ """
+ function Statement{type}(
+ ϕ1::AbstractTerm, ϕ2::AbstractTerm,
+ ) where {type <: AbstractStatementType}
+ check_valid_explainable(
+ is_commutative(type) ? # 可交换⇒排序
+ new{type}(sort!([ϕ1, ϕ2])...) :
+ new{type}(ϕ1, ϕ2)
+ ) # 增加合法性检查
+ end
+ end
+
+ "转换兼容支持:从迭代器构造"
+ Statement{type}(iter) where type = Statement{type}(iter...)
+
+end