Decision tables: Difference between revisions

m
m (→‎{{header|REXX}}: added support for superfluous blanks in answer. -- ~~~~)
m (→‎{{header|Wren}}: Minor tidy)
 
(45 intermediate revisions by 23 users not shown)
Line 1:
{{draft task}}
 
[[wp:Decision_table|Decision Tables]] are a precise yet compact way to model complicated logic. Demonstrate how your language implements decision tables. Use the example of Printer Troubleshooting given in the Wikipedia article.
{{Wikipedia|Decision Table|en}}<br>
 
[[wp:Decision_table|Decision Tables]] are a precise yet compact way to model complicated logic.
 
 
;Task:
Demonstrate how your language implements decision tables.
 
Use this [[wp:Decision_table#Example|example]] of Printer Troubleshooting given in the Wikipedia article.
<br><br>
 
=={{header|11l}}==
{{trans|Kotlin}}
 
<syntaxhighlight lang="11l">V conditions = [
(‘Printer prints’ , ‘NNNNYYYY’),
(‘A red light is flashing’ , ‘YYNNYYNN’),
(‘Printer is recognized by computer’, ‘NYNYNYNY’)]
 
V actions = [
(‘Check the power cable’ , ‘NNYNNNNN’),
(‘Check the printer-computer cable’ , ‘YNYNNNNN’),
(‘Ensure printer software is installed’, ‘YNYNYNYN’),
(‘Check/replace ink’ , ‘YYNNNYNN’),
(‘Check for paper jam’ , ‘NYNYNNNN’)]
 
V nr = conditions[0][1].len
V np = 7
print(‘Please answer the following questions with a y or n:’)
 
[Bool] answers
L(condition) conditions
V inp = ‘’
L
inp = input(‘ ’condition[0]‘ ? ’).uppercase()
I inp C (‘Y’, ‘N’)
L.break
answers.append(inp == ‘Y’)
 
print("\nRecommended action(s):")
L(r) 0 .< nr
L(c) 0 .< conditions.len
V yn = I answers[c] {‘Y’} E ‘N’
I conditions[c][1][r] != yn
L.break
L.was_no_break
I r == np
print(‘ None (no problem detected)’)
E
L(action) actions
I action[1][r] == ‘Y’
print(‘ ’action[0])
L.break</syntaxhighlight>
 
{{out}}
<pre>
Please answer the following questions with a y or n:
Printer prints ? n
A red light is flashing ? n
Printer is recognized by computer ? n
 
Recommended action(s):
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
</pre>
 
=={{header|Ada}}==
First the specification of a generic decision table package:
<langsyntaxhighlight Adalang="ada">generic
type Condition is (<>);
type Action is (<>);
Line 23 ⟶ 89:
 
end Generic_Decision_Table;
</syntaxhighlight>
</lang>
Next, the implementation of the generic decision table package:
<langsyntaxhighlight Adalang="ada">package body Generic_Decision_Table is
procedure React(Rules: Rule_A) is
A: Answers;
Line 45 ⟶ 111:
 
end Generic_Decision_Table;
</syntaxhighlight>
</lang>
That was easy! Now we implement the printer troubleshooting application:
<langsyntaxhighlight Adalang="ada">with Generic_Decision_Table, Ada.Text_IO;
 
procedure Printer_Decision_Table is
Line 114 ⟶ 180:
begin
DT.React(R);
end Printer_Decision_Table;</langsyntaxhighlight>
Sample output:
<pre>> ./printer_decision_table
Line 143 ⟶ 209:
n
Sorry! I have no idea what to do now!</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">Conditions =
(
Printer does not print |Y|Y|Y|Y|N|N|N|N|
A red light is flashing |Y|Y|N|N|Y|Y|N|N|
Printer is unrecognized |Y|N|Y|N|Y|N|Y|N|
)
 
Actions=
(
Check the power cable | | |x| | | | | |
Check the printer-computer cable |x| |x| | | | | |
Ensure printer software is installed |x| |x| |x| |x| |
Check/replace ink |x|x| | |x|x| | |
Check for paper jam | |x| |x| | | | |
)
 
Condition:=[], Action:=[], Correlation:=[]
loop, parse, Conditions, `n
{
No:= A_Index, RegExMatch(A_LoopField, "^(.*?)\t+(.*)", m), Cond%No% := m1
for k, v in StrSplit(m2, "|")
Condition[No, k] := v="Y"?1:0
}
loop, parse, Actions, `n
{
No:= A_Index , RegExMatch(A_LoopField, "^(.*?)\t+(.*)", m), Act%No% := m1
for k, v in StrSplit(m2, "|")
Action[No, A_Index] := v="X"?1:0
}
 
loop, % Condition[1].MaxIndex()
{
j := A_Index, CondLine:=ActLine:=""
loop, % Condition.MaxIndex()
CondLine .= Condition[A_Index,j]
loop, % Action.MaxIndex()
ActLine.= Action[A_Index,j]?1:0
Correlation[CondLine]:=ActLine
}
 
Gui, font,, Courier
Gui, add, text, w456
Gui, add, text, wp h1 0x7 y+0
loop, parse, Conditions, `n
{
Gui, add, text, y+0 , % A_LoopField
Gui, add, text, wp h1 0x7 y+0
}
Gui, add, text, wp
Gui, add, text, wp h1 0x7 y+0
loop, parse, Actions, `n
{
Gui, add, text, y+0 , % A_LoopField
Gui, add, text, wp h1 0x7 y+0
}
Gui, add, text, wp
loop, % Condition.MaxIndex()
Gui, add, Checkbox,vC%A_Index% gSubmit wp h15, % Cond%A_Index%
Gui, add, text, wp , take the following actions(s):
AM := Action.MaxIndex()
Gui, add, Edit, vOutput ReadOnly r%AM% wp -TabStop
Gui, show
return
 
Submit:
Gui, Submit, NoHide
CondLine:=Res:=""
loop, % Condition.MaxIndex()
CondLine.= C%A_Index%
MyCorr := Correlation[CondLine]
loop, parse, MyCorr
if A_LoopField
Res .= Act%A_Index% "`n"
GuiControl,, Output, % Res
return</syntaxhighlight>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f DECISION_TABLES.AWK DECISION_TABLES.TXT
BEGIN {
FS = ":"
}
{ if ($0 ~ /^#/) { # comment
next
}
if (rule_length == 0) { # 1st rule
rule_length = length($2)
}
if (rule_length != length($2)) {
error(sprintf("FILENAME=%s, FNR=%d, rule length not consistent with previous lengths, %s",FILENAME,FNR,$0))
}
if ($1 == "C") { # condition
if ($2 !~ /^[NY]+$/) {
error(sprintf("FILENAME=%s, FNR=%d, rule S/B 'N' or 'Y', %s",FILENAME,FNR,$0))
}
c_arr[++c] = $2 SUBSEP $3
}
else if ($1 == "A") { # action
if ($2 !~ /^[X-]+$/) {
error(sprintf("FILENAME=%s, FNR=%d, rule S/B 'X' or '-', %s",FILENAME,FNR,$0))
}
a_arr[++a] = $2 SUBSEP $3
}
}
END {
validate_rules()
if (errors > 0) { exit(1) }
show_actions(ask_conditions())
exit(0)
}
function ask_conditions( ans,i,key) {
print("condtions:")
for (i=1; i<=c; i++) {
while (1) {
printf(" %s? ",getext(c_arr[i]))
getline ans <"con"
if (ans ~ /^[nNyY]/) {
key = key toupper(substr(ans,1,1))
break
}
}
}
return(key)
}
function getext(str) {
return(substr(str,index(str,SUBSEP)+1))
}
function show_actions(user_reply, hits,i,key) {
key = key_arr[user_reply]
print("actions:")
for (i=1; i<=a; i++) {
if (substr(a_arr[i],key,1) == "X") {
printf(" %s\n",getext(a_arr[i]))
hits++
}
}
printf("%d found\n",hits)
}
function validate_rules( i,j,key) {
for (i=1; i<=rule_length; i++) {
key = ""
for (j=1; j<=c; j++) {
key = key substr(c_arr[j],i,1)
}
if (key in key_arr) {
error(sprintf("duplicate key: %s",key))
}
key_arr[key] = i
}
}
function error(message) {
printf("error: %s\n",message)
errors++
return
}
</syntaxhighlight>
<p>decision table:</p>
<pre>
# RULES CONDITIONS
C:YYYYNNNN:Printer does not print
C:YYNNYYNN:A red light is flashing
C:YNYNYNYN:Printer is unrecognized
# RULES ACTIONS
A:--X-----:Check the power cable
A:X-X-----:Check the printer-computer cable
A:X-X-X-X-:Ensure printer software is installed
A:XX--XX--:Check/replace ink
A:-X-X----:Check for paper jam
</pre>
<p>Output:</p>
<pre>
condtions:
Printer does not print? Y
A red light is flashing? Y
Printer is unrecognized? Y
actions:
Check the printer-computer cable
Ensure printer software is installed
Check/replace ink
3 found
 
condtions:
Printer does not print? N
A red light is flashing? N
Printer is unrecognized? N
actions:
0 found
</pre>
 
=={{header|C}}==
With flaky keyboard input:<langsyntaxhighlight Clang="c">#include <stdio.h>
#define N_COND 3
Line 184 ⟶ 441:
}
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text">Printer does not print? y
A red light is flashing? n
Printer is unrecognised? y
Line 191 ⟶ 448:
Check the power cable
Check the printer-computer cable
Ensure printer software is installed</langsyntaxhighlight>
 
=={{header|C++}}==
{{trans|Java}}
<syntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <vector>
 
const std::vector<std::pair<std::string, std::string>> conditions = {
{"Printer prints", "NNNNYYYY"},
{"A red light is flashing", "YYNNYYNN"},
{"Printer is recognized by computer", "NYNYNYNY"}
};
 
const std::vector<std::pair<std::string, std::string>> actions = {
{"Check the power cable", "NNYNNNNN"},
{"Check the printer-computer cable", "YNYNNNNN"},
{"Ensure printer software is installed", "YNYNYNYN"},
{"Check/replace ink", "YYNNNYNN"},
{"Check for paper jam", "NYNYNNNN"},
};
 
int main() {
const size_t nc = conditions.size();
const size_t na = actions.size();
const size_t nr = conditions[0].second.size();
const int np = 7;
 
auto answers = new bool[nc];
std::string input;
 
std::cout << "Please answer the following questions with a y or n:\n";
for (size_t c = 0; c < nc; c++) {
char ans;
do {
std::cout << conditions[c].first << "? ";
 
std::getline(std::cin, input);
ans = std::toupper(input[0]);
} while (ans != 'Y' && ans != 'N');
answers[c] = ans == 'Y';
}
 
std::cout << "Recommended action(s)\n";
for (size_t r = 0; r < nr; r++) {
for (size_t c = 0; c < nc; c++) {
char yn = answers[c] ? 'Y' : 'N';
if (conditions[c].second[r] != yn) {
goto outer;
}
}
if (r == np) {
std::cout << " None (no problem detected)\n";
} else {
for (auto action : actions) {
if (action.second[r] == 'Y') {
std::cout << " " << action.first << '\n';
}
}
}
break;
 
outer: {}
}
 
delete[] answers;
return 0;
}</syntaxhighlight>
{{out}}
<pre>Please answer the following questions with a y or n:
Printer prints? n
A red light is flashing? n
Printer is recognized by computer? n
Recommended action(s)
Check the power cable
Check the printer-computer cable
Ensure printer software is installed</pre>
 
=={{header|COBOL}}==
<syntaxhighlight lang="cobol"> >> SOURCE FORMAT FREE
identification division.
program-id. 'decisiontable'.
 
environment division.
configuration section.
repository.
function all intrinsic.
 
data division.
 
working-storage section.
 
01 conditions.
03 notprinting pic x.
03 flashing pic x.
03 notrecognized pic x.
 
procedure division.
start-decision-table.
 
display space
 
display 'The printer does not print (Y or N) ' with no advancing
accept notprinting
 
display 'A red light is flashing (Y or N) ' with no advancing
accept flashing
 
display 'The printer is unrecognized (Y or N) ' with no advancing
accept notrecognized
 
move upper-case(conditions) to conditions
 
display space
 
*>decision table Printer troubleshooter
 
*> conditions
*>Printer does not print Y Y Y Y N N N N
*>A red light is flashing Y Y N N Y Y N N
*>Printer is unrecognized Y N Y N Y N Y N
*> actions
*>Check the power cable X
*>Check the printer-computer cable X X
*>Ensure printer software is installed X X X X
*>Check/replace ink X X X X
*>Check for paper jam X X
 
*>end decision table
 
evaluate notprinting also flashing also notrecognized
 
when 'Y' also 'Y' also 'Y'
display 'Check the printer-computer cable'
display 'Ensure printer software is installed'
display 'Check/replace ink'
 
when 'Y' also 'Y' also 'N'
display 'Check/replace ink'
display 'Check for paper jam'
 
when 'Y' also 'N' also 'Y'
display 'Check the power cable'
display 'Check the printer-computer cable'
display 'Ensure printer software is installed'
 
when 'Y' also 'N' also 'N'
display 'Check for paper jam'
 
when 'N' also 'Y' also 'Y'
display 'Ensure printer software is installed'
display 'Check/replace ink'
 
when 'N' also 'Y' also 'N'
display 'Check/replace ink'
 
when 'N' also 'N' also 'Y'
display 'Ensure printer software is installed'
 
when 'N' also 'N' also 'N'
display 'no action found'
 
when other
display 'invalid input: ' notprinting space flashing space notrecognized
 
end-evaluate
 
display space
 
stop run
.
 
end program 'decisiontable'.
</syntaxhighlight>
 
{{out}}
<pre>$ cobc -xj decisiontable.cob
The printer does not print (Y or N) n
A red light is flashing (Y or N) n
The printer is unrecognized (Y or N) y
Ensure printer software is installed
</pre>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.exception, std.array;
 
immutable struct DecisionTable {
alias immutable(bool)[] IBA;
const string[] conds, actions;
Line 204 ⟶ 644:
in size_t newLen)
pure nothrow {
bool[]auto result = new bool[newLen];
result[0 .. b.length] = b[];
return assumeUnique(result).assumeUnique;
}
 
this(inimmutable string[] c, in string[] a, in bool[][][] q)
immutable string[] a,
const pure nothrow {
immutable bool[][][] q) pure nothrow {
conds = c;
actions = a;
Line 217 ⟶ 658:
r[growTo(p[0], conds.length)] =
growTo(p[1], actions.length);
rules = assumeUnique(r).assumeUnique;
}
 
Line 226 ⟶ 667:
auto iTested = growTo(tested, conds.length);
if (iTested in rules)
foreach (immutable i, immutable(byte) e; rules[iTested])
if (e) rightActions ~= actions[i];
rightActions ~= actions[i];
 
if (!rightActions.empty)
Line 241 ⟶ 683:
string answer = "no";
try
answer = stdin.readln();
catch (StdioException)
writeln("no");
Line 253 ⟶ 695:
void main() {
enum { F = false, T = true }
immutable d = immutable(DecisionTable)(
["Printer is unrecognised",
"A red light is flashing",
Line 274 ⟶ 716:
);
 
d.consult();
}</langsyntaxhighlight>
{{out}}
<pre>Printer is unrecognised? [y=yes/others=no] no
Line 284 ⟶ 726:
===Alternative Version===
{{trans|C}}
<langsyntaxhighlight lang="d">import std.stdio, std.string;
 
struct DataPair(size_t N) { string message, truth; }
string message;
immutable char[N] truth;
}
 
immutable DataPair!8[] conditions = [
{"Printer does not print", "####...."},
{"A red light is flashing", "##..##.."},
{"Printer is unrecognised", "#.#.#.#."}];
 
immutable DataPair!8[] solutions = [
{"Check the power cable", "..#....."},
{"Check the printer-computer cable", "#.#....."},
Line 301 ⟶ 746:
 
void main() {
size_t code = 0;
 
foreach (immutable cond; conditions) {
write(cond.message, "? [y=yes/others=no] ");
string answer = "no";
Line 317 ⟶ 762:
else {
writeln("\nSolutions:");
foreach (immutable sol; solutions)
if (sol.truth[code] == '#')
writeln(" ", sol.message);
}
}</langsyntaxhighlight>
{{out}}
<pre>Printer does not print? [y=yes/others=no] no
Line 328 ⟶ 773:
 
So, you don't have a problem then?</pre>
 
Keyboard handling is sketchy, just type "true" or "false" to each question.
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">dim as boolean rules(0 to 2, 0 to 7) =_
{ {false, false, false, false, true, true, true, true},_
{ true, true, false, false, true, true, false, false},_
{false, true, false, true, false, true, false, true} }
 
dim as boolean actions(0 to 4, 0 to 7) =_
{ {false, false, true, false, false, false, false, false},_
{ true, false, true, false, false, false, false, false},_
{ true, false, true, false, true, false, true, false},_
{ true, true, false, false, false, true, false, false},_
{false, true, false, true, false, false, false, false} }
dim as string rule_names(0 to 2) =_
{"Printer prints", "A red light is flashing",_
"Printer is recognized by computer"}
dim as string action_names(0 to 4) = _
{"Check the power cable", "Check the printer-computer cable",_
"Ensure printer software is installed", "Check/replace ink",_
"Check for paper jam" }
 
dim as boolean answers(0 to 2)
 
for i as uinteger = 0 to 2
print rule_names(i),
input answers(i)
next i
 
print "---- Suggested solutions: ----"
 
for i as uinteger = 0 to 4
for j as uinteger = 0 to 7
if not actions(i, j) then continue for
for k as uinteger = 0 to 2
if rules(k, j)<>answers(j) then goto dontdoit
next k
print action_names(i)
dontdoit:
next j
next i</syntaxhighlight>
 
=={{header|Go}}==
Go has no specific support for decision tables, but they can be implemented easily. With a little ingenuity, literal data can be arranged in rows and columns in a way that preserves the visual associations of decision tables. Go has an init function that might be useful for compiling decision tables at program startup. And Go maps allow efficient lookup of actions given conditions.
<langsyntaxhighlight lang="go">package main
 
import (
Line 414 ⟶ 903:
fmt.Println(a)
}
}</langsyntaxhighlight>
Output:
<pre>
Line 422 ⟶ 911:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">record cond(text,flags)
record act(text,flags,aflags)
 
Line 472 ⟶ 961:
}
}
end</langsyntaxhighlight>
 
