From 1451ab2a0006613b66803c9c83a9f7d60360284d Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Thu, 23 Apr 2020 09:54:35 +0100 Subject: [PATCH] Much progress on API --- doc/Analysis.md | 2 +- doc/Bialowieza.md | 68 +++++++-- docs/codox/AgainstTruth.html | 2 +- docs/codox/Analysis.html | 4 +- docs/codox/Arboretum.html | 2 +- docs/codox/Arden.html | 2 +- docs/codox/Bialowieza.html | 74 +++++++++- docs/codox/Errata.html | 2 +- docs/codox/Experience.html | 2 +- docs/codox/History.html | 2 +- docs/codox/Implementing.html | 2 +- docs/codox/KnacqTools.html | 2 +- docs/codox/Manifesto.html | 2 +- docs/codox/OnHylasAndPhilonus.html | 2 +- docs/codox/PredicateSubtext.html | 2 +- docs/codox/TheProblem.html | 2 +- docs/codox/index.html | 2 +- docs/codox/intro.html | 2 +- docs/codox/wildwood.advocate.html | 4 +- docs/codox/wildwood.bialowieza.html | 2 +- docs/codox/wildwood.caesar.html | 3 + docs/codox/wildwood.dengine.engine.html | 3 + docs/codox/wildwood.dengine.html | 3 + docs/codox/wildwood.knowledge-accessor.html | 2 +- docs/codox/wildwood.schema.html | 8 +- src/wildwood/caesar.clj | 6 +- .../{dengine.clj => dengine/engine.clj} | 15 +- src/wildwood/dengine/node.clj | 15 ++ src/wildwood/schema.clj | 134 +++++++++++++++--- 29 files changed, 293 insertions(+), 78 deletions(-) create mode 100644 docs/codox/wildwood.caesar.html create mode 100644 docs/codox/wildwood.dengine.engine.html create mode 100644 docs/codox/wildwood.dengine.html rename src/wildwood/{dengine.clj => dengine/engine.clj} (59%) create mode 100644 src/wildwood/dengine/node.clj diff --git a/doc/Analysis.md b/doc/Analysis.md index 3615cd8..c5bec34 100644 --- a/doc/Analysis.md +++ b/doc/Analysis.md @@ -748,7 +748,7 @@ normal conversational discussion in an easily manageable form. Had Toulmin advanced this and this only, I think he might have been taken more seriously; and I think there is merit in the current revival of interest in it. -### The Schema +### The Toulmin Schema Toulmin's concern is with arguments as they are presented informally, in conversation or writing, and the relation between the form of such diff --git a/doc/Bialowieza.md b/doc/Bialowieza.md index 12ae4fb..13734f8 100644 --- a/doc/Bialowieza.md +++ b/doc/Bialowieza.md @@ -1,6 +1,6 @@ # Bialowieza -{not yet written. To cover development of the Clojure Wildwood library, and the thinking and design which develops as I do it} +{ this chapter is in active development } ## Why Bialowieza? @@ -8,13 +8,15 @@ Bialowieza is the second iteration of the Wildwood engine, and this following co ## Motivation -## Major components of Bialowieza +The current motivation for restarting work on Wildwood is to provide non-player characters in a game world with sufficient intelligence that they can enter into meaningful unscripted conversations about objects and events in that world. + +## Major components of Bialowieza ### Knowledge Accessors The `wildwood.knowledge-accessor/Accessor` protocol defines a bidirectional transducer which can fetch data from whatever storage representation the calling application uses into the representation defined by `wildwood.schema`. -### Advocates +### Advocates The `wildwood.advocate/Advocate` protocol describes an agent which can take part in decision processes. @@ -26,7 +28,7 @@ The engine is implemented by the namespace `wildwood.bialowieza`. Advocates are entitled to use whatever inference processes they like, but they have access to `wildwood.dengine`, which is an implementation of the DTree engine described in the chapter on [Arboretum](Arboretum.html) adapted to propositions as defined in `wildwood.schema`. -## How shall we represent a proposition? +### Propositions { **TODO** read, and follow references from, https://plato.stanford.edu/entries/propositions/ } @@ -40,24 +42,45 @@ with possibly a lot of other qualifying material. So we shall say that a proposition will be represented as a Clojure map with at least the keys: -* :verb -* :subject -* :object +* `:verb` - what is asserted +* `:subject` - of whom (or what) +* `:object` - to whom (or what) + +Thus + + {:verb :killed :subject :brutus :object :caesar} + +is a proposition which asserts that Brutus killed Caesar. There may be many other privileged keys, such as -* :location - where did it happen -* :time - when did it happen +* `:location` - where did it happen? value might be something from which proximity may be derived; +* `:time` - when did it happen? This needs to be a value with a canonical order, such as a number; +* `:truth` - is it true? if present and value `false`, negates the proposition; +* `:confidence` - how sure am I? A value, perhaps, in the range -1 to 1, although conventionally if less than 1 we probably set the `:truth` value to false; +* `:data` - an argument structure...! +* `:authority` - id of agent from whom, or rule from which, I know this; -and so on. The exact set of privileged keys is probably actually a matter for particular advocates rather than for the engine itself, although if the advocates in the game don't broadly share the same set of privileged keys then it won't workvery well. +and so on. The exact set of privileged keys is probably actually a matter for particular advocates rather than for the engine itself, although if the advocates in the game don't broadly share the same set of privileged keys then it won't work very well. -## Proposition minimisation +*However...* + +The attentive reader will note that some of the proposed privileged keys map closely onto the [Toulmin schema](Analysis.html#the-toulmin-schema). Thus we can say: + +* that the proposition itself is a `claim` in the sense of the **C** term; +* that `:data` above is precisely `data` in the sense of the **D** term in Toulmin's schema, but may (is likely to) also provide a `warrant` in the sense of the **W** term; +* that `:truth` and `:confidence` are both `qualifiers` of the claim in the sense of the **Q** term; +* that `:authority` is a form of `backing` in the sense of the **B** term. + +So what, then, is an 'argument structure', as described above? It seems to me that it may be exactly a proposition, with the special feature that the data is not minimised. + +#### Proposition minimisation How are the values of `:subject`, `:object` and so on to be passed? If we pass rich knowledge structures around, then we lose the insight that different advocates may know different things about given objects. Thus, while internally within each advocate's knowledge base objects may be stored with rich data, when they're passed around in propositions they should be minimised - that is to say, the value should just be a unique identifier, such that, for every object in the domain, if an advocate knows anything at all about that object, it knows its unique identifier and knows the object by that unique identifier. -Thus the unique identifier has something of the nature of a 'true name', in the magical sense. A given true name, a given unique identifier, refers to precisely one thing in the world, and provided that two advocates both know the same true name, they can debats propositions which refer to the objects with those true names. +Thus the unique identifier has something of the nature of a 'true name', in the magical sense. A given true name, a given unique identifier, refers to precisely one thing in the world, and provided that two advocates both know the same true name, they can debats propositions which refer to the object with that true name. -Generally, a true name shall be a Clojure keyword. That keyword, passed to any advocate in the game, shall identify either `nil` (the advocate knows nothing of the object), or a map representing everything the advocate knows about the object. +Generally, a true name shall be a Clojure keyword. That keyword, passed to any advocate in the game, shall identify either `nil` (the advocate knows nothing of the object), or a map representing everything the advocate knows about the object, and within that map, the value of the key `:id` shall be that true name. But in saying 'the advocate knows', actually, the advocate knows nothing. The advocate has access to a knowledge base, and it is in the knowledge base that the knowledge is stored. It may be an individual knowledge base, in which case we can implement that idea that different advocates may have the different knowledge about the same object, or it may be a shared consensual knowledge base. @@ -69,4 +92,23 @@ This means that every implementation of the `wildwood.knowledge-accessor/Accesso The object of building Bialowieza as a library is that we should not constrain how applications which use the library store their knowledge. Rather, knowledge accessors must transduce between the representation used by the particular storage implementation and that defined in `wildwood.schema`. However, what we've described above suggests that a hierarchical database would be a very natural fit for knowlege base data - more natural, in this case, than a relational database. +## Prejudice, and defaults + +In Arboretum and later in KnacqTools, default values of features were determined by the 'knowledge engineer', normally by asking the domain expert, and were fixed for the knowledge base at all times. But these two programs each reasoned about one case at a time, and did not store knowledge about multiple cases. + +These systems could this be said to be *prejudiced*, to the extent that knowledge of the world acquired over time did not change their default judgements. Wildwood holds knowledge on potentially very many objects, and that knowledge may change dynamically over time, both as the world changes and as new things which already existed in the world become known. + +Suppose we wish to decide the truth value of the proposition + + {:verb :is :subject :brutus :object :honourable} + +Suppose we have no rule for this, so we want to use a default. Suppose we scan all the propositions in the knowledge base which match the pattern + + {:verb :is :object :honourable} + +and divide them into two sets, those which assert `true` and those which assert `false`. + +If the arity of the true set is greater than the arity of the false set, then the default is `true` (and vice versa). But we can derive more than this: we can derive a confidence score, based on the ratio of true instances to false instances. + +The problem is that this is computationally expensive. So we need to cache default values. Different advocates may use different caching strategies, with different 'time to live'. The longer the time to live of a cached default, the more prejudiced - the less agile in learning - the advocate will be; but the faster it will be able to produce decisions. diff --git a/docs/codox/AgainstTruth.html b/docs/codox/AgainstTruth.html index 504e40d..515e56d 100644 --- a/docs/codox/AgainstTruth.html +++ b/docs/codox/AgainstTruth.html @@ -1,6 +1,6 @@ -Against Truth

