Decision tables: Difference between revisions
(→Tcl: Added implementation) |
m (→{{header|Tcl}}: formatting) |
||
Line 116: | Line 116: | ||
}</lang> |
}</lang> |
||
Demonstration: |
Demonstration: |
||
<lang>DecisionTable create printerDiagnosisTable { |
<lang tcl>DecisionTable create printerDiagnosisTable { |
||
"Printer does not print" |
"Printer does not print" |
||
"A red light is flashing" |
"A red light is flashing" |
Revision as of 11:57, 25 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 ;
struct Decision {
immutable string[] conds ; immutable string[] actions ; immutable bool[][] rules ;
this(string[] c, string[] a, bool[][] q) { assert(c.length < 32, "max 31 test conditions") ; immutable(bool)[][] r ; q.length = 2^^c.length ; // fix rules foreach(ref e ; q) r ~= e.idup ; conds = c.idup ; actions = a.idup ; rules = assumeUnique(r) ; // cast to immutable, Contract style }
string[] test(bool[] tested, string NoMatchMsg = "it is fine :)") { auto idx = reduce!"2*a+b"(map!"a?1:0"(tested.reverse)) ;// get index string[] rightActions ; foreach(i, e ; rules[idx]) 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"], [[false], // others is _false_ , save hand-writing [false, false, true], [false, false, false, true], [false, false, true, true], [false, false, false, false, true], [true, true, true], [false, false, false, true, true], [false, true, true, true]] ) ; 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
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