Sample Output:<pre>Printer does not print ? Y
Line 481 ⟶ 970:
 
=={{header|J}}==
'''Solution''':<langsyntaxhighlight lang="j">require'strings'
 
'RULE_NAMES RULES'=: |:':'&cut;._2 noun define
Line 507 ⟶ 996:
options=. a #~ y {~ #. 'Y'={.@toupper@deb@(1!:1)@1:@smoutput@,&'?'@dtb"1 q
(,~ ('/'cut'Suggested resolutions:/Solution unknown.') {::~ 0=#) options
)</langsyntaxhighlight>
 
'''Example''' (''solution found''):<langsyntaxhighlight lang="j"> troubleshoot ''
Having trouble? Let's track down the problem:
Printer does not print?
Line 520 ⟶ 1,009:
Check the printer-computer cable
Ensure printer software is installed
Check/replace ink </langsyntaxhighlight>
'''Example''' (''solution not found''):<langsyntaxhighlight lang="j"> troubleshoot ''
Having trouble? Let's track down the problem:
Printer does not print?
Line 530 ⟶ 1,019:
N
Solution unknown.
</syntaxhighlight>
</lang>
 
=== Comments ===
Line 537 ⟶ 1,026:
For large numbers of rules and few actions, J's native support of sparse arrays might provide a performance advantage, particularly in space. A minor note about the implementation here: the verb (function) <tt>troubleshoot</tt> is generalized, and reusable on any set of rule table, questions, and suggested actions. The default is to use those given in the printer troubleshooting table.
 
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Objects;
 
public class DecisionTables {
private static class Pair<T, U> {
private final T t;
private final U u;
 
public static <T, U> Pair<T, U> of(T t, U u) {
return new Pair<>(t, u);
}
 
public Pair(T t, U u) {
this.t = t;
this.u = u;
}
 
public T getFirst() {
return t;
}
 
public U getSecond() {
return u;
}
}
 
private static final List<Pair<String, String>> conditions = List.of(
Pair.of("Printer prints", "NNNNYYYY"),
Pair.of("A red light is flashing", "YYNNYYNN"),
Pair.of("Printer is recognized by computer", "NYNYNYNY")
);
 
private static final List<Pair<String, String>> actions = List.of(
Pair.of("Check the power cable", "NNYNNNNN"),
Pair.of("Check the printer-computer cable", "YNYNNNNN"),
Pair.of("Ensure printer software is installed", "YNYNYNYN"),
Pair.of("Check/replace ink", "YYNNNYNN"),
Pair.of("Check for paper jam", "NYNYNNNN")
);
 
public static void main(String[] args) throws IOException {
final int nc = conditions.size();
final int na = actions.size();
final int nr = conditions.get(0).getSecond().length();
final int np = 7;
 
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
System.out.println("Please answer the following questions with a y or n:");
final boolean[] answers = new boolean[nc];
for (int c = 0; c < nc; ++c) {
String input;
do {
System.out.printf(" %s ? ", conditions.get(c).getFirst());
input = br.readLine().toUpperCase();
} while (!Objects.equals(input, "Y") && !Objects.equals(input, "N"));
answers[c] = Objects.equals(input, "Y");
}
System.out.println("\nRecommended action(s)");
 
outer:
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
char yn = answers[c] ? 'Y' : 'N';
if (conditions.get(c).getSecond().charAt(r) != yn) {
continue outer;
}
}
if (r == np) {
System.out.println(" None (no problem detected)");
} else {
for (Pair<String, String> action : actions) {
if (action.getSecond().charAt(r) == 'Y') {
System.out.printf(" %s\n", action.getFirst());
}
}
}
break;
}
}
}</syntaxhighlight>
{{out}}
<pre>Please answer the following questions with a y or n:
Printer prints ? n
A red light is flashing ? n
Printer is recognized by computer ? n
 
