All (existing) tests pass. More tests needed!

This commit is contained in:
Simon Brooke 2025-08-14 12:08:18 +01:00
parent 99fce9c98f
commit 5c1427e8fa
3 changed files with 64 additions and 43 deletions

View file

@ -14,19 +14,26 @@
(defn find-case-id [kb c] (defn find-case-id [kb c]
(cond (cond
(and (keyword? c) (-> kb :cases c)) c (and (keyword? c) (-> kb :cases c)) c
(satisfies? Case c) (:case-id c))) (satisfies? Case c) (:case-id c)
:else (throw (ex-info (format "Unexpected value `%s` passed for case" c)
{:case c
:type (type c)}))))
(defn find-feature-for [kb f] (defn find-feature-for [kb f]
(cond (satisfies? Feature f) f (cond (satisfies? Feature f) f
(keyword? f) (-> kb :features f) (keyword? f) (-> kb :features f)
:else (throw (ex-info (format "Unexpected value `%s` passed for feature" f) :else (throw (ex-info (format "Unexpected value `%s` passed for feature" f)
{:case f {:feature f
:type (type f)})))) :type (type f)}))))
(defn find-feature-id [kb f] (defn find-feature-id [kb f]
(cond (cond
(and (keyword? f) (-> kb :features f)) f (and (keyword? f) (-> kb :features f)) f
(satisfies? Feature f) (:feature-id f))) (satisfies? Feature f) (:feature-id f)
:else (throw
(ex-info (format "Unexpected value `%s` passed for feature" f)
{:feature f
:type (type f)}))))
(defn do-knowledge [kb case-or-id feature-or-id] (defn do-knowledge [kb case-or-id feature-or-id]
(let [c (find-case-for kb case-or-id) (let [c (find-case-for kb case-or-id)

View file

@ -1,44 +1,46 @@
(ns dengine.feature-test (ns dengine.feature-test
(:require (:require
[arboretum.dengine.case :refer [make-case]]
[arboretum.dengine.core :refer [add-case! add-feature!]] [arboretum.dengine.core :refer [add-case! add-feature!]]
[arboretum.dengine.feature :refer [make-feature]]
[arboretum.dengine.kb :refer [!kb]] [arboretum.dengine.kb :refer [!kb]]
[clojure.pprint :refer [pprint]] [clojure.pprint :refer [pprint]]
[clojure.test :refer [deftest is testing]]) [clojure.test :refer [deftest is testing]])
(:import (:import
[arboretum.dengine.kb KBImpl])) [arboretum.dengine.kb KBImpl]))
(def testkb (KBImpl. {} (def testkb (KBImpl. {:case-1 (make-case :case-1 "Mrs Nora Trellis"
{})) {:married {:value true
:authority :user
:reason "I have been told that married is true of Mrs Norah Trellis"}
:divorced {:value false
:authority :default
:reason "I assumed that divorced is false of Mrs Norah Trellis"}
:is-entitled-to-widows-benefit {:value true
:authority :rule
:reason "I infered that is-entitled-to-widows-benefit is true of Mrs Norah Trellis"}})}
{:widowed (make-feature "Widowed" :widowed false nil)
:married (make-feature "Married" :married false nil)}))
(reset! !kb testkb) (reset! !kb testkb)
(pprint @!kb)
(deftest feature-impl-test (deftest feature-impl-test
(testing "Testing feature implementation" (testing "Testing feature implementation"
(let [f (add-feature! "is entitled to Widow's Allowance" (let [f1 (.get-feature @!kb :widowed)
:is-entitled-to-widows-allowance false nil) c (.get-case @!kb :case-1)]
c (add-case! "Mrs Nora Trellis" :case_1 (pprint {:f f1
{:married {:value true
:authority :user
:reason "I have been told that married is true of Mrs Norah Trellis"}
:divorced {:value false
:authority :default
:reason "I assumed that divorced is false of Mrs Norah Trellis"}
:is-entitled-to-widows-benefit {:value true
:authority :rule
:reason "I infered that is-entitled-to-widows-benefit is true of Mrs Norah Trellis"}})]
(pprint {:f f
:c c}) :c c})
(let [expected :is-entitled-to-widows-allowance (let [expected :widowed
actual (.feature-id f)] actual (.feature-id f1)]
(is (= actual expected))) (is (= actual expected)))
(let [expected false (let [expected false
actual (.default f)] actual (.default f1)]
(is (= actual expected))) (is (= actual expected)))
(let [expected false (let [expected false
actual (.decide f c)] actual (.decide f1 c)]
(is (= actual expected) "If we have no knowledge and no decision method, take the defualt.")) (is (= actual expected) "If we have no knowledge and no decision method, take the defualt."))
(let [expected true (let [expected true
actual (.decide (add-feature! "Married" :married false nil) :case_1)] actual (.decide (.get-feature @!kb :married) :case-1)]
(is (= actual expected) "If we have knowledge, return it.")))) (is (= actual expected) "If we have knowledge, return it.")))))
)

View file

@ -1,38 +1,50 @@
(ns dengine.kb-test (ns dengine.kb-test
(:require (:require
[arboretum.dengine.core :refer [add-case!]] [arboretum.dengine.case :refer [make-case]]
[arboretum.dengine.core :refer [add-case! add-feature!]]
[arboretum.dengine.feature :refer [make-feature]]
[arboretum.dengine.kb :refer :all] [arboretum.dengine.kb :refer :all]
[clojure.pprint :refer [pprint]] [clojure.pprint :refer [pprint]]
[clojure.test :refer [deftest is testing]]) [clojure.test :refer [deftest is testing]])
(:import (:import
[arboretum.dengine.kb KBImpl])) [arboretum.dengine.kb KBImpl]))
(def testkb (KBImpl. {} (def testkb (KBImpl. {:case-1 (make-case :case-1 "Mrs Norah Trellis" {:married {:value true
{})) :authority :user
:reason "I have been told that married is true of Mrs Norah Trellis"}
:divorced {:value false
:authority :default
:reason "I assumed that divorced is false of Mrs Norah Trellis"}
:is-entitled-to-widows-benefit {:value true
:authority :rule
:reason "I infered that is-entitled-to-widows-benefit is true of Mrs Norah Trellis"}})}
{:divorced (make-feature "Divorced" :divorced false nil)
:married (make-feature "Married" :married false nil)
:widowed (add-feature! "Widowed" :widowed false nil)
:is-entitled-to-widows-benefit
(add-feature! "Is entitled to widows' benefit"
:is-entitled-to-widows-benefit false nil)}))
(pprint testkb) (pprint testkb)
(reset! !kb testkb) (reset! !kb testkb)
(add-case! "Mrs Nora Trellis" :case_1
{:married {:value true
:authority :user
:reason "I have been told that married is true of Mrs Norah Trellis"}
:divorced {:value false
:authority :default
:reason "I assumed that divorced is false of Mrs Norah Trellis"}
:is-entitled-to-widows-benefit {:value true
:authority :rule
:reason "I infered that is-entitled-to-widows-benefit is true of Mrs Norah Trellis"}})
(deftest access-test (deftest access-test
(testing "Accessing knowledge in the knowledge base" (testing "Accessing knowledge in the knowledge base"
(let [expected nil (let [expected nil
actual (.is? testkb :case_1 :widowed)] actual (.is? testkb :case-1 :widowed)]
(is (= actual expected))) (is (= actual expected)))
(let [expected true (let [expected true
actual (.is? testkb :case_1 :married)] actual (.is? testkb :case-1 :married)]
(is (= actual expected))) (is (= actual expected)))
(let [expected false (let [expected false
actual (.is? testkb :case_1 :divorced)] actual (.is? testkb :case-1 :divorced)]
(is (= actual expected))))) (is (= actual expected))))
(testing "Adding features"
(let [expected nil
actual (.get-feature @!kb :has-children)]
(is (= actual expected) "Not present until added..."))
(add-feature! "Has children" :has-children false nil)
(let [expected :has-children
actual (:feature-id (.get-feature @!kb :has-children))]
(is (= actual expected) "Not present until added..."))))