Add convertions and CaseIterable helpers
This commit is contained in:
parent
f0dee409b0
commit
f7dcd8bcdb
|
@ -27,3 +27,9 @@ extension GeneralizedModusPonens: FuzzySet {
|
|||
composition[element]
|
||||
}
|
||||
}
|
||||
|
||||
extension GeneralizedModusPonens: AnyFuzzySetRepresentable {
|
||||
public func eraseToAnyFuzzySet() -> AnyFuzzySet<V> {
|
||||
.init { composition[$0] }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,21 @@ public struct FuzzyRelationsComposition<U, V, W, Seq: Sequence> where Seq.Elemen
|
|||
}
|
||||
}
|
||||
|
||||
public extension FuzzyRelationsComposition where V: CaseIterable, Seq == V.AllCases {
|
||||
init(
|
||||
_ relationUV: BinaryFuzzyRelation<U, V>,
|
||||
_ relationVW: BinaryFuzzyRelation<V, W>,
|
||||
method: CompositionMethod = .maxmin
|
||||
) {
|
||||
self.relationUV = relationUV
|
||||
self.relationVW = relationVW
|
||||
self.sequence = V.allCases
|
||||
self.method = method
|
||||
}
|
||||
}
|
||||
|
||||
extension FuzzyRelationsComposition: FuzzySet {
|
||||
/// - Complexity: O(*n*) where *n* is the number of elements in `self.sequence` (number of elements of `V` to be iterated over via `Seq`)
|
||||
public func grade(forElement element: (U, W)) -> Grade {
|
||||
let u = element.0
|
||||
let w = element.1
|
||||
|
|
|
@ -12,6 +12,7 @@ public struct FuzzySetComposition<U, V, Seq: Sequence> where Seq.Element == U {
|
|||
}
|
||||
|
||||
extension FuzzySetComposition: FuzzySet {
|
||||
/// - Complexity: O(*n*) where *n* is the number of elements in `self.set.sequence` (number of elements of `V` to be iterated over via `Seq`)
|
||||
public func grade(forElement element: V) -> Grade {
|
||||
set.map {
|
||||
min($0.grade, relation[$0.element, element])
|
||||
|
|
|
@ -26,6 +26,18 @@ public struct IterableFuzzySet<Universe, S: Sequence> where S.Element == Univers
|
|||
}
|
||||
}
|
||||
|
||||
public extension IterableFuzzySet where Universe: CaseIterable, S == Universe.AllCases {
|
||||
init(membershipFunction: MembershipFunction<Universe>) {
|
||||
self.sequence = Universe.allCases
|
||||
self.function = membershipFunction
|
||||
}
|
||||
|
||||
init(membershipFunction: @escaping MembershipFunction<Universe>.FunctionType) {
|
||||
self.sequence = Universe.allCases
|
||||
self.function = .init(membershipFunction)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Fuzzy set
|
||||
|
||||
extension IterableFuzzySet: FuzzySet {
|
||||
|
@ -102,16 +114,34 @@ public extension AnyFuzzySet {
|
|||
}
|
||||
}
|
||||
|
||||
public extension AnyFuzzySet where Universe: CaseIterable {
|
||||
func makeIterable() -> IterableFuzzySet<Universe, Universe.AllCases> {
|
||||
.init(Universe.allCases, membershipFunction: membershipFunction)
|
||||
}
|
||||
}
|
||||
|
||||
public extension DiscreteMutableFuzzySet {
|
||||
func makeIterable() -> IterableFuzzySet<Universe, Dictionary<Universe, Grade>.Keys> {
|
||||
.init(grades.keys, membershipFunction: .fromDictionary(grades))
|
||||
}
|
||||
|
||||
func makeIterable<S: Sequence>(_ sequence: S) -> IterableFuzzySet<Universe, S> {
|
||||
func makeIterable<S: Sequence>(over sequence: S) -> IterableFuzzySet<Universe, S> {
|
||||
.init(sequence, membershipFunction: .init { self[$0] })
|
||||
}
|
||||
}
|
||||
|
||||
public extension DiscreteMutableFuzzySet where Universe: CaseIterable {
|
||||
func makeIterable() -> IterableFuzzySet<Universe, Universe.AllCases> {
|
||||
.init(Universe.allCases, membershipFunction: .fromDictionary(grades))
|
||||
}
|
||||
}
|
||||
|
||||
public extension IterableFuzzySet where Universe: Hashable {
|
||||
func makeDiscreteMutable() -> DiscreteMutableFuzzySet<Universe> {
|
||||
.init(.init(uniqueKeysWithValues: sequence.map { ($0, self[$0]) }))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
public extension IterableFuzzySet {
|
||||
|
|
|
@ -47,6 +47,33 @@ class IterableFuzzySetTests: XCTestCase {
|
|||
XCTAssertEqual(result, expected)
|
||||
}
|
||||
|
||||
func test_initFromCaseIterableEnum_sequenceNotRequired() {
|
||||
enum U: Int, CaseIterable {
|
||||
case a, b, c, d, e, f, g, h, i, j, k
|
||||
}
|
||||
|
||||
let sut = IterableFuzzySet { (u: U) in
|
||||
Double(u.rawValue) / Double(U.allCases.count)
|
||||
}
|
||||
|
||||
let sut2 = IterableFuzzySet(membershipFunction: MembershipFunction<U>.one)
|
||||
|
||||
XCTAssertEqual(Array(sut).map { $0.element }, U.allCases)
|
||||
XCTAssertEqual(Array(sut2).map { $0.element }, U.allCases)
|
||||
}
|
||||
|
||||
func test_initFromDiscreteMutableWhenCaseIterable_noAmbiguity() {
|
||||
enum U: CaseIterable {
|
||||
case a, b, c, d, e, f, g, h, i, j, k
|
||||
}
|
||||
|
||||
let fs = DiscreteMutableFuzzySet(.init(uniqueKeysWithValues: U.allCases.map { ($0, 0.42) }))
|
||||
|
||||
let sut = fs.makeIterable()
|
||||
|
||||
XCTAssertEqual(Array(sut).map { $0.element }, U.allCases)
|
||||
}
|
||||
|
||||
func test_alphaCut_allValuesAreBelowAlpha() {
|
||||
let alpha = 0.5
|
||||
let set = IterableFuzzySet(
|
||||
|
|
Loading…
Reference in New Issue