Decision tables

From Rosetta Code
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