Table of Contents

Documentation

The documentation of Prudens JS is under constant revisions and extensions! :)

For more details regarding the theory behind Prudens JS (i.e., Machine Coaching), consult this paper.

Introduction

Suppose you own one of these robot vacuum cleaners and also suppose that you can interact with it in order to train it to behave as per your commands. Now, suppose that once you charge your robot vacuum cleaner, you give it the following command:

"Clean all the house every day at 7 PM!"

Now, let us suppose that it is Sunday afternoon, 6:59 PM and that you are relaxing. Suddenly, you hear an annoying sound coming from the living room: it is the robot vacuum cleaner that has just started cleaning. At this time you realise that you should make some adjustments to your cleaner's settings. Namely, you get up, go to your living room and give the following command to your cleaner:

"Do not clean the house at 7 PM on Sundays! Instead, wait for me to tell you when to start cleaning on Sundays!"

In the above, you have just provided your automated cleaner with an exception, in the sense that while its general cleaning policy will be to clean every day at 7 PM, on Sundays it should deviate from it and wait for your order to do so. Proceeding in this way, you may find more circumstances in which you would like your cleaner to deviate from its previous policy and temporarily adopt some other behaviour.

Situations like the one described above, where a human coaches a machine in order to accomplish some certain task as per their desire are captured by Machine Coaching (MC). In short, MC is an iterative human-machine interaction through which a human can transfer knowledge to an agent who, in turn, acts based on it and returns explanations in the forms of arguments constructed from the knowledge it has accumulated. Upon each such argument the user may provide some input in the form of some counter-argument, in order to update the agent's knowledge.

The language of Prudens

Since MC offers a means of communication between humans and machines, it is natural that there should exist some common language through which knowledge is transferred from the human end-user to the machine agent and vice-versa. In this section we will describe the syntax and semantics of this declarative language.

Predicates, variables and constants

At some extent, Prudens's language shares several common features with prolog. To begin with, Prudens's language allows for predicates to be used to denote relations between entities of the universe. Syntactically, each predicate consists of two parts:

  • its name, which starts with a lower-case letter of the Latin alphabet (a-z) which may be followed by any finite sequence of letters (a-z, A-Z), digits (0-9) and underscores (_), and;
  • its list of arguments, which follows its name separated by no other character and consists of a comma-separated list of arguments enclosed in left and right parentheses.

So, the syntactical form of a predicate is the following:

name(arg1,arg2,...,argn).

We will refer to the (fixed) number, n, of arguments appearing in a predicate's arguments list as the predicate's arity and we will also refer to a predicate of arity n as an n-ary predicate.

Regarding a predicate's arguments, they are restricted to be either constants or variables. Constants are intended to be interpreted as specific entities of our universe while variables serve as placeholders for constants. In Prudens's language, constants are represented by strings which start with a lower-case letter (a-z) which may be followed by any finite sequence of letters (a-z, A-Z), digits (0-9) and underscores (_) - exactly as with a predicate's name. On the other hand, variables are represented by string which start with an upper-case letter (A-Z) which may again be followed by any finite sequence of letters (a-z, A-Z), digits (0-9) and underscores (_). So, for instance, the following:

fatherOf(X,bob)

is a binary predicate symbol, fatherOf(·,·), with an arguments list consisting of a variable, X, and a constant, bob. In case we interpret fatherOf(X,Y) as "X is the father of Y" and assume that there exists some entity named Bob in our universe, then the above may be interpreted as "Someone (X) is the father of Bob".

The only exception to the above are two built-in predicates, namely ?=(·,·) and ?<(·,·). As their name suggests, they denote equality and inequality in terms of math constants. That is, ?=(X,Y) is always interpreted as "X equals Y" as well as ?<(X,Y) is always interpreted as "X is less than Y". Moreover, ?=(·,·) also serves as a predicate that allows an ungrounded variable to be unified with a constant under certain circumstances.

Note that Prudens's language does not allow for function symbols, in general. That is, in case one needs to express a relation such as "2 is the successor of 1" then, instead of a typical functional notation such as:

2 = successor(1)

where successor(·) denotes the successor function on natural numbers, one should use a predicate-oriented notation such as:

successor(2,1)

where successor(·,·) is a binary predicate which is interpreted as "The first argument is the successor of the second one".

The only exception to the above occurs in the case of maths or other native Javascript functions which may be called within the scope of ?=(·,·) and ?<(·,·) or any custom Javascript predicate.

Literals, Rules, Knowledge Bases and Contexts

Predicates, variables and constants are the building blocks with which one can construct rules that capture desired behaviours or define new relations between entities of our universe. The first thing one may build with predicates is a literal. A literal in the context of Prudens's language is either a predicate itself or a negated predicate, where negation is denoted by the minus symbol (-) preceding the predicate's name - no spaces are allowed between the predicate's name and the negation symbol. So, for instance, the following are both literals:

fatherOf(X,bob), -fatherOf(Y,alice)

At this point we should highlight that negation within the context of Prudens's language is treated as classical negation which is not what happens e.g. with prolog. To shed more light on this subtle difference let us consider the following two literals:

fatherOf(george,bob); fatherOf(alice,george);

Under the Closed World Assumption (CWA) - i.e. by treating negation as failure - we can infer from the above that -fatherOf(george,jim) since the literal fatherOf(george,jim) is not included in our knowledge and, due to the CWA, it is not true. However, in the setting of Prudens's language, we cannot infer from the above that -fatherOf(george,jim), since we have not accepted any form of CWA.

