From 0dabc8da0cc6133ea4b2b9ccd55a8f7a0103b391 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 23 Apr 2020 12:07:21 +0100 Subject: [PATCH] Added tests for schema - and all pass. --- docs/codox/AgainstTruth.html | 1 - docs/codox/Analysis.html | 4 +- src/wildwood/dengine/node.clj | 2 +- src/wildwood/schema.clj | 47 +++---------- test/wildwood/core_test.clj | 7 -- test/wildwood/schema_test.clj | 120 ++++++++++++++++++++++++++++++++++ 6 files changed, 132 insertions(+), 49 deletions(-) delete mode 100644 test/wildwood/core_test.clj create mode 100644 test/wildwood/schema_test.clj diff --git a/docs/codox/AgainstTruth.html b/docs/codox/AgainstTruth.html index f5cf75e..53f4e73 100644 --- a/docs/codox/AgainstTruth.html +++ b/docs/codox/AgainstTruth.html @@ -9,7 +9,6 @@

Introduction

This document is in two parts: a statement of a problem, and an account of an attempt to address it. The problem is stated briefly in the first chapter, and fleshed out in the following two with a history of attempts which have been made in the past to address it, and an analysis of what would be needed to solve it.

The second part starts with an account of a system built by the author in collaboration with Peter Mott, describing particularly how the problem was addressed by this system; subsequent chapters will describe the development of a further system, in which the analysis developed in the first section will be applied.

-

This document deals only with explanation. Issues relating to inference and especially to truth maintenance will undoubtedly be raised as it progresses, but such hares will resolutely not be followed.

Note on the quality of the text

Much of this text was written between 1986 and 1988 on Xerox 1108 and 1186 workstations, in their native WYSIWYG document system, and printed as hard copy; and some was written on the very first generation of Apple Macintosh computer, and again printed as hard copy. The text here is the consequence of scanning the hard copy and running optical character recognition on the scans. It isn’t perfect. I am proof reading as I go and I hope that it will improve.

Contents

diff --git a/docs/codox/Analysis.html b/docs/codox/Analysis.html index c48c135..a636207 100644 --- a/docs/codox/Analysis.html +++ b/docs/codox/Analysis.html @@ -229,9 +229,7 @@ a is x

The use of ‘correct’ here is the problem. It appears to imply that one knows that the answer which one knows maps in some unproblematic way onto something real in the external world. Thus Achinstein, too, falls into the trap sprung by the radicals. In the absence of some definition of what is to be understood by ‘correct’, these definitions are simply meaningless.

This account does not address many of the facets of common sense explanation.

It has nothing to say about the amount of detail contained in an explanation. It has nothing to say about the need to express an explanation in terms of an account of the world which is accessible to the auditor. lt fails to account for the possibility of explanation by analogy, or of unintentional explanation.

-

It appears that Achinstein’s motivation in producing a new account has less to do with addressing these real world problems than with overcoming such philosophical puzzles as the Paradox of the Ravens; so his account takes us no nearer to providing a model which will support the construction of better common sense explanations. 5

-

