Decision tables: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎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 is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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

  1. http://rosettacode.org/wiki/Keyboard_Input/Obtain_a_Y_or_N_response#Tcl

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