Recommended action(s)
Check the power cable
Check the printer-computer cable
Ensure printer software is installed</pre>
 
=={{header|JavaScript}}==
===Interactive===
Since this is an interactive web page, results can't be listed. See http://jsfiddle.net/rGP6C/1/ for a live demo.
<langsyntaxhighlight lang="javascript"><html>
<head></head>
<body>
Line 596 ⟶ 1,181:
});
</script>
</html></langsyntaxhighlight>
===DecTab object===
This implements a DecisionTable object called <code>DecTab</code>. The JavaScript dialect is Microsoft's JScript.
<syntaxhighlight lang="javascript">
var DecTab = function () {
this.conditions = [];
this.rules = [];
this.actions = [];
}
 
DecTab.prototype.Conditions = function () {
var args = [].slice.call(arguments);
for (var i = 0; i < args.length; i++) {
this.conditions.push(args[i]);
}
return this;
};
 
DecTab.prototype.RulesActions = function (rules, actions) {
var count = 0;
var actionable;
this.rules.push(rules)
this.actions.push(actions);
return this;
};
 
DecTab.prototype.Decide = function () {
=={{header|Perl 6}}==
var decision = [];
<lang perl6>sub decide (@q, @s) {
var decided = false;
my $bit = 2 ** [+] (1,2,4...*) Z* reverse @q.map: {
for (var i = 0; i < this.conditions.length; i++) {
so prompt(.value ~ "? ") ~~ /:i ^y/;
decision.push((this.conditions[i]()));
}
var decisionstring = "." + decision.join(".") + ".";
 
for (i = 0; i < this.rules.length; i++) {
var rule = [];
for (var j = 0; j < this.rules[i].length; j++) {
rule.push((this.rules[i][j]));
}
sayvar "rulestring = $_"." for+ @srule.grepjoin(*".key") +& $bit)».value || "No clue!.";
if (rulestring === decisionstring) {
decided = true;
for (var k = 0; k < this.actions[i].length; k++) {
this.actions[i][k]();
}
break;
}
}
if (!decided) {
WScript.Echo("No decision table rows matched.");
}
}
</syntaxhighlight>
The task is rendered as follows
<syntaxhighlight lang="javascript">
function Ask(q) {
WScript.StdOut.Write(q);
WScript.StdOut.Write(" [Y/N]?");
var ans = WScript.StdIn.ReadLine();
ans = ans.substr(0, 1).toUpperCase() === "Y" ? "Y" : "N";
return ans;
}
function Tell(w) {
WScript.Echo(w);
}
 
function Check_the_power_cable() {
loop {
Tell("Check the power cable.");
decide
(}
function Check_the_printer_computer_cable() {
"Y Y Y Y N N N N" => "Printer does not print",
Tell("Check the printer-computer cable.");
"Y Y N N Y Y N N" => "A red light is flashing",
}
"Y N Y N Y N Y N" => "Printer is unrecognised",
function Ensure_printer_software_is_installed() {
),
Tell("Ensure printer software is installed.");
(
}
:2<0_0_1_0_0_0_0_0> => "Check the power cable",
function Check_replace_ink() {
:2<1_0_1_0_0_0_0_0> => "Check the printer-computer cable",
Tell("Check/replace ink.");
:2<1_0_1_0_1_0_1_0> => "Ensure printer software is installed",
}
:2<1_1_0_0_1_1_0_0> => "Check/replace ink",
function Check_for_paper_jam() {
:2<0_1_0_1_0_0_0_0> => "Check for paper jam",
Tell("Check for paper jam.");
);
}
say '';
}</lang>
A bit of explanation: we pass in two pair lists for the questions and solutions; we ignore the keys of the questions, since they can be
generated by regarding them as a binary counter from right to left, with the least significant bit on the bottom. The <tt>@q.map</tt> runs the prompts and maps them to booleans
using case-insensitive matching. We reverse that list and zip multiply with powers of two to figure out which bit we're going to grep for. (The zip stops on the shorter list, which is always going to be the list of booleans, since the list of powers of two is infinite.) We sum up those powers of two using a <tt>[+]</tt> reduction metaoperator, which in this case gives us a number from 0 to 7. Then we take 2 to that power.
 
function Printer_Prints() {
The solutions list of pairs is conveniently keyed on binary numbers written in colon radix notation, so we grep the keys containing the correct bit, then map the pair list to its values using a hyperoperator to parallelize it. Unlike in Perl 5, we can use <tt>||</tt> on lists as well as scalars to provide a default result if nothing matches.
return Ask("Printer prints");
{{out}}
}
<pre>Printer does not print? n
function A_red_light_is_flashing() {
A red light is flashing? y
return Ask("A red light is flashing");
Printer is unrecognised? n
}
Check/replace ink
function Printer_is_recognized_by_computer() {
return Ask("Printer is recognized by computer");
}
 
var DT = new DecTab()
Printer does not print? y
.Conditions(
A red light is flashing? n
Printer_Prints,
Printer is unrecognised? y
A_red_light_is_flashing,
Printer_is_recognized_by_computer)
.RulesActions(["N", "Y", "N"], [Check_the_printer_computer_cable, Ensure_printer_software_is_installed, Check_replace_ink])
.RulesActions(["N", "Y", "Y"], [Check_replace_ink, Check_for_paper_jam])
.RulesActions(["N", "N", "N"], [Check_the_power_cable, Check_the_printer_computer_cable, Ensure_printer_software_is_installed])
.RulesActions(["N", "N", "Y"], [Check_for_paper_jam])
.RulesActions(["Y", "Y", "N"], [Ensure_printer_software_is_installed, Check_replace_ink])
.RulesActions(["Y", "Y", "Y"], [Check_replace_ink])
.RulesActions(["Y", "N", "N"], [Ensure_printer_software_is_installed])
.RulesActions(["Y", "N", "Y"], [])
.Decide();
</syntaxhighlight>
And a sample run
<syntaxhighlight lang="text">
C:\>CScript DecisionTable.js
Printer prints [Y/N]?Y
A red light is flashing [Y/N]?Y
Printer is recognized by computer [Y/N]?Y
Check/replace ink.
</syntaxhighlight>
 
=={{header|jq}}==
{{trans|Wren}}
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
 
In the following solution, `input` is used to read the user's
yes/no responses, and so jq should be invoked with the -R and -n command-line options.
 
Because of the limitations of jq's I/O capabilities, the
prompts for this task are written to stderr, which unfortunately makes them
untidy.
<syntaxhighlight lang="jq">def get_response:
input
| if . == "Y" or . == "y" then "Y"
elif . == "N" or . == "n" then "N"
else null
end;
 
def ask($prompt):
def ask:
$prompt|stderr
| get_response
| if . then . else ask end;
ask;
def conditions: [
["Printer prints" , "NNNNYYYY"],
["A red light is flashing" , "YYNNYYNN"],
["Printer is recognized by computer", "NYNYNYNY"]
];
def actions: [
["Check the power cable" , "NNYNNNNN"],
["Check the printer-computer cable" , "YNYNNNNN"],
["Ensure printer software is installed", "YNYNYNYN"],
["Check/replace ink" , "YYNNNYNN"],
["Check for paper jam" , "NYNYNNNN"]
];
 
def interact:
conditions as $conditions
| actions as $actions
| ($conditions|length) as $nc
| ($actions|length) as $na
| ($conditions[0][1]|length) as $nr # number of rules
| 7 as $np # index of 'no problem' rule
| "Please answer the following questions with a y or n:",
( reduce range(0; $nc) as $c ( null;
.[$c] = ask("\($conditions[$c][0])? ") )) as $answers
| ("\nRecommended action(s):",
label $out
| range(0; $nr) as $r
| if all( range(0; $nc); $conditions[.][1][$r:$r+1] == $answers[.])
then if $r == $np
then "None (no problem detected)."
else $actions[] | select(.[1][$r:$r+1] == "Y") | .[0]
end,
break $out
else empty
end ) ;
 
interact
 
</syntaxhighlight>
'''Example (transcript)'''
<pre>
$ jq -rRn -f decision-tables.jq
Please answer the following questions with a y or n:
"Printer prints? "n
"A red light is flashing? "n
"Printer is recognized by computer? "n
 
Recommended action(s):
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
</pre>
 
 
=={{header|Julia}}==
{{trans|Perl}}
<syntaxhighlight lang="julia">const queries = [("Printer does not print", 0b11110000),
("A red light is flashing", 0b11001100),
("Printer is unrecognised", 0b10101010)]
 
const answers = Dict(0b00100000 => "Check the power cable",
0b10100000 => "Check the printer-computer cable",
0b10101010 => "Ensure printer software is installed",
0b11001100 => "Check/replace ink",
0b01010000 => "Check for paper jam",
0b00000001 => "Cannot diagnose any problem.")
 
function ynprompt(prompt)
while true
print(prompt, "?: ")
if (ans = strip(uppercase(readline()))[1]) in ['Y', 'N']
return ans
end
end
end
 
function decide(queries, answers)
cond = 0b11111111
for (prompt, value) in queries
cond &= (ynprompt(prompt) == 'Y' ? value : UInt8(~value))
end
for (bitpat, diagnosis) in answers
if cond & bitpat != 0
println(diagnosis)
end
end
end
 
decide(queries, answers)
</syntaxhighlight>{{out}}
<pre>
Printer does not print?: y
A red light is flashing?: y
Printer is unrecognised?: n
Check/replace ink
Check for paper jam
</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.51
 
val conditions = listOf(
"Printer prints" to "NNNNYYYY",
"A red light is flashing" to "YYNNYYNN",
"Printer is recognized by computer" to "NYNYNYNY"
)
 
val actions = listOf(
"Check the power cable" to "NNYNNNNN",
"Check the printer-computer cable" to "YNYNNNNN",
"Ensure printer software is installed" to "YNYNYNYN",
"Check/replace ink" to "YYNNNYNN",
"Check for paper jam" to "NYNYNNNN"
)
 
fun main(args: Array<String>) {
val nc = conditions.size
val na = actions.size
val nr = conditions[0].second.length // number of rules
val np = 7 // index of 'no problem' rule
println("Please answer the following questions with a y or n:")
val answers = BooleanArray(nc)
for (c in 0 until nc) {
var input: String
do {
print(" ${conditions[c].first} ? ")
input = readLine()!!.toUpperCase()
}
while (input != "Y" && input != "N")
answers[c] = (input == "Y")
}
println("\nRecommended action(s):")
outer@ for (r in 0 until nr) {
for (c in 0 until nc) {
val yn = if (answers[c]) 'Y' else 'N'
if (conditions[c].second[r] != yn) continue@outer
}
if (r == np) {
println(" None (no problem detected)")
}
else {
for (a in 0 until na) {
if (actions[a].second[r] == 'Y') println(" ${actions[a].first}")
}
}
return
}
}</syntaxhighlight>
 
Sample input/output:
<pre>
Please answer the following questions with a y or n:
Printer prints ? n
A red light is flashing ? n
Printer is recognized by computer ? n
 
Recommended action(s):
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
</pre>
 
=={{header|Lua}}==
Printer does not print? n
{{trans|C++}}
<syntaxhighlight lang="lua">function promptYN(q)
local ans = '?'
repeat
io.write(q..'? ')
ans = string.upper(io.read())
until ans == 'Y' or ans == 'N'
return ans == 'Y'
end
 
function getCharAt(s,i)
return string.sub(s,i,i)
end
 
conditions = {
{"Printer prints", "NNNNYYYY"},
{"A red light is flashing", "YYNNYYNN"},
{"Printer is recognized by computer", "NYNYNYNY"},
}
 
actions = {
{"Check the power cable", "NNYNNNNN"},
{"Check the printer-computer cable", "YNYNNNNN"},
{"Ensure printer software is installed", "YNYNYNYN"},
{"Check/replace ink", "YYNNNYNN"},
{"Check for paper jam", "NYNYNNNN"},
}
 
nc = #conditions
nr = string.len(conditions[1][2])
answers = {}
 
print('Please answer the following questions with a y or n:')
for i,v in pairs(conditions) do
answers[i] = promptYN(v[1])
end
 
print('Recommended action(s)')
for r=1,nr do
local skip = false
for c=1,nc do
local yn = answers[c] and 'Y' or 'N'
if getCharAt(conditions[c][2], r) ~= yn then
skip = true
break
end
end
if not skip then
if r == nr then
print(" None (no problem detected)")
else
for i,a in pairs(actions) do
if getCharAt(a[2], r) == 'Y' then
print(" ", a[1])
end
end
end
end
end</syntaxhighlight>
{{out}}
<pre>Please answer the following questions with a y or n:
Printer prints? n
A red light is flashing? n
Printer is unrecognisedrecognized by computer? n
Recommended action(s)
No clue!
Check the power cable
Check the printer-computer cable
Ensure printer software is installed</pre>
 
=={{header|Nim}}==
Printer does not print? ^C</pre>
We have defined a generic decision table object and used it with the Wikipedia printer example.
<syntaxhighlight lang="nim">import strutils, tables
 
####################################################################################################
# Generic defintion of the decision table.
 
type
 
DTable[Cond, Act: Ordinal] = object
questions: array[Cond, string]
answers: array[Act, string]
rules: Table[set[Cond], seq[Act]]
 
proc initDTable[Cond, Act](): DTable[Cond, Act] = discard
 
proc addCondition[Cond, Act](dt: var DTable[Cond, Act]; cond: Cond; question: string) =
if dt.questions[cond].len != 0:
raise newException(ValueError, "condition already set: " & $cond)
dt.questions[cond] = question
 
proc addAction[Cond, Act](dt: var DTable[Cond, Act]; act: Act; answer: string) =
if dt.answers[act].len != 0:
raise newException(ValueError, "action already set: " & $act)
dt.answers[act] = answer
 
proc addRule[Cond, Act](dt: var DTable[Cond, Act]; rule: set[Cond]; acts: openArray[Act]) =
if rule in dt.rules:
raise newException(ValueError, "rule already set.")
dt.rules[rule] = @acts
 
proc askQuestion(question: string): string =
while true:
stdout.write question & ' '
stdout.flushFile()
result = stdin.readLine().strip()
if result in ["y", "n"]: break
 
 
proc apply[Cond, Act](dt: DTable[Cond, Act]) =
# Build condition set.
var conds: set[Cond]
echo "Answer questions with 'y' or 'n'"
for cond, question in dt.questions:
if question.len == 0:
raise newException(ValueError, "missing question for condition: " & $cond)
let answer = askQuestion(question)
if answer == "y":
conds.incl cond
# Apply rule.
echo()
if conds in dt.rules:
echo "Actions recommended:"
for act in dt.rules[conds]:
echo "- ", dt.answers[act]
else:
echo "No action recommended."
 
 
####################################################################################################
# Decision table for Wikipedia printer example.
 
type
 
Condition {.pure.} = enum PrinterPrints, RedLightFlashing, PrinterRecognized
Action {.pure.} = enum CheckPowerCable, CheckPrinterCable, CheckSoftware, CheckInk, CheckPaperJam
 
const
 
Questions = [PrinterPrints: "Does printer print?",
RedLightFlashing: "Does red light is flashing?",
PrinterRecognized: "Is printer recognized by computer?"]
 
Answers = [CheckPowerCable: "check the power cable",
CheckPrinterCable: "check the printer-computer cable",
CheckSoftware: "ensure printer software is installed",
CheckInk: "check/replace ink",
CheckPaperJam: "check for paper jam"]
 
var dt = initDTable[Condition, Action]()
 
for cond, question in Questions:
dt.addCondition(cond, question)
 
for act, answer in Answers:
dt.addAction(act, answer)
 
dt.addRule({}, [CheckPowerCable, CheckPrinterCable, CheckSoftware])
dt.addRule({PrinterPrints}, [CheckSoftware])
dt.addRule({RedLightFlashing}, [CheckPrinterCable, CheckSoftware, CheckInk])
dt.addRule({PrinterRecognized}, [CheckPaperJam])
dt.addRule({PrinterPrints, RedLightFlashing}, [CheckSoftware])
dt.addRule({RedLightFlashing, PrinterRecognized}, [CheckInk, CheckPaperJam])
dt.addRule({PrinterPrints, RedLightFlashing, PrinterRecognized}, [CheckInk])
 
dt.apply()</syntaxhighlight>
 
{{out}}
<pre>Answer questions with 'y' or 'n'
Does printer print? n
Does red light is flashing? y
Is printer recognized by computer? y
 
Actions recommended:
- check/replace ink
- check for paper jam</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl" line>use v5.36;
 
sub decide($q,$a) {
my @q = @{$q};
my %a = %{$a};
my($cnt,$bit) = (1,0);
 
for my $prompt (@q) {
print "$prompt: ";
$bit += $cnt if <> =~ /y/i;
$cnt *= 2;
}
$bit = 2**$bit;
 
while (my ($bitpat,$diagnosis) = each %a) {
print "$diagnosis\n" if $bit & $bitpat;
}
}
 
my @queries = (
'Printer is unrecognised',
'A red light is flashing',
'Printer does not print',
);
 
my %answers = (
0b00100000 => 'Check the power cable',
0b10100000 => 'Check the printer-computer cable',
0b10101010 => 'Ensure printer software is installed',
0b11001100 => 'Check/replace ink',
0b01010000 => 'Check for paper jam',
);
 
decide(\@queries,\%answers);</syntaxhighlight>
{{out}}
<pre>Printer is unrecognised: n
A red light is flashing: n
Printer does not print: y
Check for paper jam</pre>
 
=={{header|Phix}}==
Written such that conditions and actions could easily be read from a plain text file,
and should cope fairly well with different lengths, missing/conflicting options, etc.
=== console version ===
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (wait_key)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">conditions</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
YYYYNNNN:Printer does not print
YYNNYYNN:A red light is flashing
YNYNYNYN:Printer is unrecognized
"""</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">actions</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
--X-----:Check the power cable
X-X-----:Check the printer-computer cable
X-X-X-X-:Ensure printer software is installed
XX--XX--:Check/replace ink
-X-X----:Check for paper jam
"""</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">letters</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"uneven %s pairings"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">name</span><span style="color: #0000FF;">}))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">l</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"mismatched lengths (line %d)"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span><span style="color: #000000;">letters</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">throw</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"invalid letter [%c not in %s]"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span><span style="color: #000000;">letters</span><span style="color: #0000FF;">}))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">qa</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split_any</span><span style="color: #0000FF;">(</span><span style="color: #000000;">conditions</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n:"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">sa</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split_any</span><span style="color: #0000FF;">(</span><span style="color: #000000;">actions</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n:"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">qa</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">ask_questions</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">a</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">qa</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">qa</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">":? "</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">())</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"YN"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nplease enter Y or N\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%c\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">qa</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">valid</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_answers</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sa</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">sa</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'X'</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sa</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d answers\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">try</span>
<span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">qa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"YN"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"condition"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-X"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"action"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">catch</span> <span style="color: #000000;">e</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">e</span>
<span style="color: #7060A8;">abort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">try</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ask_questions</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">sv</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">sv</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"no answers"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">sv</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">show_answers</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">else</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"multiple answer sets\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"for %d:\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show_answers</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Printer does not print:? N
A red light is flashing:? Y
Printer is unrecognized:? Y
Ensure printer software is installed
Check/replace ink
2 answers
</pre>
=== GUI version ===
{{libheader|Phix/pGUI}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">conditions</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
YYYYNNNN:Printer does not print
YYNNYYNN:A red light is flashing
YNYNYNYN:Printer is unrecognized
"""</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">actions</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
--X-----:Check the power cable
X-X-----:Check the printer-computer cable
X-X-X-X-:Ensure printer software is installed
XX--XX--:Check/replace ink
-X-X----:Check for paper jam
"""</span>
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">qyn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">qus</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">conditions</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">),</span><span style="color: #008000;">':'</span><span style="color: #0000FF;">})),</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">a_x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">act</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">actions</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">),</span><span style="color: #008000;">':'</span><span style="color: #0000FF;">}))</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nq</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">qus</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">na</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">act</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">ynl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">qyn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">qyn</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">)=</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ynl</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nq</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"mismatched YN lengths"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a_x</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">)=</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ynl</span><span style="color: #0000FF;">,</span><span style="color: #000000;">na</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"mismatched X- lengths"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">unique</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">qyn</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">))=</span><span style="color: #008000;">"NY"</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">unique</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a_x</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">))=</span><span style="color: #008000;">"-X"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Decision_tables"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">help_text</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
Check all that apply and press the "Get Answers" button.
"""</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tbox</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hbox</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vbox</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">okbtn</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">answers</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">toggles</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">show_help</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupMessage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">title</span><span style="color: #0000FF;">,</span><span style="color: #000000;">help_text</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span> <span style="color: #000080;font-style:italic;">-- (don't open browser help!)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">button_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*okbtn*/</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ynl</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">nq</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">yn</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"YN"</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">IupGetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">toggles</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"VALUE"</span><span style="color: #0000FF;">)]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ynl</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">yn</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">qyn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">sv</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">answer</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sv</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"no answers"</span><span style="color: #0000FF;">:</span>
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sv</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"multiple answer sets\n"</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">sv</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ynl</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">sv</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">answer</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"for %d:\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">actions</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">na</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">a_x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'X'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">actions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">actions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">act</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">actions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">actions</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d answers\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">actions</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">answer</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">actions</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">answers</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">answer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"SIZE"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupRefresh</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*dlg*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (standard practice for me)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_F5</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (let browser reload work)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_F1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">show_help</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_CR</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">button_cb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">okbtn</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">toggles</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupToggle</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">qus</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"RIGHTBUTTON=YES, CANFOCUS=NO"</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">okbtn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupButton</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Get Answers"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"button_cb"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"PADDING=5x5"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">answers</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"EXPAND=BOTH, PADDING=10x10"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">tbox</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupVbox</span><span style="color: #0000FF;">(</span><span style="color: #000000;">toggles</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ALIGNMENT=ARIGHT"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">hbox</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupHbox</span><span style="color: #0000FF;">({</span><span style="color: #000000;">tbox</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupVbox</span><span style="color: #0000FF;">({</span><span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">(),</span><span style="color: #000000;">okbtn</span><span style="color: #0000FF;">})})</span>
<span style="color: #000000;">vbox</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupVbox</span><span style="color: #0000FF;">({</span><span style="color: #000000;">hbox</span><span style="color: #0000FF;">,</span><span style="color: #000000;">answers</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"MARGIN=20x10"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vbox</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="%s", MINSIZE=540x200`</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"KEY_CB"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">IupSetAttributeHandle</span><span style="color: #0000FF;">(</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"PARENTDIALOG"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
 
=={{header|Picat}}==
===Interactive version===
<syntaxhighlight lang="picat">import util.
%
% Interactive version.
% Answer with YnNn
%
go =>
conditions(Conditions),
solutions(Solutions),
 
Answers=query(Conditions),
println(join(decision_table(Solutions,Answers),'\n')),
nl.
 
%
% Query the user about the problem.
% Valid responses: YyNn
%
query(Conditions) = Answers =>
Answers = [0 : _I in 1..Conditions[1,2].length],
println("Please answer the questions with YyNn."),
foreach([Text,Cond] in Conditions)
A = "",
while (not(membchk(A, ["Y","N","y","n"])))
printf("%s? ", Text),
A := read_line(),
if membchk(A,["Y","y"]) then
Answers := map(\/, Answers,Cond)
end
end
end,
nl.
 
%
% Get the result given the answers (list of 01).
%
decision_table(Solutions,Answers) = Result =>
Result = [],
if sum(Answers) = 0 then
Result := ["Nice, no problem."]
else
foreach([Text,Sol] in Solutions)
if map(/\,Sol,Answers) == Sol then
Result := Result ++ [Text]
end
end
end.
 
conditions(Conditions) =>
Conditions = [
["Printer does not print", [1,1,1,1,0,0,0,0]],
["A red light is flashing", [1,1,0,0,1,1,0,0]],
["Printer is unrecognised", [1,0,1,0,1,0,1,0]]
].
 
solutions(Solutions) =>
Solutions = [
["Check the power cable", [0,0,1,0,0,0,0,0]],
["Check the printer-computer cable", [1,0,1,0,0,0,0,0]],
["Ensure printer software is installed",[1,0,1,0,1,0,1,0]],
["Check/replace ink", [1,1,0,0,1,1,0,0]],
["Check for paper jam", [0,1,0,1,0,0,0,0]]
].</syntaxhighlight>
 
{{out}}
<pre>
Please answer the questions with YyNn.
Printer does not print? y
A red light is flashing? n
Printer is unrecognised? y
 
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
Check for paper jam</pre>
 
===All possible answers/combinations===
For debugging purposes it it's nice to be able to print all the possible combinations of answers/solutions.
 
<syntaxhighlight lang="picat">%
% Go through all combinations of answers
%
go2 =>
PS = power_set([1,2,3]).delete([]).sort(),
println(PS),
conditions(Conditions),
solutions(Solutions),
AllCond = [Cond : [_,Cond] in Conditions],
foreach(P in PS)
println(p=P),
println(conditions=join([Conditions[I].first() : I in P],', ')),
A = [0:_I in 1..Conditions[1,2].length],
foreach(C in [AllCond[I] : I in P])
A := map(\/,A,C)
end,
println(a=A),
println(join(decision_table(Solutions,A),'\n')),
nl
end,
nl.</syntaxhighlight>
 
{{out}}
(truncated)
<pre>
p = [1]
conditions = Printer does not print
a = [1,1,1,1,0,0,0,0]
Check the power cable
Check the printer-computer cable
Check for paper jam
 
p = [1,2]
conditions = Printer does not print, A red light is flashing
a = [1,1,1,1,1,1,0,0]
Check the power cable
Check the printer-computer cable
Check/replace ink
Check for paper jam
 
p = [1,2,3]
conditions = Printer does not print, A red light is flashing, Printer is unrecognised
a = [1,1,1,1,1,1,1,0]
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
Check/replace ink
Check for paper jam
 
...
</pre>
 
=={{header|PicoLisp}}==
We allow ourselves a luxurious user interface:
<langsyntaxhighlight PicoLisplang="picolisp">(de yes? (Cond)
(out NIL (prin (car Cond) "? "))
(in NIL
Line 660 ⟶ 2,048:
T )
(T (member Reply '(NIL N NO No n no false 0)))
(prinl "Please answer 'Yes' or 'No'") ) ) ) )</langsyntaxhighlight>
The decision table used in the example:
<langsyntaxhighlight PicoLisplang="picolisp">(de *Conditions
("Printer does not print" T T T T NIL NIL NIL NIL)
("A red light is flashing" T T NIL NIL T T NIL NIL)
Line 672 ⟶ 2,060:
("Ensure printer software is installed" T NIL T NIL T NIL T)
("Check/replace ink" T T NIL NIL T T)
("Check for paper jam" NIL T NIL T) )</langsyntaxhighlight>
The decision can be made directly on the condition and action data, without the need to create intermediate tables:
<langsyntaxhighlight PicoLisplang="picolisp">(de decide ()
(let Reply (mapcar yes? *Conditions)
(extract and
Line 681 ⟶ 2,069:
(unless (pick '((Flg) (<> Flg (next))) Reply)
(rest) ) ) )
(mapcar car *Actions) ) ) )</langsyntaxhighlight>
Output:
<pre>: (decide)
Line 702 ⟶ 2,090:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">
'''
Create a Decision table then use it
Line 741 ⟶ 2,129:
dt_user(dt)
dt_user(dt)
dt_user(dt)</langsyntaxhighlight>
 
'''Sample Run'''
Line 792 ⟶ 2,180:
Try this:
Pray!</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ say "Check power cable." cr ] is cpc ( --> )
[ say "Check printer-computer cable." cr ] is cpcc ( --> )
[ say "Ensure printer software installed." cr ] is epsi ( --> )
[ say "Check/replace ink." cr ] is cri ( --> )
[ say "Check for paper jam." cr ] is cpj ( --> )
[ say "No problem detected." cr ] is npd ( --> )
 
[ [ dup $ " (y/n) " join input
dup $ "" = iff drop again ]
nip 0 peek upper char Y = ] is condition ( $ --> b )
 
[ $ "Does the printer print?"
condition
$ "Is a red light flashing?"
condition
$ "Does the computer recognise the printer?"
condition
1 << | 1 << |
[ table
( n n n ) [ cpc cpcc epsi ]
( y n n ) epsi
( n y n ) [ cpcc epsi cri ]
( y y n ) epsi
( n n y ) cpj
( y n y ) npd
( n y y ) [ cri cpj ]
( y y y ) cri ]
cr do ] is diagnose ( --> )</syntaxhighlight>
 
{{out}}
 
As a dialogue in the Quackery shell.
 
<pre>/O> diagnose
...
Does the printer print? (y/n) n
Is a red light flashing? (y/n) n
Does the computer recognise the printer? (y/n) y
 
Check for paper jam.
 
</pre>
 
=={{header|Racket}}==
 
This implementation shows off the 2d language. The "Actions" could be a square array of empty and X boxes.
I thought it might be fun to merge them.
 
<syntaxhighlight lang="racket">#lang unstable/2d racket
 
(define (ask-y/n q)
(printf "~a [y/n]?" q)
(define (get-y/n)
(match (read-line)
[(? eof-object?) eof]
[(regexp #rx"^[yY]") #t]
[(regexp #rx"^[nN]") #f]
[_ (printf "reply yes or no, please:") (get-y/n)]))
(get-y/n))
 
(define (cells->hash grid)
(for*/hash ((block (in-list grid)) (address (in-list (car block))))
(values address (match (cdr block)
['(N) #f]
['(Y) #t]
['(X) 'X]
[else else]))))
 
(define (run-decision-table tbl)
(match-define (list '2ddecision_table col-widths row-heights all-cells ...) tbl)
;; after this, the rules without an X are removed
(define full-cells (filter (match-lambda [(list _ _ _ ...) #t] [_ #f]) all-cells))
;; cell addresses are (list column row)
(match-define
(list-no-order
`((,_ ... (1 1) ,_ ...) ,caption ...)
`(((,rules-columns ,_) ...) Rules)
`(((,(app add1 text-columns) ,condition-rows) ...) Conditions)
`(((,_ ,action-rows) ...) Actions)
remaining-cells ...)
full-cells)
(define remaining-cells# (cells->hash remaining-cells))
(define (cell# c r (dflt #f))
(hash-ref remaining-cells# (list c r) dflt))
(define text-column (first text-columns))
(let question-loop ((remain-conds condition-rows) (remain-acts action-rows))
(match remain-conds
[(list) (displayln "I give up... read the manual or something.")]
[(list conds-h conds-t ...)
(match (ask-y/n (string-join (map ~a (cell# text-column conds-h)) " "))
[(? eof-object?) "bye!"]
[y/n-response
(define remain-acts-
(for/list
((action remain-acts)
#:when (for/first
((rule-c (in-list rules-columns))
#:when (eq? (cell# rule-c conds-h) y/n-response) ; matches rule flag
#:when (equal? (cell# rule-c action #f) 'X)) ; has an X
#t))
action))
(match remain-acts-
[(list) (printf "No more actions... no more suggestions from the rules!~%")]
[(list only-action) (printf "Suggested action: ~s~%" (cell# text-column only-action))]
[_ (question-loop conds-t remain-acts-)])])])))
 
(define printer-troubleshooting-2dtable
'#2ddecision_table
╔═╦════════════╦════════════════════════════════════════════╦═╦═╦═╦═╦═╦═╦═╦═╗
║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║
╠═╬════════════╩════════════════════════════════════════════╬═╩═╩═╩═╩═╩═╩═╩═╣
║ ║ Printer troubleshooter ║ Rules ║
╠═╬════════════╦════════════════════════════════════════════╬═══════╦═══════╣
║ ║ Conditions ║ Printer does not print ║Y ║N ║
╠═╣ ╠════════════════════════════════════════════╣ ╔═══╬═══╗ ║
║ ║ ║ A red light is flashing ║ ║N ║Y ║ ║
╠═╣ ╠════════════════════════════════════════════╣ ╔═╬═╗ ║ ╔═╬═╗ ║
║ ║ ║ Printer is unrecognized ║ ║N║Y║ ║ ║N║Y║ ║
╠═╬════════════╬════════════════════════════════════════════╬═╩═╬═╬═╩═╩═╩═╩═╣
║ ║ Actions ║ Check the power cable ║ ║X║ ║
╠═╣ ╠════════════════════════════════════════════╬═╗ ║ ║ ║
║ ║ ║ Check the printer-computer cable ║X║ ║ ║ ║
╠═╣ ╠════════════════════════════════════════════╣ ║ ║ ║ ╔═╗ ╔═╗ ║
║ ║ ║ Ensure printer software is installed ║ ║ ║ ║ ║X║ ║X║ ║
╠═╣ ╠════════════════════════════════════════════╣ ╚═╬═╝ ║ ╚═╬═╝ ║
║ ║ ║ Check/replace ink ║ ║ ║ ║ ║
╠═╣ ╠════════════════════════════════════════════╬═╗ ║ ╔═╬═══╝ ║
║ ║ ║ Check for paper jam ║ ║ ║ ║X║ ║
╚═╩════════════╩════════════════════════════════════════════╩═╩═╩═╩═╩═══════╝)
 
(run-decision-table printer-troubleshooting-2dtable)</syntaxhighlight>
 
{{out}}
 
A trial run...
<pre>Printer does not print [y/n]?n
A red light is flashing [y/n]?y
Printer is unrecognized [y/n]?n
Suggested action: (Check/replace ink)</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub decide (@q, @s) {
my $bit = 2 ** [+] (1,2,4...*) Z* reverse @q.map: {
so prompt(.value ~ "? ") ~~ /:i ^y/;
}
say " $_" for @s.grep(*.key +& $bit)».value || "No clue!";
}
 
loop {
decide
(
"Y Y Y Y N N N N" => "Printer does not print",
"Y Y N N Y Y N N" => "A red light is flashing",
"Y N Y N Y N Y N" => "Printer is unrecognised",
),
(
:2<0_0_1_0_0_0_0_0> => "Check the power cable",
:2<1_0_1_0_0_0_0_0> => "Check the printer-computer cable",
:2<1_0_1_0_1_0_1_0> => "Ensure printer software is installed",
:2<1_1_0_0_1_1_0_0> => "Check/replace ink",
:2<0_1_0_1_0_0_0_0> => "Check for paper jam",
);
say '';
}</syntaxhighlight>
A bit of explanation: we pass in two pair lists for the questions and solutions; we ignore the keys of the questions, since they can be
generated by regarding them as a binary counter from right to left, with the least significant bit on the bottom. The <tt>@q.map</tt> runs the prompts and maps them to booleans
using case-insensitive matching. We reverse that list and zip multiply with powers of two to figure out which bit we're going to grep for. (The zip stops on the shorter list, which is always going to be the list of booleans, since the list of powers of two is infinite.) We sum up those powers of two using a <tt>[+]</tt> reduction metaoperator, which in this case gives us a number from 0 to 7. Then we take 2 to that power.
 
The solutions list of pairs is conveniently keyed on binary numbers written in colon radix notation, so we grep the keys containing the correct bit, then map the pair list to its values using a hyperoperator to parallelize it. Unlike in Perl 5, we can use <tt>||</tt> on lists as well as scalars to provide a default result if nothing matches.
{{out}}
<pre>Printer does not print? n
A red light is flashing? y
Printer is unrecognised? n
Check/replace ink
 
Printer does not print? y
A red light is flashing? n
Printer is unrecognised? y
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
 
Printer does not print? n
A red light is flashing? n
Printer is unrecognised? n
No clue!
 
Printer does not print? ^C</pre>
 
=={{header|REXX}}==
This REXX example shows how one version of a decision table could be implemented,
<br>There was additional support added to the code for:
* a &nbsp; ''no solution found'' &nbsp; message
* a &nbsp; ''don't care'' &nbsp; requirement &nbsp; (regarding the decision table)
* a method of specifying requirements and not needing recoding for future queries
* used a minimalistic way in expressing the decision table
* extra prompting when there was a user reponse error
* handles superfluous blanks and some punctuation.
* displaying of a countdown so user knows length of interrogation
* visual fidelity aids for postmortem analysis (as in logs)
* a method of allowing the user to quit the interrogation
<lang rexx>/*REXX pgm demonstrates a decision table and possible corrective actions*/
Q. =
Q.1 = 'Does the printer not print?'
Q.2 = 'Is there a red light flashing on the printer?'
Q.3 = 'Is the printer unrecognized by the software?'
Q.0 = 3
act.= /* Y = yes N = no not letter = don't care. */
 
There was additional support added to the code for:
/* ┌───────◄ answer to 1st question (in upper\lower\mixed case). */
::* &nbsp; a &nbsp; ''no solution found'' &nbsp; message
/* │┌──────◄ " " 2nd " " " " " " */
::* &nbsp; a &nbsp; ''don't care'' &nbsp; requirement &nbsp; (regarding the decision table)
/* ││┌─────◄ " " 3rd " " " " " " */
::* &nbsp; a method of specifying requirements and not needing recoding for future queries
/* │││ */
::* &nbsp; used a minimalistic way in expressing the decision table
/* ↓↓↓ */
::* &nbsp; extra prompting when there was a user response error
act.1 = 'yny' ; pos.1 = 'Check the power cable.'
::* &nbsp; handles superfluous blanks and some punctuation.
act.2 = 'y.y' ; pos.2 = 'check the printer-computer cable.'
::* &nbsp; displaying of a countdown so user knows length of interrogation
act.3 = '..y' ; pos.3 = 'Ensure printer software is installed.'
::* &nbsp; visual fidelity aids for postmortem analysis (as in logs)
act.4 = '.y.' ; pos.4 = 'Check/replace ink.'
::* &nbsp; a method of allowing the user to quit (opt-out of) the interrogation
act.5 = 'y.n' ; pos.5 = 'Check for paper jam.'
<syntaxhighlight lang="rexx">/*REXX program demonstrates a (query) decision table and possible corrective actions.*/
Q.=; Q.1 = 'Does the printer not print?'
Q.2 = 'Is there a red light flashing on the printer?'
Q.3 = 'Is the printer unrecognized by the software?'
Q.0 = 3 /*the number of questions to be asked. */
action.= /* Y=yes N=no if character isn't a letter = don't care.*/
 
/* ┌─────◄── answer to 1st question (it can be in upper\lower\mixed case). */
/* │┌────◄── " " 2nd " " " " " " " " " */
/* ││┌───◄── " " 3rd " " " " " " " " " */
/* │││ */
/* ↓↓↓ */
action.1 = 'yny' ; pos.1 = "═════════ Check the power cable."
action.2 = 'y.y' ; pos.2 = "═════════ check the printer-computer cable."
action.3 = '..y' ; pos.3 = "═════════ Ensure printer software is installed."
action.4 = '.y.' ; pos.4 = "═════════ Check/replace ink."
action.5 = 'y.n' ; pos.5 = "═════════ Check for paper jam."
 
do i=1 for while Q.0i\==''; ans.i= asker(i); end /*display querythe question, getobtain resp.response*/
end /*i*/
say
possible=0say /*we'lldisplay a beblank countingline possiblebefore solsquestions*/
possible= 0 /*we'll be counting possible solutions.*/
 
do k=1 while actaction.k\=='' /*filter the answers via decision tabtable*/
 
do j=1; d= substr(actaction.k, j, 1); upper d
jm= j//Q.0; if jm==0 then jm= Q.0
if d==' ' then leave
if \datatype(d, 'U') then iterate
if d\==ans.jm then iterate k
if j==Q then leave
end /*j*/
say pos.k /*this could be a possible solsolution. */
possible= possible + 1 /*count numnumber of possible solutions. */
end /*k*/
 
if possible==0 then say 'No═════════ solutions givenThere are no solutions for the information supplied.'
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*───────────────────────────────────ASKER subroutine───────────────────*/
asker: arg ?; oops= 0; Qprefix= copies('─', 9) '(question' ? "of" Q.0') '
howTo = '(You can answer with a Yes or No [or Quit])'
 
do forever
if oops then do; say; say right(howTo, 79); say; oops= 0; end
say Qprefix Q.?; parse pull x /*ask a question (after a prompt)*/end
x=strip(space(x),,'say Qprefix Q.')?; parse upper var parse pull x u 1 u1 2 /*u1=1stask charquestion (after prompt)*/
ifx= wordsstrip(space(x)==0, , .); then iterate parse upper var x /*nothingu entered?1 u1 2 /*u1=1st Trycharacter again.of answer.*/
if abbrevwords('QUIT',u,1x)==0 then exititerate /*the user is tired of answering /*Nothing entered? Try again.*/
if (abbrev('YESQUIT', u,1) |then exit abbrev('NO',u)) & words(x)==1 then return u1 /*user is tired of answering.*/
if (abbrev('YES', u) | abbrev("NO", u)) & words(x)==1 then return u1
say 'invalid response: ' x; oops=1
say 'invalid response: ' x; oops= 1
end /*forever*/</lang>
end /*forever*/</syntaxhighlight>
'''output''' (a screen scraping using a DOS prompt window for the possible responses)
{{out|output|text=&nbsp; (a screen scraping using a DOS prompt window for some of the possible responses):}}
DECISION.REX is the REXX program that produced this output.
 
<pre style="height:50ex;overflow:scroll">
('''decision.rex''' &nbsp; is the name of the REXX program that produced this output.)
<pre style="height:72ex">
D:\►rexx decision
 
───────── (question 1 of 3) Does the printer not print?
no ◄■■■■■■■■ user input.
no
───────── (question 2 of 3) Is there a red light flashing on the printer?
No ◄■■■■■■■■ user input.
No
───────── (question 3 of 3) Is the printer unrecognized by the software?
n ◄■■■■■■■■ user input.
n
 
No═════════ solutions givenThere are no solutions for the information supplied.
 
D:\►rexx decision
───────── (question 1 of 3) Does the printer not print?
n ◄■■■■■■■■ user input.
n
───────── (question 2 of 3) Is there a red light flashing on the printer?
n ◄■■■■■■■■ user input.
n
───────── (question 3 of 3) Is the printer unrecognized by the software?
yes ◄■■■■■■■■ user input.
yes
 
═════════ Ensure printer software is installed.
 
D:\►rexx decision
───────── (question 1 of 3) Does the printer not print?
n ◄■■■■■■■■ user input.
n
───────── (question 2 of 3) Is there a red light flashing on the printer?
Ye ◄■■■■■■■■ user input.
Ye
───────── (question 3 of 3) Is the printer unrecognized by the software?
n ◄■■■■■■■■ user input.
n
 
═════════ Check/replace ink.
 
D:\►rexx decision
───────── (question 1 of 3) Does the printer not print?
n ◄■■■■■■■■ user input.
n
───────── (question 2 of 3) Is there a red light flashing on the printer?
yes. ◄■■■■■■■■ user input.
yes.
───────── (question 3 of 3) Is the printer unrecognized by the software?
yes ◄■■■■■■■■ user input.
yes
 
═════════ Ensure printer software is installed.
═════════ Check/replace ink.
 
D:\►rexx decision
───────── (question 1 of 3) Does the printer not print?
y ◄■■■■■■■■ user input.
y
───────── (question 2 of 3) Is there a red light flashing on the printer?
no ◄■■■■■■■■ user input.
no
───────── (question 3 of 3) Is the printer unrecognized by the software?
no ◄■■■■■■■■ user input.
no
 
═════════ Check for paper jam.
 
D:\►rexx decision
───────── (question 1 of 3) Does the printer not print?
y ◄■■■■■■■■ user input.
y
───────── (question 2 of 3) Is there a red light flashing on the printer?
n ◄■■■■■■■■ user input.
n
───────── (question 3 of 3) Is the printer unrecognized by the software?
y ◄■■■■■■■■ user input.
y
 
═════════ Check the power cable.
═════════ check the printer-computer cable.
═════════ Ensure printer software is installed.
 
D:\►rexx decision
───────── (question 1 of 3) Does the printer not print?
y ◄■■■■■■■■ user input.
y
───────── (question 2 of 3) Is there a red light flashing on the printer?
y ◄■■■■■■■■ user input.
y
───────── (question 3 of 3) Is the printer unrecognized by the software?
n ◄■■■■■■■■ user input.
n
 
═════════ Check/replace ink.
═════════ Check for paper jam.
 
D:\►rexx decision
───────── (question 1 of 3) Does the printer not print?
y ◄■■■■■■■■ user input.
y
───────── (question 2 of 3) Is there a red light flashing on the printer?
y ◄■■■■■■■■ user input.
y
───────── (question 3 of 3) Is the printer unrecognized by the software?
y ◄■■■■■■■■ user input.
y
 
═════════ check the printer-computer cable.
═════════ Ensure printer software is installed.
═════════ Check/replace ink.
 
D:\►
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Decision tables
 
see "The printer does not print (Y or N) "
give notprinting
see "A red light is upper(flashing) (Y or N) "
give flashing
see "The printer is unrecognized (Y or N) "
give notrecognized
 
if upper(notprinting) = "Y" and upper(flashing) = "Y" and upper(notrecognized) = "Y"
see "Check the printer-computer cable" + nl
see "Ensure printer software is installed" + nl
see "Check/replace ink"
elseif upper(notprinting) = "Y" and upper(flashing) = "Y" upper(notrecognized) = "N"
see "Check/replace ink" + nl
see "Check for paper jam" + nl
elseif upper(notprinting) = "Y" and upper(flashing) = "N" and upper(notrecognized) = "Y"
see "Check the power cable"
see "Check the printer-computer cable" + nl
see "Ensure printer software is installed" + nl
elseif upper(notprinting) = "Y" and upper(flashing) = "N" and upper(notrecognized) = "N"
see "Check for paper jam" + nl
elseif upper(notprinting) = "N" and upper(flashing) = "Y" and upper(notrecognized) = "Y"
see "Ensure printer software is installed" + nl
see "Check/replace ink" + nl
elseif upper(notprinting) = "N" and upper(flashing) = "Y" and upper(notrecognized) = "N"
see "Check/replace ink" + nl
elseif upper(notprinting) = "N" and upper(flashing) = "N" and upper(notrecognized) = "Y"
see "Ensure printer software is installed" + nl
elseif upper(notprinting) = "N" and upper(flashing) = "N" and upper(notrecognized) = "N"
see "no action found" + nl
else
see "invalid input: " + upper(notprinting) + " " + upper(flashing) + " " + upper(notrecognized) + nl
ok
</syntaxhighlight>
Output:
<pre>
The printer does not print (Y or N) y
A red light is upper(flashing) (Y or N) y
The printer is unrecognized (Y or N) y
Check the printer-computer cable
Ensure printer software is installed
Check/replace ink
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class DecisionTable
def initialize(conditions, actions)
@conditions = conditions
Line 1,002 ⟶ 2,636:
]
)
loop {dt.run}</langsyntaxhighlight>
 
Example
Line 1,066 ⟶ 2,700:
Actions:
PC LOAD LETTER</pre>
 
=={{header|Scala}}==
{{trans|Java}}
<syntaxhighlight lang="scala">import java.io.{BufferedReader, InputStreamReader}
 
import scala.util.control.Breaks
 
object DecisionTables {
val conditions = List(
("Printer prints", "NNNNYYYY"),
("A red light is flashing", "YYNNYYNN"),
("Printer is recognized by computer", "NYNYNYNY")
)
 
val actions = List(
("Check the power cable", "NNYNNNNN"),
("Check the printer-computer cable", "YNYNNNNN"),
("Ensure printer software is installed", "YNYNYNYN"),
("Check/replace ink", "YYNNNYNN"),
("Check for paper jam", "NYNYNNNN")
)
 
def main(args: Array[String]): Unit = {
// var x = (1, 2)
// println(x)
// println(conditions)
// println(actions)
 
val nc = conditions.size
val na = actions.size
val nr = conditions.head._2.length
val np = 7
 
val br = new BufferedReader(new InputStreamReader(System.in))
 
println("Please answer the following questions with a y or n:")
val answers = Array.ofDim[Boolean](nc)
for (c <- 0 until nc) {
var input = ""
do {
printf(" %s ? ", conditions(c)._1)
input = br.readLine().toUpperCase
} while (input != "Y" && input != "N")
answers(c) = input == "Y"
}
println("\nRecommended actions(s)")
 
val Outer = new Breaks
val Inner = new Breaks
Outer.breakable {
for (r <- 0 until nr) {
var outer = true
 
Inner.breakable {
for (c <- 0 until nc) {
val yn = if (answers(c)) 'Y' else 'N'
if (conditions(c)._2(r) != yn) {
outer = false
Inner.break
}
}
}
 
if (outer) {
if (r == np) {
println(" None (no problem detected)")
} else {
for (action <- actions) {
if (action._2(r) == 'Y') {
printf(" %s\n", action._1)
}
}
}
Outer.break
}
}
}
}
}</syntaxhighlight>
{{out}}
<pre>Please answer the following questions with a y or n:
Printer prints ? y
A red light is flashing ? y
Printer is recognized by computer ? y
 
Recommended actions(s)
Check/replace ink</pre>
 
=={{header|Sidef}}==
{{trans|Raku}}
<syntaxhighlight lang="ruby">func decide (q, s) {
 
var bits = q.map { |p|
read("#{p.value}? ", String) ~~ /^y/i ? 1 : 0
}
 
var n = with (0) { |t|
bits.each { |b|
t <<= 1
t |= b
}
1 << t
}
 
s.grep { .key & n }.map{ .value }.each { |ans|
say " #{ans}"
}
}
 
loop {
decide(
[
Pair("Y Y Y Y N N N N", "Printer does not print"),
Pair("Y Y N N Y Y N N", "A red light is flashing"),
Pair("Y N Y N Y N Y N", "Printer is unrecognised"),
],
[
Pair(0b0_0_1_0_0_0_0_0, "Check the power cable"),
Pair(0b1_0_1_0_0_0_0_0, "Check the printer-computer cable"),
Pair(0b1_0_1_0_1_0_1_0, "Ensure printer software is installed"),
Pair(0b1_1_0_0_1_1_0_0, "Check/replace ink"),
Pair(0b0_1_0_1_0_0_0_0, "Check for paper jam"),
]
)
say ''
}</syntaxhighlight>
{{out}}
<pre>
Printer does not print? y
A red light is flashing? n
Printer is unrecognised? n
Check for paper jam
 
Printer does not print? n
A red light is flashing? n
Printer is unrecognised? y
Ensure printer software is installed
 
Printer does not print? y
A red light is flashing? y
Printer is unrecognised? n
Check/replace ink
Check for paper jam
 
Printer does not print? n
A red light is flashing? y
Printer is unrecognised? y
Ensure printer software is installed
Check/replace ink
 
Printer does not print? ^C
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require TclOO
 
#http://rosettacode.org/wiki/Keyboard_Input/Obtain_a_Y_or_N_response#Tcl
Line 1,107 ⟶ 2,893:
}
}
}</langsyntaxhighlight>
Demonstration:
<langsyntaxhighlight lang="tcl">DecisionTable create printerDiagnosisTable {
"Printer does not print"
"A red light is flashing"
Line 1,120 ⟶ 2,906:
"Check for paper jam" {0 1 0 1}
}
printerDiagnosisTable consult</langsyntaxhighlight>
Output:
<pre>
Line 1,128 ⟶ 2,914:
Ensure printer software is installed
Check/replace ink
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "io" for Stdin, Stdout
import "./str" for Str
 
var conditions = [
["Printer prints" , "NNNNYYYY"],
["A red light is flashing" , "YYNNYYNN"],
["Printer is recognized by computer", "NYNYNYNY"]
]
 
var actions = [
["Check the power cable" , "NNYNNNNN"],
["Check the printer-computer cable" , "YNYNNNNN"],
["Ensure printer software is installed", "YNYNYNYN"],
["Check/replace ink" , "YYNNNYNN"],
["Check for paper jam" , "NYNYNNNN"]
]
 
var nc = conditions.count
var na = actions.count
var nr = conditions[0][1].count // number of rules
var np = 7 // index of 'no problem' rule
System.print("Please answer the following questions with a y or n:")
var answers = List.filled(nc, false)
for (c in 0...nc) {
var input
while (true) {
System.write(" %(conditions[c][0]) ? ")
Stdout.flush()
input = Str.upper(Stdin.readLine())
if (input == "Y" || input == "N") break
}
answers[c] = (input == "Y")
}
System.print("\nRecommended action(s):")
for (r in 0...nr) {
var outer = false
for (c in 0...nc) {
var yn = answers[c] ? "Y" : "N"
if (conditions[c][1][r] != yn) {
outer = true
break
}
}
if (!outer) {
if (r == np) {
System.print(" None (no problem detected)")
} else {
for (a in 0...na) {
if (actions[a][1][r] == "Y") System.print(" %(actions[a][0])")
}
}
break
}
}</syntaxhighlight>
 
{{out}}
Sample input/output:
<pre>
Please answer the following questions with a y or n:
Printer prints ? n
A red light is flashing ? n
Printer is recognized by computer ? n
 
Recommended action(s):
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
</pre>
 
=={{header|XPL0}}==
{{trans|Wren}}
<syntaxhighlight lang "XPL0">include xpllib; \for ToUpper, Print
 
int Conditions, Actions, NC, NA, NR, NP, Answers(3), Input, Outer, YN, R, C, A;
char S;
[Conditions:= [
["Printer prints" , "NNNNYYYY"],
["A red light is flashing" , "YYNNYYNN"],
["Printer is recognized by computer", "NYNYNYNY"]
];
Actions:= [
["Check the power cable" , "NNYNNNNN"],
["Check the printer-computer cable" , "YNYNNNNN"],
["Ensure printer software is installed", "YNYNYNYN"],
["Check/replace ink" , "YYNNNYNN"],
["Check for paper jam" , "NYNYNNNN"]
];
NC:= 3;
NA:= 5;
NR:= 8; \number of rules
NP:= 7; \index of 'no problem' rule
Print("Please answer the following questions with a y or n:\n");
for C:= 0 to NC-1 do
[loop [Print(" %s ? ", Conditions(C,0));
OpenI(0);
Input:= ToUpper(ChIn(0));
if Input = ^Y or Input = ^N then quit;
];
Answers(C):= Input = ^Y;
];
Print("\nRecommended action(s):\n");
for R:= 0 to NR-1 do
[Outer:= false;
for C:= 0 to NC-1 do
[YN:= if Answers(C) then ^Y else ^N;
S:= Conditions(C,1); \to access character bytes not integers
if S(R) # YN then
[Outer:= true;
C:= NC; \break
];
];
if not Outer then
[if R = NP then
Print(" None (no problem detected)\n")
else [for A:= 0 to NA-1 do
[S:= Actions(A,1);
if S(R) = ^Y then
Print(" %s\n", Actions(A,0));
];
];
R:= NR; \break
];
];
]</syntaxhighlight>
{{out}}
<pre>
Please answer the following questions with a y or n:
Printer prints ? n
A red light is flashing ? n
Printer is recognized by computer ? n
 
Recommended action(s):
Check the power cable
Check the printer-computer cable
Ensure printer software is installed
</pre>
9,476

edits