A [ mh L/Go/w%` \

-

` Eegozi

+

It appears that Achinstein’s motivation in producing a new account has less to do with addressing these real world problems than with overcoming such philosophical puzzles as the Paradox of the Ravens; so his account takes us no nearer to providing a model which will support the construction of better common sense explanations.

Toulmin

Turning aside for the moment from those philosophers who have made a study of explanation per se, there is another whose work is currently attracting fashionable attention in Expert Systems (and especially mechanised explanation) circles; one must make passing reference to Toulmin, and, unless one chooses to use his argument schema, one must produce a very good argument for not doing so. Therfore it is important to know what he actually argued.

A Toulmin’s programme was to replace the syllogistic with a new logical schema of his own. He did not address symbolic logic except by dismissing it as irrelevant to the study of real world arguments:

diff --git a/src/wildwood/dengine/node.clj b/src/wildwood/dengine/node.clj index f26b8ba..ad04787 100644 --- a/src/wildwood/dengine/node.clj +++ b/src/wildwood/dengine/node.clj @@ -1,4 +1,4 @@ -(ns wildwood.dengine.engine +(ns wildwood.dengine.node "A dtree node.") (defn node? diff --git a/src/wildwood/schema.clj b/src/wildwood/schema.clj index bc18649..5f747b2 100644 --- a/src/wildwood/schema.clj +++ b/src/wildwood/schema.clj @@ -29,9 +29,6 @@ :authority ;; id of agent from whom, or rule from which, I know this. }) -;; (argument-keys :authority) -;; (argument-keys :data) - (defn proposition? "True if `o` qualifies as a proposition. A proposition is probably a map with some privileged keys, and may look something like a minimised @@ -56,21 +53,6 @@ ;; are not minimised (indeed, they should not be). TODO: fix. (some map? (vals o)))))) -;; (proposition? {:verb :killed :subject :brutus :object :caesar}) ;; true -;; (proposition? {:verb :killed :subject :brutus :object :caesar} true) ;; true -;; (proposition? {:verb :killed :subject :brutus :object :caesar :truth false}) ;; true -;; (proposition? {:verb :killed :subject :brutus}) ;; false: no :object key -;; (proposition? {:verb :killed -;; :subject {:id :brutus :name "Marcus Brutus"} -;; :object {:id :caesar -;; :name "Gaius Julius Caesar" -;; :wife :drusila}}) ;; true, although not minimised -;; (proposition? {:verb :killed -;; :subject {:id :brutus :name "Marcus Brutus"} -;; :object {:id :caesar -;; :name "Gaius Julius Caesar" -;; :wife :drusila}} true) ;; false, because minimisation was required - (defn truth "If `p` is a proposition, return whether the value asserted by that proposition is `true`. If the `:truth` key is missing, `true` is @@ -85,10 +67,6 @@ true) nil)) -;; (truth {:verb :killed :subject :brutus :object :caesar}) -;; (truth {:verb :killed :subject :brutus :object :caesar :truth true}) -;; (truth {:verb :killed :subject :brutus :object :caesar :truth false}) - (defn rule? "True if `o` qualifies as a rule. A rule is a structure which comprises * an id and @@ -103,21 +81,16 @@ (defn argument? "True if `o` qualifies as an argument structure. - An argument structure is a (potentially rich proposition which, in addition, should have values + An argument structure is a (potentially rich) proposition which, in addition, should have values for `:confidence` and `:authority`. A value for `:data` may, and probably will, - also be present but is not required." + also be present but is not required. The value of `:confidence` must be a number + in the range -1 to 1." [o] (and (proposition? o) - (every? #(o %) argument-keys))) - -;; (argument? {:verb :killed :subject :brutus :object :caesar}) ;; false, lacks :confidence, :authority -;; (argument? {:verb :killed :subject :brutus :object :caesar :confidence 0.7 :authority :falco}) ;; true -;; (argument? {:verb :killed -;; :subject {:id :brutus :name "Marcus Brutus"} -;; :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila} -;; :confidence 1 -;; :authority :brutus}) ;; true + (every? #(o %) argument-keys) + (number? (:confidence o)) + (<= -1 (:confidence o) 1))) (defn minimise "Expecting that `o` is a (potentially rich) proposition, return a map identical @@ -143,7 +116,7 @@ (keys o))) o)) -;; (proposition? -;; (minimise {:verb :killed -;; :subject {:id :brutus :name "Marcus Brutus"} -;; :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila}})) +(proposition? + (minimise {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila}})) diff --git a/test/wildwood/core_test.clj b/test/wildwood/core_test.clj deleted file mode 100644 index 7826615..0000000 --- a/test/wildwood/core_test.clj +++ /dev/null @@ -1,7 +0,0 @@ -(ns wildwood.core-test - (:require [clojure.test :refer :all] - [wildwood.core :refer :all])) - -(deftest a-test - (testing "FIXME, I fail." - (is (= 0 1)))) diff --git a/test/wildwood/schema_test.clj b/test/wildwood/schema_test.clj new file mode 100644 index 0000000..5553840 --- /dev/null +++ b/test/wildwood/schema_test.clj @@ -0,0 +1,120 @@ +(ns wildwood.schema-test + (:require [clojure.test :refer :all] + [wildwood.schema :refer :all])) + +(deftest required-keys-test + (testing "Required keys are policed as specified" + (is (= (required-keys :verb) :verb)) + (is (= (required-keys :subject) :subject)) + (is (= (required-keys :subject) :subject)) + (is (nil? (required-keys 7))) + (is (nil? (required-keys "Froboz"))) + (is (nil? (required-keys 'Froboz))) + (is (nil? (required-keys {:verb :kill :subject :brutus :object :caesar})))) + (testing "Argument keys are not required" + (map + #(is (nil? (required-keys %))) + argument-keys)) + (testing "Consensual keys are not required" + (map + #(is (nil? (required-keys %))) + consensual-keys))) + +(deftest proposition-test + (testing "Propositions are identified correctly" + (is (proposition? {:verb :kill :subject :brutus :object :caesar})) + (is (proposition? {:verb :kill :subject :brutus :object :caesar} true) + "Minimisation tested and found") + (is (proposition? {:verb :kill :subject :brutus :object :caesar :truth false}) + "Non-required key is allowed") + (is (= (proposition? {:verb :kill :subject :brutus}) false) + "Should be false, no :object key") + (is (proposition? {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar + :name "Gaius Julius Caesar" + :wife :drusila}}) + "Unminimised proposition, but minimisation not required") + (is (= (proposition? {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar + :name "Gaius Julius Caesar" + :wife :drusila}} true) + false) + "Unminimised proposition, minimisation required"))) + +(deftest truth-test + (testing "Correctly distinguishing between assertions and negations" + (is (truth {:verb :kill :subject :brutus :object :caesar}) + "Implicit assertion") + (is (truth {:verb :kill :subject :brutus :object :caesar :truth true}) + "Explicit assertion") + (is (not (truth {:verb :kill :subject :brutus :object :caesar :truth false})) + "Explicit negation"))) + +(deftest argument-test + (testing "Arguments are correctly identified" + (is (not (argument? {:verb :kill :subject :brutus :object :caesar})) + "false, lacks :confidence, :authority") + (is (argument? {:verb :kill + :subject :brutus + :object :caesar + :confidence 0.7 + :authority :falco}) + "true, all required keys present and :confidence has valid value") + (is (not (argument? {:verb :kill + :subject :brutus + :object :caesar + :confidence 1.7 + :authority :falco})) + "false, all required keys present but :confidence has invalid value") + (is (argument? {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila} + :confidence 1 + :authority :brutus}) + "true; not minimised but arguments are not required to be") + (is (not (argument? [:verb :subject :object])) + "false: not even close (sequence)") + (is (not (argument? :verb)) + "false: not even close (keyword)") + (is (not (argument? "Froboz")) + "false: not even close (string)") + (is (not (argument? 7)) + "false: not even close (number)"))) + +(deftest minimise-test + (testing "Proposition minimisation" + (is (= + (minimise {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila}}) + {:verb :kill :subject :brutus :object :caesar})) + (is (proposition? + (minimise {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila}})) + "A minimised proposition is still a proposition") + (is (= + (minimise {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila} + :confidence 1 + :authority {:id :brutus :name "Marcus Brutus"}}) + {:verb :kill + :subject :brutus + :object :caesar + :confidence 1 + :authority {:id :brutus :name "Marcus Brutus"}}) + "The value of the :authority key (and other argument keys, actually) + should not be minimised") + (is (argument? + (minimise {:verb :kill + :subject {:id :brutus :name "Marcus Brutus"} + :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila} + :confidence 1 + :authority {:id :brutus :name "Marcus Brutus"}})) + "A minimised argument is still an argument"))) + + +