Having clarified the status of negation in the context of Prudens's language, we proceed with rules. Rules in the context of Prudens's language consist of the following:

  • a name, which is separated by :: from the rule's main part;
  • a body, which is a comma-separated list of literals and;
  • a head, which is a single literal.

For instance, the following string is a rule:

Rule_1 :: fatherOf(X, Y), fatherOf(X, Z) implies siblings(Y, Z).

It is important to note at this point that all three attributes of a rule - i.e. its name, its body and its head - should not be empty. So, a rule cannot be nameless, and one may not infer anything having no hypotheses.

Using rules, one may construct knowledge bases, which are order lists of rules. For instance, the following list of two rules is considered a knowledge base:

Rule_1 :: f(X), g(X, Y) implies h(X);
Rule_2 :: f(X) implies -h(X);

The same applies for the following one:

Rule_2 :: f(X) implies -h(X);
Rule_1 :: f(X), g(X, Y) implies h(X);

Observe that, as we have mentioned above, knowledge bases are ordered lists of rules. So, the above two knowledge bases are different. For more on how the order of rules affects inference, see the corresponding section.

As one may observe, knowledge bases encode knowledge in the form of prioritized if-then rules. Another structure that encodes knowledge within Prudens's language are contexts. A context is a set of pairwise non-conflicting variable-free literals. That is, any literal that is included in a context has all its variables substituted with some constants. So, while e.g. f(a,b) may be included in some context, f(X,b) may not be part of any context, due to X being not substituted with some constant. So, an example of a context is the following one:

f(a); f(b); g(a, b); h(a, b, c);

Observe that, as with knowledge bases, the different entries of a context are separated from each other with a semicolon (;).

Inference

As we have mentioned above, Prudens's language allows for two separate structures to encode knowledge:

  • Knowledge bases, which are ordered collections of rules and;
  • contexts, which ara (unordered) lists of instantiated and pairwise non-conflicting literals.

As far as the first are concerned, knowledge bases are intended to represent knowledge in the form of general rules that describe some certain behaviour across several possible situations. On the other hand, contexts encode knowledge in the form of facts describing a specific situation. So, within the context of Prudens's language, contexts contain idisputable facts that hold at some certain occasion while a knowledge base contains general rules that are triggered by a contextual facts.

Rules and Priorities

To clarify things a little more, consider the following knowledge base, let KB1:

Rule_3 :: isSunday(X), isRaining(X) implies action(atHome);
Rule_2 :: isSunday(X), isRaining(X) implies -action(playOutside);
Rule_1 :: isSunday(X) implies action(playOutside);

KB1 encodes a simple policy regarding what to do (or not to do) on Sundays. Namely, Rule_1 informs us that we are willing to go and play outside on Sundays. However, Rule_2 adds an exception to the above general behaviour. Namely, on rainy Sundays, we are not willing to play outside but, instead, as Rule_3 informs us, we prefer staying at home. So, KB1 encodes our behaviour across two possible scenarios:

  • on a casual sunny Sunday we prefer to play outside but;
  • on a rainy Sunday we prefer staying at home.

The two above scenarios can be encoded using two contexts, namely, context C1:

isSunday(today)

which encodes the first scenario - a casual (non-rainy) Sunday and context C2:

isSunday(today); isRaining(today);

which encodes the second scenario - a rainy Sunday.

Observe in the above how the order of the rules plays an important role. As we have said, a knowledge base is an ordered list of rules. The order of appearance of rules in a knowledge base determines what happens when two conflicting rules have been triggered at the same time. Namely, in the above case where under C2 both Rule_1 and Rule_2 are triggered, since Rule_2 appears higher than Rule_1 in KB1, we infer that Rule_2 is of higher priority than Rule_1 and, hence, we ignore the latter in favour of Rule_2.

In case we had the following knowledge base, let KB2, instead of KB1, things would be different:

Rule_1 :: isSunday(X) implies action(playOutside);
Rule_3 :: isSunday(X), isRaining(X) implies action(atHome);
Rule_2 :: isSunday(X), isRaining(X) implies -action(playOutside);

In the above situation, Rule_1 is considered of higher priority over any other rule and, consequently, in both C1 and C2 our action would be to go outside and play - since rules Rule_2 and Rule_3 are either not triggered - in C1 - or triggered but dismissed due to being of lower priority than Rule_1 - in C2.

Rule Chaining

To be continued...

Known bugs

  • #001: Ctrl+A does not function properly inside the "Knowledge Base" and "Context" code editors. Namely, the text is selected and un-selected within less than 200ms.
  • #002: The "_" shortcut for dummy variables - i.e. variables that are of no significance in some certain predicate - is not properly supported yet.
  • #003: Custom Javascript predicates as well as ?= and ?< predicates are not fully supported yet.
  • #004: Syntax highlighting is not fully supported yet in none of the two editors.
  • #005: Syntax error codes regarding Prudens's language are still under development. Thus, all errors as for now fall into the same category - namely, KnowledgeBaseSyntaxError.
  • #006: Ctrl+Z keyboard shortcut does not work properly - neither does the Right click > Undo/Redo functionality in both "Knowledge Base" and "Context" code editors.
  • #007: In the "graph" part of a deduction's output, only the first rule that has led to the corresponding literal is presented.
  • #008: When ?= is used as the first (or single) predicate in a rule's body, reasoning yields unpredictable results - however, when used at a later position in a rule, it works as expected.