Against Truth

+Against Truth

Against Truth

Simon Brooke

“Hey, what IS truth, man?” Beeblebrox, Z, quoted in [Adams, 1978]

diff --git a/docs/codox/Analysis.html b/docs/codox/Analysis.html index fb4b9b4..7a4f14b 100644 --- a/docs/codox/Analysis.html +++ b/docs/codox/Analysis.html @@ -1,6 +1,6 @@ -Analysis

Analysis

+Analysis

Analysis

Accounts from the Philosophy of Science

(Towards another chapter. What l want to do is: ,

    @@ -256,7 +256,7 @@ a is x

    Thus those practitioners in the field of Expert Systems who advance Toulmin as an authority must face up to this corrolary: if Toulmin’s arguments are valid, then there cannot ever be a successful Expert System based on any technology we have now available, as all current Expert Systems are based on some logical formalism (even if, as in the case of production systems, this formalism is crude); and all, certainly, claim to be decision processes for arguments in their domain. As such, according to Toulmin, they are the modern equivalents of the PhiIosophers’ stone - they cannot exist.

    He was, to be fair to him, writing in the year that LISP was being developed, when the posibility of mechanical inference was dreamed of only by visionaries like Turing; nevertheless the cavalier manner in which he dismisses all of the 19th and 20th century advances in logic significantly weakens his claims to be taken seriously in this field.

    But if Toulmin cannot be taken seriously as a logician, is there any residual value in his work on argument? I think it is possible that there is, because the argument schema with which he hoped to replace both the traditional syllogism, and the formalisms of modern logic, does indeed capture the content of normal conversational discussion in an easily manageable form. Had Toulmin advanced this and this only, I think he might have been taken more seriously; and I think there is merit in the current revival of interest in it.

    -

    The Schema

    +

    The Toulmin Schema

    Toulmin’s concern is with arguments as they are presented informally, in conversation or writing, and the relation between the form of such informal arguments and the forms recognised by formal logic.

    He questions whether the aristotelian ‘standard form’ of an argument is ‘candid’; that is, whether it is presented in such a way as to make its merits as argument most manifest. He suggests that the analysis into only three elements, major premiss, minor premiss, conclusion may be artificially simplified:

    diff --git a/docs/codox/Arboretum.html b/docs/codox/Arboretum.html index e5d1fd6..a19e585 100644 --- a/docs/codox/Arboretum.html +++ b/docs/codox/Arboretum.html @@ -1,6 +1,6 @@ -Arboretum

    Arboretum

    +Arboretum

    Arboretum

    This chapter describes briefly an inference mechanism, implemented in the Arboretum prototype; this is included here to show the results achieved in the author’s early work on explanation, on which it is hoped to build in the current work. A fuller description of this mechanism, and of the Arboretum prototype, will be found in [Mott & Brooke 87], from which this chapter is largely drawn.

    Arboretum was written in InterLisp-D[4] using LOOPS [5] object oriented facilities, to allow people to manipulate DTree structures through graphical representations: to build arbitrarily large knowledge bases, to use these to provide answers to questions about objects in domains admitting incomplete information - and to provide natural language explanations of these answers. The inference process by which answers are produced is shown as an animated graph. The user can ask the system how the value of any particular feature was arrived at, and what that value was. . It was developed for the Alvey DHSS Large Demonstrator Project, and sought to meet early perceptions of the needs of DHSS Adjudication Officers. Adjudication Officers decide claimants’ eligibility over a wide range of welfare benefits. There is a very large volume of work to be done, so they work under considerable pressure.

    The Adjudication process within the DHSS has its own levels of authority culminating in the

    diff --git a/docs/codox/Arden.html b/docs/codox/Arden.html index 7f80b26..0a597df 100644 --- a/docs/codox/Arden.html +++ b/docs/codox/Arden.html @@ -1,6 +1,6 @@ -Arden

    Arden

    +Arden

    Arden

    Why Arden?

    It was something of tradition in the InterLisp-D community to give successive versions of a project codenames with successive alphabetical initials. So the first version would have a name starting ‘A’, the second ‘B’, and so on. The first prototype for Wildwood was called ‘Arden’, because it starts with an ‘A’, and because it is a fantastical dream-like forest depicted in Shakespeare’s play ‘As You Like It’, which if I recall correctly was performed as a promenade performance by the Duke’s Theatre in Lancaster in that year. While Arboretum - that carefully tended garden of trees - had been, as I’ve said, largely Peter’s in concept, Wildwood would be mine.

    Background

    diff --git a/docs/codox/Bialowieza.html b/docs/codox/Bialowieza.html index f806464..df793d9 100644 --- a/docs/codox/Bialowieza.html +++ b/docs/codox/Bialowieza.html @@ -1,6 +1,74 @@ -Bialowieza

    Bialowieza

    -

    {not yet written. To cover development of the Clojure Wildwood library, and the thinking and design which develops as I do it}

    +Bialowieza

    Bialowieza

    +

    { this chapter is in active development }

    Why Bialowieza?

    -

    Bialowieza is the second iteration of the Wildwood engine, and this following convention its name should start with ‘B’. Białowieża is Europe’s last great wild wood, and it is currently under threat.

    \ No newline at end of file +

    Bialowieza is the second iteration of the Wildwood engine, and this following convention its name should start with ‘B’. Białowieża is Europe’s last great wild wood, and it is currently under threat.

    +

    Motivation

    +

    The current motivation for restarting work on Wildwood is to provide non-player characters in a game world with sufficient intelligence that they can enter into meaningful unscripted conversations about objects and events in that world.

    +

    Major components of Bialowieza

    +

    Knowledge Accessors

    +

    The wildwood.knowledge-accessor/Accessor protocol defines a bidirectional transducer which can fetch data from whatever storage representation the calling application uses into the representation defined by wildwood.schema.

    +

    Advocates

    +

    The wildwood.advocate/Advocate protocol describes an agent which can take part in decision processes.

    +

    The engine itself

    +

    The engine is implemented by the namespace wildwood.bialowieza.

    +

    Inference processes

    +

    Advocates are entitled to use whatever inference processes they like, but they have access to wildwood.dengine, which is an implementation of the DTree engine described in the chapter on Arboretum adapted to propositions as defined in wildwood.schema.

    +

    Propositions

    +

    { TODO read, and follow references from, https://plato.stanford.edu/entries/propositions/ }

    +

    As a slightly tendentious first stab, a proposition is a sentence which is either true or false. This is tendentious because two different sentences which have the same underlying semantic import are usually considered to be instances of the same proposition, and seen from the other end, there may be many ways you can validly express a single proposition in a single natural language. However, for the present purpose, the proposition that a proposition is a sentence is good enough.

    +

    A sentence generally has the form

    +
    <verb subject object>
    +
    +

    with possibly a lot of other qualifying material.

    +

    So we shall say that a proposition will be represented as a Clojure map with at least the keys:

    +
      +
    • :verb - what is asserted
    • +
    • :subject - of whom (or what)
    • +
    • :object - to whom (or what)
    • +
    +

    Thus

    +
    {:verb :killed :subject :brutus :object :caesar}
    +
    +

    is a proposition which asserts that Brutus killed Caesar.

    +

    There may be many other privileged keys, such as

    +
      +
    • :location - where did it happen? value might be something from which proximity may be derived;
    • +
    • :time - when did it happen? This needs to be a value with a canonical order, such as a number;
    • +
    • :truth - is it true? if present and value false, negates the proposition;
    • +
    • :confidence - how sure am I? A value, perhaps, in the range -1 to 1, although conventionally if less than 1 we probably set the :truth value to false;
    • +
    • :data - an argument structure…!
    • +
    • :authority - id of agent from whom, or rule from which, I know this;
    • +
    +

    and so on. The exact set of privileged keys is probably actually a matter for particular advocates rather than for the engine itself, although if the advocates in the game don’t broadly share the same set of privileged keys then it won’t work very well.

    +

    However…

    +

    The attentive reader will note that some of the proposed privileged keys map closely onto the Toulmin schema. Thus we can say:

    +
      +
    • that the proposition itself is a claim in the sense of the C term;
    • +
    • that :data above is precisely data in the sense of the D term in Toulmin’s schema, but may (is likely to) also provide a warrant in the sense of the W term;
    • +
    • that :truth and :confidence are both qualifiers of the claim in the sense of the Q term;
    • +
    • that :authority is a form of backing in the sense of the B term.
    • +
    +

    So what, then, is an ‘argument structure’, as described above? It seems to me that it may be exactly a proposition, with the special feature that the data is not minimised.

    +

    Proposition minimisation

    +

    How are the values of :subject, :object and so on to be passed? If we pass rich knowledge structures around, then we lose the insight that different advocates may know different things about given objects. Thus, while internally within each advocate’s knowledge base objects may be stored with rich data, when they’re passed around in propositions they should be minimised - that is to say, the value should just be a unique identifier, such that, for every object in the domain, if an advocate knows anything at all about that object, it knows its unique identifier and knows the object by that unique identifier.

    +

    Thus the unique identifier has something of the nature of a ‘true name’, in the magical sense. A given true name, a given unique identifier, refers to precisely one thing in the world, and provided that two advocates both know the same true name, they can debats propositions which refer to the object with that true name.

    +

    Generally, a true name shall be a Clojure keyword. That keyword, passed to any advocate in the game, shall identify either nil (the advocate knows nothing of the object), or a map representing everything the advocate knows about the object, and within that map, the value of the key :id shall be that true name.

    +

    But in saying ‘the advocate knows’, actually, the advocate knows nothing. The advocate has access to a knowledge base, and it is in the knowledge base that the knowledge is stored. It may be an individual knowledge base, in which case we can implement that idea that different advocates may have the different knowledge about the same object, or it may be a shared consensual knowledge base.

    +

    A proposition is represented as a map. So to minimise a proposition, for every value in that map, if the value is itself a map it shall be replaced by the value of the key :id in that map.

    +

    This means that every implementation of the wildwood.knowledge-accessor/Accessor protocol must transduce whatever token its backing store uses as the primary key for an object to :id when it performs a fetch operation.

    +

    Thoughts on the shape of a knowledge base

    +

    The object of building Bialowieza as a library is that we should not constrain how applications which use the library store their knowledge. Rather, knowledge accessors must transduce between the representation used by the particular storage implementation and that defined in wildwood.schema. However, what we’ve described above suggests that a hierarchical database would be a very natural fit for knowlege base data - more natural, in this case, than a relational database.

    +

    Prejudice, and defaults

    +

    In Arboretum and later in KnacqTools, default values of features were determined by the ‘knowledge engineer’, normally by asking the domain expert, and were fixed for the knowledge base at all times. But these two programs each reasoned about one case at a time, and did not store knowledge about multiple cases.

    +

    These systems could this be said to be prejudiced, to the extent that knowledge of the world acquired over time did not change their default judgements. Wildwood holds knowledge on potentially very many objects, and that knowledge may change dynamically over time, both as the world changes and as new things which already existed in the world become known.

    +

    Suppose we wish to decide the truth value of the proposition

    +
    {:verb :is :subject :brutus :object :honourable}
    +
    +

    Suppose we have no rule for this, so we want to use a default. Suppose we scan all the propositions in the knowledge base which match the pattern

    +
    {:verb :is :object :honourable}
    +
    +

    and divide them into two sets, those which assert true and those which assert false.

    +

    If the arity of the true set is greater than the arity of the false set, then the default is true (and vice versa). But we can derive more than this: we can derive a confidence score, based on the ratio of true instances to false instances.

    +

    The problem is that this is computationally expensive. So we need to cache default values. Different advocates may use different caching strategies, with different ‘time to live’. The longer the time to live of a cached default, the more prejudiced - the less agile in learning - the advocate will be; but the faster it will be able to produce decisions.

    \ No newline at end of file diff --git a/docs/codox/Errata.html b/docs/codox/Errata.html index db28255..a16b6c0 100644 --- a/docs/codox/Errata.html +++ b/docs/codox/Errata.html @@ -1,6 +1,6 @@ -Errata

    Errata

    +Errata

    Errata

    1. On title page: the claim that Zaphod Beeblebrox is quoted as saying ‘Hey, what IS truth, man?’ in the printed text of Douglas Adams ‘Hitchhikers Guide to the Galaxy’ is false.
    \ No newline at end of file diff --git a/docs/codox/Experience.html b/docs/codox/Experience.html index 2d2b8ba..b6762e3 100644 --- a/docs/codox/Experience.html +++ b/docs/codox/Experience.html @@ -1,4 +1,4 @@ -Experience

    Experience

    +Experience

    Experience

    {Not yet written. To cover an evaluation of the Clojure Wildwood library, when it works, and what I can learn from it going forward}

    \ No newline at end of file diff --git a/docs/codox/History.html b/docs/codox/History.html index fa3d215..afd3e1c 100644 --- a/docs/codox/History.html +++ b/docs/codox/History.html @@ -1,6 +1,6 @@ -History

    History

    +History

    History

    History: Introduction

    The object of this chapter is to describe and discuss the development of Expert System explanations from the beginning’ to the most recent systems. The argument which I will try to advance is that development has been continuously driven by the perceived inadequacy of the explanations given; and that, while many ad hoc, and some principled, approaches have been tried, no really adequate explanation system has emerged. Further, I will claim that, as some of the later and more principled explanation systems accurately model the accounts of explanation advanced in current philosophy, the philosophical understanding of explanation is itself inadequate.

    {I ought to add to this chapter to give some overview of what’s happened since 1990, and look at explanations of neural network decisions, because that will help in later parts/chapters of Part One}

    diff --git a/docs/codox/Implementing.html b/docs/codox/Implementing.html index 4986ead..8ea5e4d 100644 --- a/docs/codox/Implementing.html +++ b/docs/codox/Implementing.html @@ -1,4 +1,4 @@ -Implementing

    Implementing

    +Implementing

    Implementing

    {not yet written. To cover the actual structure of the Clojure Wildwood library, as I do it}

    \ No newline at end of file diff --git a/docs/codox/KnacqTools.html b/docs/codox/KnacqTools.html index 117cd9f..87d8478 100644 --- a/docs/codox/KnacqTools.html +++ b/docs/codox/KnacqTools.html @@ -1,6 +1,6 @@ -KnacqTools

    KnacqTools

    +KnacqTools

    KnacqTools

    Background

    KnacqTools (’Knowledge Acquisition Toolkit") was essentially a productisation of the ideas developed in Arboretum. It was written in C, originally for Acorn’s RISC OS operating system, and later ported to UNIX. The only major innovation of KnacqTools was that it was able to transform DTree knowledge structures into the rule languages of a number of contemporary ‘expert system’ inference engines.

    Thus the expected use of KnacqTools was not to run an inference process itself (although of course it could do this), but to allow a knowledge engineer, using Peter Mott’s ‘elicitation by exception’ technique, which I and others had polished in the field, to enter DTrees elicited from domain experts, compile these DTrees into production rules, and export those prodution rules to the selected expert system package for deployment.

    diff --git a/docs/codox/Manifesto.html b/docs/codox/Manifesto.html index 97bc70b..02550c3 100644 --- a/docs/codox/Manifesto.html +++ b/docs/codox/Manifesto.html @@ -1,6 +1,6 @@ -Manifesto

    Manifesto

    +Manifesto

    Manifesto

    Machine inference – automated reasoning, the core of what gets called Artificial Intellegence – has ab initio been based on the assumption that the purpose of reasoning was to preserve truth. It is because this assumption is false that the project has thus far failed to bear fruit, that Allan Turing’s eponymous test has yet to be passed.

    Clockwork minds

    Of course it is possible to build machines which, within the constraints of finite store, can accurately compute theora of first order predicate calculus ad nauseam but such machines do not display behaviour which is convincingly intelligent. They are cold and mechanical; we do not recognise ourselves in them. Like the Girl in the Fireplace’s beautiful clocks, they are precisely inhuman.

    diff --git a/docs/codox/OnHylasAndPhilonus.html b/docs/codox/OnHylasAndPhilonus.html index a2fd17b..3efb113 100644 --- a/docs/codox/OnHylasAndPhilonus.html +++ b/docs/codox/OnHylasAndPhilonus.html @@ -1,6 +1,6 @@ -On the First Dialogue of Hylas and Philonous

    On the First Dialogue of Hylas and Philonous

    +On the First Dialogue of Hylas and Philonous

    On the First Dialogue of Hylas and Philonous

    The argument that our perception of a ‘real world’ does not prove its existence is not new, of course. Here is a classic statement of a similar argument from BerkeIey’s First Dialogue of Hylas and Philonous:

    Hyl.: Do we not perceive the stars and moon, for example, to be a A great way off? Is not this, I say, manifest to the senses? I

    diff --git a/docs/codox/PredicateSubtext.html b/docs/codox/PredicateSubtext.html index caaa1dc..b4f9e85 100644 --- a/docs/codox/PredicateSubtext.html +++ b/docs/codox/PredicateSubtext.html @@ -1,6 +1,6 @@ -On the subtext of a predicate

    On the subtext of a predicate

    +On the subtext of a predicate

    On the subtext of a predicate

    Predicates are not atomic. They do not come single spies, but freighted with battalions of inferable subtexts. Suppose Anthony says

    Brutus killed Caesar in Rome during the ides of March
     
    diff --git a/docs/codox/TheProblem.html b/docs/codox/TheProblem.html index cad523e..3962a2f 100644 --- a/docs/codox/TheProblem.html +++ b/docs/codox/TheProblem.html @@ -1,6 +1,6 @@ -The Problem

    The Problem

    +The Problem

    The Problem

    In this chapter talk about the perceived need for expert system explanations. Advance:

    the arguments used by expert systems designers, saying why explanations are needed;

    the arguments used by critics which claim that the explanations given are not good enough.

    diff --git a/docs/codox/index.html b/docs/codox/index.html index a7d40f4..ae239a3 100644 --- a/docs/codox/index.html +++ b/docs/codox/index.html @@ -1,3 +1,3 @@ -Wildwood 0.1.0-SNAPSHOT

    Wildwood 0.1.0-SNAPSHOT

    Released under the EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0

    A general inference library using a game theoretic inference mechanism.

    Installation

    To install, add the following dependency to your project or build file:

    [wildwood "0.1.0-SNAPSHOT"]

    Topics

    Namespaces

    wildwood.advocate

    An agent capable of playing the explanation game.

    Public variables and functions:

    wildwood.bialowieza

    The second iteration of the core inference engine for Wildwood

    Public variables and functions:

    wildwood.knowledge-accessor

    The key point of building Bialowieza as a library rather than a complete application is that it should be possible to hook it up to multiple sources of knowledge. Thus we must design a protocol through which knowledge can be accessed, and a schema in which it will be returned. Note that the accessor must be able to add knowledge to the knowledge base, as well as retrieve it.

    Public variables and functions:

      wildwood.schema

      The knowledge representation. This probably ends up looking a bit like a Toulmin schema, where claims are represented as propositions. There also need to be rules or predicates, things which can test whether a given proposition has a given value. There may be other stuff in here.

      Public variables and functions:

      \ No newline at end of file +Wildwood 0.1.0-SNAPSHOT

      Wildwood 0.1.0-SNAPSHOT

      Released under the EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0

      A general inference library using a game theoretic inference mechanism.

      Installation

      To install, add the following dependency to your project or build file:

      [wildwood "0.1.0-SNAPSHOT"]

      Topics

      Namespaces

      wildwood.advocate

      An agent capable of playing the explanation game.

      Public variables and functions:

      wildwood.bialowieza

      The second iteration of the core inference engine for Wildwood

      Public variables and functions:

      wildwood.caesar

      A dummy set of advocates and knowledge accessors with knowledge about the death of Julius Caesar.

      wildwood.dengine.engine

      An implementation of the DTree engine adapted to wildwood.schema propositions.

      Public variables and functions:

      wildwood.dengine.engine

      An implementation of the DTree engine adapted to wildwood.schema propositions.

      Public variables and functions:

      wildwood.knowledge-accessor

      The key point of building Bialowieza as a library rather than a complete application is that it should be possible to hook it up to multiple sources of knowledge. Thus we must design a protocol through which knowledge can be accessed, and a schema in which it will be returned. Note that the accessor must be able to add knowledge to the knowledge base, as well as retrieve it.

      Public variables and functions:

      wildwood.schema

      The knowledge representation. This probably ends up looking a bit like a Toulmin schema, where claims are represented as propositions. There also need to be rules or predicates, things which can test whether a given proposition has a given value. There may be other stuff in here.

      \ No newline at end of file diff --git a/docs/codox/intro.html b/docs/codox/intro.html index 05cb734..9a8690d 100644 --- a/docs/codox/intro.html +++ b/docs/codox/intro.html @@ -1,6 +1,6 @@ -Introduction to Wildwood

      Introduction to Wildwood

      +Introduction to Wildwood

      Introduction to Wildwood

      I started building Wildwood nearly forty years ago on InterLisp-D workstations. Then, because of changing academic projects, I lost access to those machines, and the project was effectively abandoned. But, I’ve kept thinking about it; it has cool ideas.

      Explicable inference

      Wildwood was a follow on from ideas developed in Arboretum, an inference system based on a novel propositional logic using defaults. Arboretum was documented in our paper

      diff --git a/docs/codox/wildwood.advocate.html b/docs/codox/wildwood.advocate.html index 9d5ee9d..4761bba 100644 --- a/docs/codox/wildwood.advocate.html +++ b/docs/codox/wildwood.advocate.html @@ -1,7 +1,7 @@ -wildwood.advocate documentation

      wildwood.advocate

      An agent capable of playing the explanation game.

      +wildwood.advocate documentation

      wildwood.advocate

      An agent capable of playing the explanation game.

      An advocate must have its own knowledge accessor. Different advocates within a game may be accessing different knowledge bases, or different subsets of the same knowledge base with different - potentially competing - knowledge. It also needs to know the schema in which knowledge will be presented.

      Since the mechanism by which the application will communicate with the library must include a way for users to interact with the game, and since the role of the user in the came is just as a participant, advocate must be defined as a protocol, in order that it may be extended by code within the application which is passed in to the game when the game is started. Indeed, multiple agents - the user(s) and potentially non-player characters - may be passed in.

      In this conception, nothing within a default advocate has to be able to produce or consume natural language. It is sufficient for the API exposed by wildwood.advocate to receive and return wildwood.schema objects.

      -

      Obviously to show a user interface anything similar to Arden’s, or for what I intend for The Great Game, the advocates passed must ‘at their other end’ - that is, on the application side rather than the library side - be able to consume and emit natural language, but that functionality does not need to be part of the wildwood library, and certainly does not need to be part of the default advocate as specified here.

      Advocate

      protocol

      members

      decide

      (decide self proposition argument)

      Return true, false or nil as the value of this proposition, given this argument. The value of proposition should be a proposition as defined by wildwood.schema/proposition?; the value of argument should satisfy wildwood.schema/argument?.

      id

      (id self)

      Return a value which uniquely identifies this agent.

      move

      (move self proposition argument)

      Return a new argument structure representing the result of applying my decide method to this proposition and argument, specifying in some way not yet determined what sort of move I have made.

      record

      (record self proposition value)

      Pass a proposition with a determined value to me, in order that advocates can, if desired, record the determined value in their knowledge base. The API does not require that the advocate records the decision, only that it has the opportunity to do so. Return the value.

      \ No newline at end of file +

      Obviously to show a user interface anything similar to Arden’s, or for what I intend for The Great Game, the advocates passed must ‘at their other end’ - that is, on the application side rather than the library side - be able to consume and emit natural language, but that functionality does not need to be part of the wildwood library, and certainly does not need to be part of the default advocate as specified here.

      Advocate

      protocol

      members

      decide

      (decide self proposition argument)

      Return true, false or nil as the value of this proposition, given this argument. The value of proposition should be a proposition as defined by wildwood.schema/proposition?; the value of argument should satisfy wildwood.schema/argument?.

      id

      (id self)

      Return a value which uniquely identifies this agent.

      move

      (move self proposition argument)

      Return a new argument structure representing the result of applying my decide method to this proposition and argument, specifying in some way not yet determined what sort of move I have made.

      record

      (record self proposition value)

      Pass a proposition with a determined value to me, in order that advocates can, if desired, record the determined value in their knowledge base. The API does not require that the advocate records the decision, only that it has the opportunity to do so. Return the value.

      \ No newline at end of file diff --git a/docs/codox/wildwood.bialowieza.html b/docs/codox/wildwood.bialowieza.html index 811122c..f19a5d4 100644 --- a/docs/codox/wildwood.bialowieza.html +++ b/docs/codox/wildwood.bialowieza.html @@ -1,6 +1,6 @@ -wildwood.bialowieza documentation

      wildwood.bialowieza

      The second iteration of the core inference engine for Wildwood

      decide

      (decide proposition & agents)

      Decide the truth value of this proposition by convening a game between these advocate agents. Iterate the game until all agents PASS; then finally offer each agent’s record method the proposition together with the decided truth value (true or false), before returning that value.

      +wildwood.bialowieza documentation

      wildwood.bialowieza

      The second iteration of the core inference engine for Wildwood

      decide

      (decide proposition & agents)

      Decide the truth value of this proposition by convening a game between these advocate agents. Iterate the game until all agents PASS; then finally offer each agent’s record method the proposition together with the decided truth value (true or false), before returning that value.

      The proposition is a proposition as defined in the wildwood.schema; that is to say, the predicate wildwood.schema/predicate? returns true of it. If the proposition isn’t a predicate, throw an exception.

      Each of agents should be an object implementing the wildwood.advocate/Advocate protocol. If an agent isn’t an Advocate, throw an exception.

      Do not throw an exception under any other circumstances.

      diff --git a/docs/codox/wildwood.caesar.html b/docs/codox/wildwood.caesar.html new file mode 100644 index 0000000..be7a70b --- /dev/null +++ b/docs/codox/wildwood.caesar.html @@ -0,0 +1,3 @@ + +wildwood.caesar documentation

      wildwood.caesar

      A dummy set of advocates and knowledge accessors with knowledge about the death of Julius Caesar.

      april

      The month of April, 44BC, as a range.

      drusila-kb

      Drusila knows that Longus killed Caesar in the forum. She keys it on all three, for efficiency of retrieval.

      faldo-db

      Falco knows that Caesar has been killed, but doesn’t know by whom or when.

      gaius-db

      Gaius knows that Brutus killed Caesar, but believes it happened in April.

      ides-of-march

      16th March, 44BC

      marc-anthony-kb

      Mark Antony knows that Brutus is honourable.

      march

      The month of March, 44BC, as a range.

      \ No newline at end of file diff --git a/docs/codox/wildwood.dengine.engine.html b/docs/codox/wildwood.dengine.engine.html new file mode 100644 index 0000000..fc2a9f5 --- /dev/null +++ b/docs/codox/wildwood.dengine.engine.html @@ -0,0 +1,3 @@ + +wildwood.dengine.engine documentation

      wildwood.dengine.engine

      An implementation of the DTree engine adapted to wildwood.schema propositions.

      decide

      (decide proposition node accessor)

      Decide the truth value of this proposition, using the dtree rooted at this node and knowledge provided by this accessor.

      \ No newline at end of file diff --git a/docs/codox/wildwood.dengine.html b/docs/codox/wildwood.dengine.html new file mode 100644 index 0000000..1c400c1 --- /dev/null +++ b/docs/codox/wildwood.dengine.html @@ -0,0 +1,3 @@ + +wildwood.dengine documentation

      wildwood.dengine

      An implementation of the DTree engine adapted to wildwood.schema propositions.

      colour

      (colour node)

      If this node is a valid dtree node, return its colour.

      decide

      (decide proposition node accessor)

      Decide the truth value of this proposition, using the dtree rooted at this node and knowledge provided by this accessor.

      node?

      (node? o)

      Return true if this o is recognisable as a dtree node, else false.

      \ No newline at end of file diff --git a/docs/codox/wildwood.knowledge-accessor.html b/docs/codox/wildwood.knowledge-accessor.html index fdde955..0f836e3 100644 --- a/docs/codox/wildwood.knowledge-accessor.html +++ b/docs/codox/wildwood.knowledge-accessor.html @@ -1,3 +1,3 @@ -wildwood.knowledge-accessor documentation

      wildwood.knowledge-accessor

      The key point of building Bialowieza as a library rather than a complete application is that it should be possible to hook it up to multiple sources of knowledge. Thus we must design a protocol through which knowledge can be accessed, and a schema in which it will be returned. Note that the accessor must be able to add knowledge to the knowledge base, as well as retrieve it.

      \ No newline at end of file +wildwood.knowledge-accessor documentation

      wildwood.knowledge-accessor

      The key point of building Bialowieza as a library rather than a complete application is that it should be possible to hook it up to multiple sources of knowledge. Thus we must design a protocol through which knowledge can be accessed, and a schema in which it will be returned. Note that the accessor must be able to add knowledge to the knowledge base, as well as retrieve it.

      Accessor

      protocol

      members

      fetch

      (fetch self id)

      Fetch all the knowledge I have about the object identified by this id value, as a map whose :id key has this id value.

      store

      (store self id proposition)

      Add this proposition to the knowledge I hold about the object identified by this id value.

      \ No newline at end of file diff --git a/docs/codox/wildwood.schema.html b/docs/codox/wildwood.schema.html index 1276f6f..5cf126f 100644 --- a/docs/codox/wildwood.schema.html +++ b/docs/codox/wildwood.schema.html @@ -1,5 +1,7 @@ -wildwood.schema documentation

      wildwood.schema

      The knowledge representation. This probably ends up looking a bit like a Toulmin schema, where claims are represented as propositions. There also need to be rules or predicates, things which can test whether a given proposition has a given value. There may be other stuff in here.

      -

      Internal representation of most of this will be as Clojure maps.

      argument?

      (argument? o)

      True if o qualifies as an argument structure.

      -

      I don’t yet fully know what an argument looks like, but it is probably conceptually very like a recursive Toulmin structure, or else a list each of whose elements comprises a map with keys : * :vote - true, false or nil; * :move - a keyword representing one of the valid moves in the game; * :agent - something identifying the agent which made the move; * :argument - a Toulmin structure.

      proposition?

      (proposition? o)

      True if o qualifies as a proposition. A proposition is probably a map with some privileged keys, and may look something like a minimised the-great-game.gossip.news-items item.

      rule?

      (rule? o)

      True if o qualifies as a rule. A rule is should be function of one argument, and should (if this can simply be checked) return a truth value, where truth value is one of true, false or nil.

      \ No newline at end of file +wildwood.schema documentation

      wildwood.schema

      The knowledge representation. This probably ends up looking a bit like a Toulmin schema, where claims are represented as propositions. There also need to be rules or predicates, things which can test whether a given proposition has a given value. There may be other stuff in here.

      +

      Internal representation of most of this will be as Clojure maps.

      argument-keys

      Every argument is a proposition, which additionally has these keys.

      argument?

      (argument? o)

      True if o qualifies as an argument structure.

      +

      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.

      consensual-keys

      Every proposition which has these keys, in a given decision process, must have the same semantics and types for their values. The exact representations used for the values of these keys does not matter, it is consensual between all participating advocates in a decision process.

      minimise

      (minimise o)

      Expecting that o is a (potentially rich) proposition, return a map identical to o save that for each value v of key k in o, if v is a map and k is not a member of argument-keys, then the returned map shall substitute the value of (:id v).

      +

      see also wildwood.knowledge-access/maximise.

      proposition?

      (proposition? o)(proposition? o minimised)

      True if o qualifies as a proposition. A proposition is probably a map with some privileged keys, and may look something like a minimised the-great-game.gossip.news-items item.

      +

      If minimised is passed and is true, then the proposition must be minimised - that is to say, the values of keys in a proposition map may not themselves be keys. Where the value of a key represents an object in the world, that value must be simply the id of the object, not a richer representation.

      required-keys

      Every proposition is expected to have values for these keys.

      rule?

      (rule? o)

      True if o qualifies as a rule. A rule is a structure which comprises * an id and * a function of two arguments, a proposition and a knowledge accessor, and which should (if this can simply be checked) return an argument structure.

      truth

      (truth p)

      If p is a proposition, return whether the value asserted by that proposition is true. If the :truth key is missing, true is assumed.

      \ No newline at end of file diff --git a/src/wildwood/caesar.clj b/src/wildwood/caesar.clj index 4cbec27..aed3167 100644 --- a/src/wildwood/caesar.clj +++ b/src/wildwood/caesar.clj @@ -23,14 +23,14 @@ :longus [{:verb :killed :subject :longus :object :caesar :location :forum :date ides-of-march}] :forum [{:verb :killed :subject :longus :object :caesar :location :forum :date ides-of-march}]}) -(defn faldo-db - "Falco knows that Caesar has been killed, but doesn't know who by or when." +(def faldo-db + "Falco knows that Caesar has been killed, but doesn't know by whom or when." {:caesar [{:verb :killed :object :caesar :location :forum}] :brutus [{:verb :killed :object :caesar :location :forum}] :forum [{:verb :killed :object :caesar :location :forum}]}) (def gaius-db - "Gaius knows that Brutus killed him, but thinks it happened in April." + "Gaius knows that Brutus killed Caesar, but believes it happened in April." {:caesar [{:verb :killed :subject :brutus :object :caesar :location :forum :date april}] :brutus [{:verb :killed :subject :brutus :object :caesar :location :forum :date april}] :forum [{:verb :killed :subject :brutus :object :caesar :location :forum :date april}]}) diff --git a/src/wildwood/dengine.clj b/src/wildwood/dengine/engine.clj similarity index 59% rename from src/wildwood/dengine.clj rename to src/wildwood/dengine/engine.clj index f2ac3cd..8bf4614 100644 --- a/src/wildwood/dengine.clj +++ b/src/wildwood/dengine/engine.clj @@ -1,22 +1,11 @@ -(ns wildwood.dengine +(ns wildwood.dengine.engine "An implementation of the DTree engine adapted to `wildwood.schema` propositions." (:require [wildwood.knowledge-accessor :refer [Accessor]] [wildwood.schema :refer [proposition?]])) -(defn node? - "Return `true` if this `o` is recognisable as a dtree node, else `false`." - ;; TODO: implement - false) - -(defn colour - "If this `node` is a valid dtree node, return its colour." - [node] - ;; TODO: implement - false) - (defn decide "Decide the truth value of this `proposition`, using the dtree rooted at - this `node` and knowledge provided by this accessor." + this `node` and knowledge provided by this `accessor`." ;; how is explanation returned in this schema? We need a richer return value ;; than just a truth value. [proposition node accessor] diff --git a/src/wildwood/dengine/node.clj b/src/wildwood/dengine/node.clj new file mode 100644 index 0000000..f26b8ba --- /dev/null +++ b/src/wildwood/dengine/node.clj @@ -0,0 +1,15 @@ +(ns wildwood.dengine.engine + "A dtree node.") + +(defn node? + "Return `true` if this `o` is recognisable as a dtree node, else `false`." + ;; TODO: implement + [o] + false) + +(defn colour + "If this `node` is a valid dtree node, return its colour." + [node] + ;; TODO: implement + false) + diff --git a/src/wildwood/schema.clj b/src/wildwood/schema.clj index 1cab842..bc18649 100644 --- a/src/wildwood/schema.clj +++ b/src/wildwood/schema.clj @@ -17,43 +17,133 @@ representations used for the values of these keys does not matter, it is consensual between all participating advocates in a decision process." - #{:time ;; a representation of time - which should have a canonical ordering - :location ;; a representation of place - which may have concepts of proximity + #{:time ;; a representation of time - which should have a canonical ordering; + :location ;; a representation of place - which may have concepts of proximity; + :truth ;; if present and value `false`, negates the proposition; + :data ;; an argument structure...! }) +(def argument-keys + "Every argument is a proposition, which additionally has these keys." + #{:confidence ;; how sure am I? A value, perhaps, in the range -1 to 1, although conventionally if less than 1 we probably set the `:truth` value to false; + :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 - `the-great-game.gossip.news-items` item. In particular, a proposition must + `the-great-game.gossip.news-items` item. + + If `minimised` is passed and is `true`, then the proposition must be minimised - that is to say, the values of keys in a proposition map may not themselves be keys. Where the value of a key represents an object in the world, that value must be simply the `id` of the object, not a richer representation." - ;; TODO: write this. - [o] - (and - (map? o) - (not (some map? (vals o))) - (every? #(o %) required-keys))) + ([o] + (and + (map? o) + (every? #(o %) required-keys))) + ([o minimised] + (and + (proposition? o)) + (not + (when + (true? minimised) + ;; not good enough. An argument is a proposition even if its argument-keys + ;; 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 + assumed." + ;; TODO: for orthogonality, this might be renamed `decide`. + [p] + (if + (proposition? p) + (if + (false? (:truth p)) + false + 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 should be function of one - argument, and should (if this can simply be checked) return a truth value, - where truth value is one of `true`, `false` or `nil`." + "True if `o` qualifies as a rule. A rule is a structure which comprises + * an id and + * a function of two arguments, a proposition and a knowledge accessor, + and which should (if this can simply be checked) return an argument + structure." [o] - ;; TODO: write this + ;; TODO: write this. In practice it may be simpler if we defprotocol or + ;; defrecord a rule structure. false) (defn argument? "True if `o` qualifies as an argument structure. - I don't yet fully know what an argument looks like, - but it is probably conceptually very like a recursive Toulmin structure, - or else a list each of whose elements comprises a map with keys : - * :vote - `true`, `false` or `nil`; - * :move - a keyword representing one of the valid moves in the game; - * :agent - something identifying the agent which made the move; - * :argument - a Toulmin structure." + 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." [o] - ;; TODO: write this. - false) + (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 + +(defn minimise + "Expecting that `o` is a (potentially rich) proposition, return a map identical + to `o` save that for each value `v` of key `k` in `o`, if `v` is a map and `k` + is not a member of `argument-keys`, then the returned map shall substitute the + value of `(:id v)`. + + see also `wildwood.knowledge-access/maximise`." + [o] + (if + (map? o) + (reduce + merge + {} + (map + (fn [k] + {k + (let [v (k o)] + (if + (and (not (argument-keys k)) (map? v)) + (:id v) + v))}) + (keys o))) + o)) + +;; (proposition? +;; (minimise {:verb :killed +;; :subject {:id :brutus :name "Marcus Brutus"} +;; :object {:id :caesar :name "Gaius Julius Caesar" :wife :drusila}}))