Rules

You build an eXvisory dev chatbot using 5 different logic rule types:

  • Fault - a specific diagnosable fault

  • Fault group - a group of related faults

  • Eliminator - a test that can eliminate or scope a fault group

  • Query test - a test that typically asks the user a question

  • Synthetic test - a test that combines the results of other tests

eXvisory dev is all about enabling you to progressively add diagnostic knowledge without being overwhelmed by complexity. The eXvisory logic rules are carefully constrained to be as simple as possible - expressive enough to model expert troubleshooting, but not so expressive they become incomprehensible at scale (when there are many of them).

Let's look at example logic rules from our sample mobile device troubleshooter.

Fault

  • In the fault containment hierarchy click on the wireless node (it's below device, network and internet in the hierarchy) to select and zoom in on it.

  • Click on the blue flight_mode_enabled node (hovering over nodes expands their text).

  • On the right hand side of the editor select the Fault tab.

  • The editor should look like the screenshot below.

Example fault: flight_mode_enabled

Fault nodes model diagnosable problems. They are shown in blue in the fault containment hierarchy and cannot contain sub-faults. The flight_mode_enabled fault is a networking problem caused by flight mode being inadvertently enabled on a mobile device. It is contained within the network, internet, wireless and flight_mode fault groups. If any of these ancestor fault groups have already been eliminated then inference will never reach this node (it will not be evaluated).

The flight_mode_enabled fault is configured using the JSON editor on the right:

  • _class - uniquely identifies the fault.

  • comment - developer-added comment (appears as a comment in generated code).

  • conditions - evaluates the settings flight_mode test (which asks the user if flight mode is enabled and shows them how to find out) and assigns its result to the variable ?enabled.

  • result - logic expression, if it evaluates to TRUE (in this case if ?enabled is TRUE) then this fault has been diagnosed and inference completes.

  • resources - the found resource is displayed if the fault result evaluates to TRUE.

So, if inference reaches this fault, it runs a test to check whether flight mode is enabled, and if it is enabled it displays a conclusion and inference completes.

Fault group

  • In the fault containment hierarchy click on the wireless node (it's below device, network and internet in the hierarchy) to select and zoom in on it.

  • If you have a mouse wheel, use it to zoom out and back in again. Zooming does not affect the current selection.

  • Click on the white space in the hierarchy to zoom all the way out and select the root node (in our example the device fault group).

  • Click on the wireless node.

  • On the right hand side of the editor select the Fault tab.

  • The editor should look like the screenshot below.

Example fault group: wireless

Fault groups are groups of related faults, organised into a containment hierarchy. The wireless fault group is a subset of the internet fault group, meaning it includes all internet-related faults encountered while using a wireless network. The other internet sub-fault (and peer of wireless) is usb_tether, which includes all internet-related faults encountered using a wired USB network.

At first glance the eXvisory fault containment hierarchy looks like the simple hierarchy of components and sub-components within a product. But while that component hierarchy will always strongly influence the fault containment hierarchy it's not the best way of thinking about it. A better way is to think about groups of faults whose diagnoses share the same initial tests and questions. The higher-level fault groups will represent the shared initial questions, lower-level fault groups represent later, more detailed questions. This isn't always immediately obvious, even to expert troubleshooters, but don't worry - eXvisory dev's graphical editor makes it straightforward to try out different hierarchies and move nodes around.

Editing fault groups is easy, using the JSON editor on the right:

  • _class - uniquely identifies the fault group.

  • comment - a developer-added comment (appears as a comment in generated code).

  • subclasses - ordered list of the _class names of sub-faults (can be fault groups or faults).

Inference proceeds from left-to-right and top-to-bottom through the fault containment hierarchy, so sub-faults will be evaluated in the order of the subclasses list.

You can also re-order subclasses by using CTRL-click-and-drag on the fault containment hierarchy. Try clicking on bt_tether (last child node of wireless), pressing the CTRL key and dragging it on top of flight_mode (first child node of wireless). The sample fault containment hierarchy is read-only so it won't permit the re-ordering, but you can see how it works.

Eliminator

  • In the fault containment hierarchy click on the wireless node (it's below device, network and internet in the hierarchy) to select and zoom in on it.

  • If you have a mouse wheel, use it to zoom out until all the nodes are visible (while keeping the wireless node selected).

  • On the right hand side of the editor select the Eliminators tab.

  • The editor should look like the screenshot below.

Example eliminator: wireless default

Note how the wireless fault group and all of its sub-faults are highlighted in the fault containment hierarchy (and all other nodes are muted). If you could run a test that ELIMINATED all wireless-related Internet faults from consideration, you would at a stroke eliminate all the highlighted wireless sub-faults. Even better, if you could run a test that SCOPED the fault to be a wireless-related Internet fault, you would at a stroke eliminate all the other muted faults in the hierarchy!

That's what an eliminator is - a test that can ELIMINATE or SCOPE a given fault group. It's configured using the JSON editor on the right, under the Eliminator tab:

  • _class - identifies the fault group to which the eliminator belongs.

  • label - all tests require a label to identify them (along with their _class and variant fields). Eliminators are a special kind of test and always have the label "eliminator".

  • variant - a fault group can have multiple eliminators (variants), each of which must have a different variant name. The example eliminator has a single variant called "default" (by convention). Its full name is therefore _class label variant or "wireless eliminator default".

  • comment - developer-added comment (appears as a comment in generated code).

  • conditions - the example eliminator evaluates two tests and assigns their results to variables. The first test is the eliminator from internet, the parent fault group of wireless. The second test is called "internet network" and returns the type of network being used to access the Internet, e.g. "wifi". When there are multiple test conditions all of them are evaluated. If a test has already been evaluated (somewhere else in the hierarchy) it returns its existing result.

  • result - logic expression that uses the variables assigned by conditions to calculate whether the eliminator is UNKNOWN, ELIMINATED or SCOPED. The example expression means "ELIMINATE wireless faults if the Internet is being accessed over USB; otherwise if the fault is SCOPED as an Internet fault (and we're not using USB, so we must be using a wireless network) it must also be SCOPED to wireless faults; otherwise set eliminator to UNKNOWN".

If an eliminator evaluates to ELIMINATED then inference returns from a fault group without evaluating its sub-faults. If an eliminator evaluates to SCOPED then all other unrelated fault groups (outside the eliminator's fault group and its parents and sub-faults) are ELIMINATED and the fault group becomes the suspect fault (useful for partial diagnoses). An eliminator evaluating to UNKNOWN does nothing and inference proceeds to the sub-faults of the eliminator's fault group.

Query test

  • In the fault containment hierarchy click on the internet node (it's below device and network in the hierarchy) to select and zoom in on it.

  • In the right hand side of the editor select the Tests tab.

  • Use the pull down menus (above the JSON editor) to select the internet network test.

  • The editor should look like the screenshot below.

Example query test: internet network

Query tests are questions a chatbot asks its users in order to troubleshoot a problem. They typically involve asking the user to inspect product settings or perform diagnostic tests. Query tests at first glance may look a little more complicated (in the screenshot above) but are easy to configure:

  • _class - identifies the fault (or fault group) to which the test is assigned. This is somewhat arbitrary (a test can be assigned to any fault) but assigning it to a logically related fault helps legibility.

  • label - all tests require a label to identify them (along with their _class and variant fields).

  • comment - developer-added comment (appears as a comment in generated code).

  • _values - the example query test asks the user "Which network are you using to connect to the Internet?". The _valuesfield shows that this is a multiple choice question and the string array containing "wifi", "mobile", "bluetooth" and "usb" are the logical options used internally. The visible descriptions for each option (which are presented to the user) are entered in the corresponding "wifi", "mobile", "bluetooth", "usb" fields of the resources object.

  • resources - there are three types of string resources in this example test. The "prompt" resource is the question presented to the user, the "help" resource tells the user how to answer the question and the remaining resources are the visible multiple choice answers. Most string resources can use templates to refer to previously evaluated test results and Markdown for formatting.

As you can see from the screenshot the test's string resources use templating to refer to previously evaluated tests. This is very powerful and enables tests to be reused across similar but different products, significantly reducing complexity. For example, this test provides different "help" for iOS, Android and Windows mobile devices. Note also that most of the help is via links to curated articles from the Internet. For scalability and maintainability as little specific product knowledge should be built into deep logic networks as possible. Most product specific knowledge should come from Internet links.

Synthetic test

  • In the fault containment hierarchy click on the network node (it's below the device root node in the hierarchy) to select and zoom in on it.

  • In the right hand side of the editor select the Tests tab.

  • Use the pull down menus (above the JSON editor) to select the network symptom test.

  • The editor should look like the screenshot below.

Example synthetic test: network symptom

Synthetic tests are tests that logically combine the results of other tests, to deduce intermediate facts or conclusions useful to the diagnostic process. Synthetic tests execute 'in the background' and do not ask the user questions, but they can output explanations and deductions. They are configured using the JSON editor on the right, under the Tests tab:

  • _class - identifies the fault (or fault group) to which the test is assigned. This is somewhat arbitrary (a test can be assigned to any fault) but assigning it to a logically related fault helps legibility.

  • label - all tests require a label to identify them (along with their _class and variant fields).

  • comment - developer-added comment (appears as a comment in generated code).

  • conditions - the example synthetic test network symptom evaluates two tests and assigns their results to variables. The first device symptom test is a query test that asks the user to select high-level problem symptoms from a multiple choice list. The second triage subsymptom test asks the user for subsymptoms (it's actually composed from multiple test variants, one for each possible device symptom, but it is used as a single test).

  • result - logic expression that in the network symptom example uses the conditions variables to calculate whether the reported symptoms and subsymptons could be network-related. The logic expression uses a slightly odd looking syntax (from LISP - now you're doing AI :) but with practice it's easy to understand. The example expression means "return TRUE if the symptom is not any of the listed values or the subsymptom is not any of the other listed values, otherwise return FALSE".