Decision tables: Difference between revisions
m (→{{header|D}}: redo the table input format to include conditions' states) |
|||
Line 5: | Line 5: | ||
=={{header|D}}== |
=={{header|D}}== |
||
<lang d>import std.stdio, std.algorithm, std.exception, std.string ; |
<lang d>import std.stdio, std.algorithm, std.exception, std.string, std.array, std.conv ; |
||
struct Decision { |
struct Decision { |
||
⚫ | |||
immutable string[] conds ; |
immutable string[] conds ; |
||
immutable string[] actions ; |
immutable string[] actions ; |
||
immutable |
immutable IBA[IBA] rules ; |
||
this(string[] c, string[] a, |
this(string[] c, string[] a, byte[][][] q) { |
||
assert(c.length < 32, "max 31 test conditions") ; |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
conds = c.idup ; |
conds = c.idup ; |
||
actions = a.idup ; |
actions = a.idup ; |
||
IBA[IBA] r ; |
|||
⚫ | |||
⚫ | |||
⚫ | |||
p[1].length = actions.length ; |
|||
⚫ | |||
} |
|||
⚫ | |||
} |
} |
||
string[] test(bool[] tested, string NoMatchMsg = "it is fine :)") { |
string[] test(bool[] tested, string NoMatchMsg = "it is fine :)") { |
||
byte[] testedBytes = array(map!"to!byte(a?1:0)"(tested)) ; |
|||
return test(testedBytes, NoMatchMsg) ; |
|||
} |
|||
string[] test(byte[] tested, string NoMatchMsg = "it is fine :)") { |
|||
string[] rightActions ; |
string[] rightActions ; |
||
tested.length = conds.length ; |
|||
auto rule = tested.idup in rules ; |
|||
if(rule !is null) |
|||
⚫ | |||
foreach(i, e ; *rule) |
|||
if(e) |
|||
⚫ | |||
if(rightActions.length > 0) |
if(rightActions.length > 0) |
||
return rightActions ; |
return rightActions ; |
||
Line 47: | Line 55: | ||
void main() { |
void main() { |
||
Decision d = Decision( |
Decision d = Decision( |
||
["Printer is unrecognised", |
["Printer is unrecognised", |
||
"A red light is flashing", |
"A red light is flashing", |
||
Line 56: | Line 64: | ||
"Check/replace ink", |
"Check/replace ink", |
||
"Check for paper jam"], |
"Check for paper jam"], |
||
[[ |
[[[1,0,0],[0,0,1]], |
||
[ |
[[0,1,0],[0,0,0,1]], |
||
[ |
[[1,1,0],[0,0,1,1]], |
||
[ |
[[0,0,1],[0,0,0,0,1]], |
||
[ |
[[1,0,1],[1,1,1]], |
||
[ |
[[0,1,1],[0,0,0,1,1]], |
||
[ |
[[1,1,1],[0,1,1,1,0]] |
||
] |
|||
) ; |
) ; |
||
d.consult() ; |
d.consult() ; |
Revision as of 13:42, 26 January 2011
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.
D
<lang d>import std.stdio, std.algorithm, std.exception, std.string, std.array, std.conv ;
struct Decision {
alias immutable(byte)[] IBA ; immutable string[] conds ; immutable string[] actions ; immutable IBA[IBA] rules ;
this(string[] c, string[] a, byte[][][] q) { conds = c.idup ; actions = a.idup ; IBA[IBA] r ; foreach(p ; q) { p[0].length = conds.length ; p[1].length = actions.length ; r[p[0].idup] = p[1].idup ; } rules = assumeUnique(r) ; }
string[] test(bool[] tested, string NoMatchMsg = "it is fine :)") { byte[] testedBytes = array(map!"to!byte(a?1:0)"(tested)) ; return test(testedBytes, NoMatchMsg) ; } string[] test(byte[] tested, string NoMatchMsg = "it is fine :)") { string[] rightActions ; tested.length = conds.length ; auto rule = tested.idup in rules ; if(rule !is null) foreach(i, e ; *rule) if(e) rightActions ~= actions[i] ; if(rightActions.length > 0) return rightActions ; return [NoMatchMsg] ; }
void consult() { bool[] query ; string answer ; foreach(c;conds) { write(c,"? [y=yes/others=no] ") ; readf("%s\n", &answer) ; query ~= (answer.length > 0 && answer.tolower[0..1] == "y") ; } writeln(test(query).join("\n")) ; }
}
void main() {
Decision d = Decision( ["Printer is unrecognised", "A red light is flashing", "Printer does not print"], ["Check the power cable", "Check the printer-computer cable", "Ensure printer software is installed", "Check/replace ink", "Check for paper jam"], [[[1,0,0],[0,0,1]], [[0,1,0],[0,0,0,1]], [[1,1,0],[0,0,1,1]], [[0,0,1],[0,0,0,0,1]], [[1,0,1],[1,1,1]], [[0,1,1],[0,0,0,1,1]], [[1,1,1],[0,1,1,1,0]] ] ) ; d.consult() ;
}</lang> Sample output:
Printer is unrecognised? [y=yes/others=no] y A red light is flashing? [y=yes/others=no] y Printer does not print? [y=yes/others=no] n Ensure printer software is installed Check/replace ink
Python
<lang python> Create a Decision table then use it
def dt_creator():
print("\n\nCREATING THE DECISION TABLE\n") conditions = input("Input conditions, in order, separated by commas: ") conditions = [c.strip() for c in conditions.split(',')] print( ("\nThat was %s conditions:\n " % len(conditions)) + '\n '.join("%i: %s" % x for x in enumerate(conditions, 1)) ) print("\nInput an action, a semicolon, then a list of tuples of rules that trigger it. End with a blank line") action2rules, action = [], ' ' while action: action = input("%i: " % (len(action2rules) + 1)).strip() if action: name, _, rules = [x.strip() for x in action.partition(';')] rules = eval(rules) assert all(len(rule) == len(conditions) for rule in rules), \ "The number of conditions in a rule to trigger this action is wrong" action2rules.append((name, rules)) actions = [x[0] for x in action2rules] # Map condition to actions rule2actions = dict((y,[]) for y in set(sum((x[1] for x in action2rules), []))) for action, rules in action2rules: for r in rules: rule2actions[r].append( action ) return conditions, rule2actions
def dt_user(dt, default=['Pray!']):
conditions, rule2actions = dt print("\n\nUSING THE DECISION TABLE\n") rule = tuple(int('y' == input("%s? (Answer y if statement is true or n): " % c)) for c in conditions) print("Try this:\n " + '\n '.join(rule2actions.get(rule, default)))
if __name__ == '__main__':
dt = dt_creator() dt_user(dt) dt_user(dt) dt_user(dt)</lang>
Sample Run
CREATING THE DECISION TABLE Input conditions, in order, separated by commas: Printer does not print, A red light is flashing, Printer is unrecognised That was 3 conditions: 1: Printer does not print 2: A red light is flashing 3: Printer is unrecognised Input an action, a semicolon, then a list of tuples of rules that trigger it. End with a blank line 1: Check the power cable; [(1,0,1)] 2: Check the printer-computer cable; [(1,1,1), (1,0,1)] 3: Ensure printer software is installed; [(1,1,1), (1,0,1), (0,1,1), (0,0,1)] 4: Check/replace ink; [(1,1,1), (1,1,0), (0,1,1), (0,1,0)] 5: Check for paper jam; [(1,1,0), (1,0,0)] 6: USING THE DECISION TABLE Printer does not print? (Answer y if statement is true or n): n A red light is flashing? (Answer y if statement is true or n): y Printer is unrecognised? (Answer y if statement is true or n): y Try this: Ensure printer software is installed Check/replace ink USING THE DECISION TABLE Printer does not print? (Answer y if statement is true or n): y A red light is flashing? (Answer y if statement is true or n): n Printer is unrecognised? (Answer y if statement is true or n): y Try this: Check the power cable Check the printer-computer cable Ensure printer software is installed USING THE DECISION TABLE Printer does not print? (Answer y if statement is true or n): n A red light is flashing? (Answer y if statement is true or n): n Printer is unrecognised? (Answer y if statement is true or n): n Try this: Pray!
Tcl
<lang tcl>package require TclOO
proc yesno Template:Message "Press Y or N to continue" {
fconfigure stdin -blocking 0 exec stty raw read stdin ; # flush puts -nonewline "${message}: " flush stdout while {![eof stdin]} { set c [string tolower [read stdin 1]] if {$c eq "y" || $c eq "n"} break } puts [string toupper $c] exec stty -raw fconfigure stdin -blocking 1 return [expr {$c eq "y"}]
}
oo::class create DecisionTable {
variable qlist responses constructor {questions responseMap} {
set qlist $questions set responses $responseMap
}
method consult {} {
set idx 0 foreach q $qlist { set answer [yesno "$q? \[y/n\]"] set idx [expr {$idx*2 + (1-$answer)}] } foreach {msg map} $responses { # Allow a column to be omitted; magic! if {"0[lindex $map $idx]"} { puts $msg } }
}
}</lang> Demonstration: <lang tcl>DecisionTable create printerDiagnosisTable {
"Printer does not print" "A red light is flashing" "Printer is unrecognised"
} {
"Check the power cable" {0 0 1} "Check the printer-computer cable" {1 0 1} "Ensure printer software is installed" {1 0 1 0 1 0 1} "Check/replace ink" {1 1 0 0 1 1} "Check for paper jam" {0 1 0 1}
} printerDiagnosisTable consult</lang> Output:
Printer does not print? [y/n]: N A red light is flashing? [y/n]: Y Printer is unrecognised? [y/n]: Y Ensure printer software is installed Check/replace ink