Jannick Knudsen 1 jaar geleden
commit
17b5af2fb5
21 gewijzigde bestanden met toevoegingen van 4151 en 0 verwijderingen
  1. 1 0
      README.md
  2. BIN
      ein
  3. 580 0
      ein.js
  4. 0 0
      ein.js.c.js
  5. 0 0
      ein.js.c.js_tmp
  6. 301 0
      ein2.js
  7. 301 0
      ein2.js.c.js
  8. 301 0
      ein2.js.c.js_tmp
  9. 37 0
      ein3.js
  10. 1 0
      ein3.js.c.js
  11. 1 0
      ein3.js.c.js_tmp
  12. 481 0
      ein_sol.js
  13. 761 0
      ein_work2.js
  14. 725 0
      einwork.js
  15. 19 0
      ena.js
  16. 18 0
      ena.js.c.js
  17. 18 0
      ena.js.c.js_tmp
  18. 197 0
      sol.txt
  19. 409 0
      solver.js
  20. 0 0
      solver.js.c.js
  21. 0 0
      solver.js.c.js_tmp

+ 1 - 0
README.md

@@ -0,0 +1 @@
+##einstein-solver


+ 580 - 0
ein.js

@@ -0,0 +1,580 @@
+// var mo = require("./solver");
+ /*
+     .addVariabelSet("Nationality", ["Norwegian", "German", "Dane", "Swede", "Englishman"])
+     .addVariabelSet("Color", ["Yellow", "Red", "White", "Blue", "Green"])
+     .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
+     .addVariabelSet("Drinks", ["Bier", "Water", "Coffee", "Milk", "Tea"])
+     .addVariabelSet("Animals", ["Birds", "Dogs", "Cats", "Horses", "Fish","Snake"])
+     */
+
+function EV() {
+    this.__e = {};
+}
+EV.prototype.__e = {};
+EV.prototype.emit = function(n) {
+    var that = this;
+    var args = [].slice.apply(arguments, [1]);
+    (this.__e[n] || []).map(function(lis) {
+        lis.map(function(fn) {
+            fn.apply(that, args)
+        })
+    })
+    return this;
+}
+EV.prototype.on = function(n) {
+    var args = [].slice.apply(arguments, [1]);
+    this.__e[n] = this.__e[n] || [];
+    this.__e[n].push(args);
+    return this;
+}
+
+function inherits(ctor, superCtor) {
+    var Obj = function() {};
+    Obj.prototype = superCtor.prototype;
+    ctor.prototype = new Obj
+}
+
+
+function permutates(xs) {
+    var ret = [];
+
+    for (var i = 0; i < xs.length; i = i + 1) {
+        var rest = permutates(xs.slice(0, i).concat(xs.slice(i + 1)));
+
+        if (!rest.length) {
+            ret.push([xs[i]])
+        } else {
+            for (var j = 0; j < rest.length; j = j + 1) {
+                ret.push([xs[i]].concat(rest[j]))
+            }
+        }
+    }
+    return ret;
+}
+
+function mo() {
+    this.variabler = {};
+    this.funcs = {};
+    this.rulas = [];
+}
+inherits(mo, EV)
+
+mo.prototype.addVariabelSet = function(navn, arr) {
+    this.variabler[navn] = arr
+    return this;
+}
+mo.prototype.addVariableTable = function(navn, arr) {
+    return this;
+}
+mo.prototype.addFunction = function(name, func) {
+    this.funcs[name] = func;
+    return this;
+}
+mo.prototype.addClause = function() {
+    var args = Array.prototype.slice.apply(arguments, []);
+    while (args.length) {
+        var arg = args.shift();
+
+        var props = Object.keys(arg);
+        var propid1, propid2;
+
+        if (this.variabler[props[0]]) {
+            propid1 = Object.keys(this.variabler).indexOf(props[0]);
+        }
+        if (this.variabler[props[1]]) {
+            propid2 = Object.keys(this.variabler).indexOf(props[1]);
+        } else {}
+        var arr = []
+        if (propid1 > -1 && propid2 > -1) {
+            val1 = this.variabler[props[0]].indexOf(arg[props[0]])
+            val2 = this.variabler[props[1]].indexOf(arg[props[1]])
+            arr = ["check", propid1, propid2, val1, val2, [props[0], arg[props[0]], props[1], arg[props[1]]].join(" ")];
+        } else {
+            var lookfor = props[props.length - 1];
+            if (this.funcs[lookfor]) {
+                arr = this.funcs[lookfor].apply(this, [arg])
+            }
+        }
+    }
+    this.rulas.push(arr);
+    return this;
+}
+
+mo.prototype.build = function(tabl) {
+    var r = [];
+    var arr = [];
+    var pertable = []
+
+    for (var navn in this.variabler) {
+        pertable.push(permutates((this.variabler[navn]).map(function(a, i) {
+            return i
+        })));
+    }
+    pertable = pertable.sort(function(a,b){ return a.length > b.length ? 1 : a.length < b.length ? -1 : 0 });
+
+    pertable.map(function(a){
+
+        console.log("A",a.length)
+
+    })
+
+
+    return pertable.pop()
+}
+
+mo.prototype.checkPos = function(prop1, prop2, val1, val2) {
+
+    return this.current[this.sos[prop1]][val2] == val1
+
+}
+
+mo.prototype.check = function(prop1, prop2, val1, val2) {
+    var i;
+    //   console.log(prop1,this.sos[prop1], prop2, this.current[this.sos[prop1]],this.current[this.sos[prop2]],val1,val2)
+    for (i = 0; i < 5; i++) {
+        if (this.current[this.sos[prop1]][i] == val1) {
+            //         console.log("II,",i,this.current[this.sos[prop1]][i],"=",val1,"&", this.current[this.sos[prop2]][i],"=",val2 );
+            var p;
+            p = (this.current[this.sos[prop2]][i] == val2)
+            return p;
+        }
+    }
+    return false;
+}
+mo.prototype.checkLeft = function(prop1, prop2, val1, val2) {
+    var i;
+    for (i = 0; i < 4; i++) {
+        if (this.current[this.sos[prop1]][i] == val1) {
+            var p;
+            p = (this.current[this.sos[prop2]][i + 1] == val2)
+            return p;
+        }
+    }
+    return false;
+}
+mo.prototype.checkRight = function(prop1, prop2, val1, val2) {
+    var i;
+    for (i = 1; i < 5; i++) {
+        if (this.current[this.sos[prop1]][i] == val1) {
+            var p;
+            p = (this.current[this.sos[prop2]][i - 1] == val2)
+            return p;
+        }
+    }
+    return false;
+}
+
+mo.prototype.checkBoth = function(prop1, prop2, val1, val2) {
+
+    return this.checkLeft(prop1, prop2, val1, val2) || this.checkRight(prop1, prop2, val1, val2)
+}
+
+/*
+mo.prototype.inner_solve_l_1 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_2 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_3 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_4 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_5 = function(cands) {
+
+}
+*/
+
+
+
+mo.prototype.inner_solve = function(cands) {
+    /*todo tada - slip fri for for for for for */
+    var self = this;
+
+    var cc = cands.length;
+    var ticks = [0, 0, 0, 0, 0];
+    var ic = 0;
+    var iomax = self.rulas.length;
+    var ioa = 0;
+    var suma = cands.reduce(function(a, b) {
+        return b[1].length * a
+    }, 1)
+
+    console.log(cands);
+
+    console.log(this.rulas);
+    
+
+    return;
+
+
+    for (var i0 = 0; i0 < cands[0][1].length; i0++) {
+        if (cands[1]) {
+
+            for (var i1 = 0; i1 < cands[1][1].length; i1++) {
+                if (cands[2]) {
+
+                    for (var i2 = 0; i2 < cands[2][1].length; i2++) {
+                        if (cands[3]) {
+
+                        } else {
+                            total = suma * self.subspace * self.subspace
+                            var st = [0, 1, 2, 3, 4]
+                            self.sos[cands[0][0]] = cands[0][1][i0]
+                            self.sos[cands[1][0]] = cands[1][1][i1]
+                            self.sos[cands[2][0]] = cands[2][1][i2]
+
+                            st.splice(st.indexOf(cands[0][0]), 1);
+                            st.splice(st.indexOf(cands[1][0]), 1);
+                            st.splice(st.indexOf(cands[2][0]), 1);
+                            for (var i3 = 0; i3 < self.subspace; i3++) {
+                                for (var i4 = 0; i4 < self.subspace; i4++) {
+                                    ic++
+                                    self.sos[st[0]] = i3
+                                    self.sos[st[1]] = i4
+                                    var io = 0;
+                                    var ff = true;
+                                    while (io < iomax && ff) {
+                                        ff = false;
+                                        var t = self.rulas[io];
+                                        ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                                        if (ff) {
+                                            io++;
+                                        }
+                                    }
+                                    if (io > ioa) {
+                                        ioa = io;
+                                        var tt = self.rulas.map(function(t) {
+                                            return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                                        })
+                                        self.emit("part", ic, io, ioa, iomax, self.sos, tt.map(function(a) {
+                                            return a.join(" ")
+                                        }))
+                                    }
+                                    if (ioa >= iomax) {
+                                        return self.sos;
+                                    }
+                                    if (ic % 1000000 === 0) {
+                                        self.emit("status", (ic / (total / 100)).toFixed(2) + "%", total, ic, ioa, iomax)
+                                        // console.log("X2", ic, io, ioa, iomax,":>", self.sos[cands[0][0]], self.sos[cands[1][0]], self.sos[cands[2][0]], i3, i4);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+
+
+                    var st = [0, 1, 2, 3, 4]
+                    self.sos[cands[0][0]] = cands[0][1][i0]
+                    self.sos[cands[1][0]] = cands[1][1][i1]
+                    //                           self.sos[cands[2][0]] = cands[2][1][i2]
+
+                    st.splice(st.indexOf(cands[0][0]), 1);
+                    st.splice(st.indexOf(cands[1][0]), 1);
+                    //                             st.splice(st.indexOf(cands[2][0]), 1);
+                    total = suma * self.subspace * self.subspace * self.subspace;
+
+                    for (var i2 = 0; i2 < self.subspace; i2++) {
+                        for (var i3 = 0; i3 < self.subspace; i3++) {
+                            for (var i4 = 0; i4 < self.subspace; i4++) {
+                                ic++
+                                self.sos[st[0]] = i2
+                                self.sos[st[1]] = i3
+                                self.sos[st[2]] = i4
+                                var io = 0;
+                                var ff = true;
+                                while (io < iomax && ff) {
+                                    ff = false;
+                                    var t = self.rulas[io];
+                                    ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                                    if (ff) {
+                                        io++;
+                                    }
+                                }
+                                if (io > ioa) {
+                                    ioa = io;
+                                    var tt = self.rulas.map(function(t) {
+                                        return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                                    })
+                                    self.emit("part", ic, io, ioa, iomax, self.sos, tt.map(function(a) {
+                                        return a.join(" ")
+                                    }))
+                                }
+                                if (ioa >= iomax) {
+                                    return self.sos;
+                                }
+                                if (ic % 1000000 === 0) {
+                                    console.log("X3", ic, io, ioa, iomax, ":>", self.sos[cands[0][0]], self.sos[cands[1][0]], i2, i3, i4);
+                                }
+                            }
+                        }
+
+                    }
+
+
+
+
+
+
+
+                }
+
+            }
+
+
+        }
+
+    }
+
+
+    return false;
+
+
+
+}
+
+
+mo.prototype.solve = function() {
+    var self = this;
+    self.current = this.build("House");
+    console.log(self.current);
+    
+    var sa = Object.keys(this.variabler);
+    self.sos = sa.map(function(a) {
+        return 0; //self.current.length - 1; //Math.floor(Math.random()*self.current.length-1);
+    })
+    self.subspace = self.current.length;
+    self.varspace = sa.length;
+
+
+    var iteration = 0;
+    var maxi = 0;
+    var ioa = -1;
+
+
+    // først find variabler som bruges i samme opslag.
+    var tas = {}
+    var firsta = [];
+    self.rulas.map(function(ru) {
+        console.log(ru);
+        if (ru[1] == ru[2]) {
+            firsta.push(ru);
+        }
+    })
+
+    self.sos = self.sos.map(function(a) {
+        return 0
+    })
+
+    var osa = -1
+    console.log(firsta);
+
+    var cands = [];
+
+
+    for (var x = 0; x < firsta.length; x++) {
+        self.sos = self.sos.map(function(a) {
+            return 0
+        })
+
+        var t = firsta[x];
+        var ca = [];
+        for (var i = 0; i < self.subspace; i++) {
+            var ff = false;
+            self.sos[t[1]] = i
+            ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+            if (ff) {
+                ca.push(i);
+            }
+        }
+        cands.push([t[1], ca]);
+    }
+
+
+    self.sos = self.sos.map(function(a) {
+        return 0
+    })
+    var result = this.inner_solve(cands);
+    this.emit("done", result);
+}
+
+
+mo.prototype.printit = function(vals) {
+    var self = this;
+    var vals = vals || self.sos;
+    var lpad = function(s, l) {
+        while (s.length < l) {
+            s = " " + s
+        };
+        return s;
+    }
+    var rpad = function(s, l) {
+        while (s.length < l) {
+            s = s + " "
+        };
+        return s;
+    }
+    var s = [];
+    s.push([" ", 1, 2, 3, 4, 5].map(function(a) {
+        return lpad("" + a, 12)
+    }).join(" "));
+    Object.keys(self.variabler).map(function(k, ia) {
+        s.push([k, 0, 1, 2, 3, 4].map(function(a, io) {
+            return a == k ? rpad(k + ":" + vals[ia], 20) : lpad("" + self.variabler[k][self.current[vals[ia]][a]], 12)
+        }).join(" "))
+    })
+    console.log(s.join("\n") + "\n")
+}
+
+
+module.exports = mo;
+
+
+ var t = new mo()
+     .addVariabelSet("Nationality", ["Norwegian", "Dane", "Englishman", "German", "Swede"])
+     .addVariabelSet("Color", ["Yellow", "Blue", "Red", "Green", "White"])
+     .addVariabelSet("Smokes", ["Dunhill", "Blend", "PallMall", "Prince", "BlueMasters"])
+     .addVariabelSet("Drinks", ["Water", "Tea", "Milk", "Coffee", "Bier" ])
+     .addVariabelSet("Animals", ["Cats", "Horses", "Birds", "Fish", "Dogs"])
+     .addFunction("Neighbor", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkBoth", propid1, propid2, valid1, valid2, [prop1, val1, "Besides", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_Before", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_Before"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkLeft", propid1, propid2, valid1, valid2, [prop1, val1, "Before", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_After", function() {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_After"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkRight", propid1, propid2, valid1, valid2, [prop1, val1, "After", prop2, val2].join(" ")]
+     })
+     .addFunction("House", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = prop1
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var val1 = arg[prop1];
+         var val2 = arg["House"];
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         return ['checkPos', propid1, propid1, valid1, val2, [prop1, val1, "House", val2].join(" ")]
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "House": 0
+     })
+     .addClause({
+         "Drinks": "Milk",
+         "House": 2
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "Neighbor": {
+             "Color": "Blue"
+         }
+     })
+     .addClause({
+         "Nationality": "Englishman",
+         "Color": "Red"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Drinks": "Water"
+         }
+     })
+     .addClause({
+         "Nationality": "Swede",
+         "Animals": "Dogs"
+     })
+     .addClause({
+         "Nationality": "Dane",
+         "Drinks": "Tea"
+     })
+     .addClause({
+         "Color": "Green",
+         "Drinks": "Coffee"
+     })
+     .addClause({
+         "Smokes": "PallMall",
+         "Animals": "Birds"
+     })
+     .addClause({
+         "Color": "Yellow",
+         "Smokes": "Dunhill"
+     })
+     .addClause({
+         "Nationality": "German",
+         "Smokes": "Prince"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Animals": "Cats"
+         }
+     })
+     .addClause({
+         "Animals": "Horses",
+         "Neighbor": {
+             "Smokes": "Dunhill"
+         }
+     })
+     .addClause({
+         "Smokes": "BlueMasters",
+         "Drinks": "Bier"
+     })
+     .addClause({
+         "Color": "Green",
+         "Neighbor_Before": {
+             "Color": "White"
+         }
+     })
+     .on("status", function(per, total, ic, ioa, iomax) {
+         console.log("Status", per, ic + " of " + total, "sat " + ioa + " of " + iomax);
+     })
+     .on("part", function(iterations, foundl, foundt, total, sos, rules) {
+         this.parts = this.parts || [];
+         this.parts.push([iterations, foundt, total, sos, rules]);
+     })
+     .on("done", function(result) {
+         if (result) {
+             console.log("FOUND SOLUTION:", result);
+             this.printit(result);
+             if (this.parts && this.parts.length) {
+                 var rr = this.parts.pop();
+                 console.log(rr[4]);
+             }
+         } else {
+             console.log("NO SOLUTION");
+             console.log("Closest:");
+             if (this.parts && this.parts.length) {
+                 var rr = this.parts.pop();
+                 // console.log("RRRRR",rr);
+                 this.printit(rr[3])
+                 console.log(rr[4]);
+             }
+         }
+     })
+     .solve()

File diff suppressed because it is too large
+ 0 - 0
ein.js.c.js


File diff suppressed because it is too large
+ 0 - 0
ein.js.c.js_tmp


+ 301 - 0
ein2.js

@@ -0,0 +1,301 @@
+function mo() {
+    this.variabler = {};
+    this.tabel = {};
+    this.tabel_navn = "";
+    this.regler = [];
+    this._internal_step_counter = 0;
+    this.funcs = {};
+}
+
+mo.prototype.addVariabelSet = function(navn, arr) {
+    this.variabler[navn] = arr;
+    return this;
+}
+mo.prototype.addVariableTable = function(navn, arr) {
+    this.tabel[navn] = arr;
+    this.tabel_navn = navn;
+    return this;
+}
+
+mo.prototype.addClause = function() {
+    var args = Array.prototype.slice.apply(arguments, []);
+    this.regler.push(args.shift());
+    return this;
+}
+mo.prototype.addFunction = function(name,func) {
+    this.funcs[name] = func;
+    return this;
+}
+
+/*mo.prototype.randoma = function(tabl) {
+    var ll = this.tabel[tabl].length,
+        l = 0;
+    var r = [];
+    var taken = {}
+    for (var navn in this.variabler) {
+        taken[navn] = {}
+    }
+    while (l < ll) {
+        var o = {}
+        o[tabl] = this.tabel[tabl][l];
+        for (var navn in this.variabler) {
+
+            var m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+            
+            while (taken[navn][m]) {
+                m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+                this._internal_step_counter++;
+            }
+            taken[navn][m] = 1;
+            o[navn] = m
+        }
+        r.push(o);
+        l++
+    }
+    return r;
+}*/
+mo.prototype.buildBase = function() {
+    var tabl = this.tabel_navn;
+    var ll = this.tabel[tabl].length,
+        l = 0;
+    var r = [];
+    var taken = {}
+    for (var navn in this.variabler) {
+        taken[navn] = {}
+    }
+    while (l < ll) {
+        var o = {}
+
+        o[tabl] = this.tabel[tabl][l];
+        
+        for (var navn in this.variabler) {
+            
+
+            var m = this.variabler[navn][l];
+            
+           /* while (taken[navn][m]) {
+                m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+                this._internal_step_counter++;
+            }*/
+
+//            taken[navn][m] = 1;
+            o[navn] = m
+            
+        }
+
+        r.push(o);
+        o._sure = [];
+        l++
+    }
+
+
+
+    return r;
+}
+function rra(w){
+return function(a){
+    return a!==w
+}    
+}
+
+mo.prototype.solve = function() {
+    var current = this.buildBase()
+    var tabl = this.tabel_navn;
+    this.regler.map(function(rule){
+        if(rule[tabl]){
+            var ruleTarget = current.filter(function(a){ return a[tabl] === rule[tabl]}).shift();
+            Object.keys(rule).filter(rra(tabl)).map(function(prop){
+                var currentHolder = current.filter(function(a){ return a[prop]===rule[prop]}).shift();
+                currentHolder[prop] = ruleTarget[prop]
+                ruleTarget[prop] = rule[prop];
+                ruleTarget._sure.push(prop)
+            })
+        }
+    })
+
+    var rep = this.regler.filter(function(rule){ return !rule[tabl] })
+
+    //this.randoma("House");
+
+    var sat = false;
+    var ii = 0;
+  
+
+    while (!sat && ii < 100000) {
+        ii++
+
+
+                
+
+//        console.log(this.regler.length);
+
+        /*        var ffs = this.regler.map(function(reg) {
+            var t = false;
+            try {
+                t = eval(reg);
+            } catch (e) {
+                // console.log("EE",e);
+            }
+            return t;
+        })
+        var longa = ffs.filter(function(a) {
+            return a === true
+        }).length;
+        if(longa >= longest){
+            longest = longa;
+            ffou = current; 
+        }
+*/
+
+        /*        if (longa === ffs.length) {
+            sat = true;
+        } else {
+           current = this.randoma("House");
+        }
+*/
+        if (ii % 100000 === 0) {
+            console.log(ii);
+
+        }
+
+
+    }
+
+
+    //    console.log(longest);
+
+    //        console.log("TEST",t);
+
+
+    //    console.log(current);
+
+    //  console.log(this.regler);
+
+    if (sat) {
+        console.log("Found Solution:", current);
+
+    }
+
+   console.log(current);
+}
+
+
+mo.prototype.stats = function() {
+    console.log("steps ", this._internal_step_counter)
+    console.log(this);
+}
+
+var t = new mo()
+    .addVariabelSet("Color", ["Green","Red", "White", "Yellow", "Blue" ])
+    .addVariabelSet("Nationality", ["Norwegian", "Dane", "Swede", "Englishman", "German"])
+    .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
+    .addVariabelSet("Drinks", ["Water", "Bier", "Milk", "Tea", "Coffee"])
+    .addVariabelSet("Animals", ["Dogs", "Birds", "Cat", "Horses", "Fish"])
+    .addVariableTable("House", [1, 2, 3, 4, 5])
+    .addFunction("Neighbor", function() {})
+    .addFunction("Neighbor_Before", function() {})
+    .addFunction("Neighbor_After", function() {})
+    .addClause({
+        "Nationality": "Norwegian",
+        "House": 1
+    })
+    .addClause({
+        "Drinks": "Milk",
+        "House": 3
+    })
+    .addClause({
+        "Nationality": "Norwegian",
+        "Neighbor": {
+            "Color": "Blue"
+        }
+    })
+    .addClause({
+        "Nationality": "Englishman",
+        "Color": "Red"
+    })
+    .addClause({
+        "Smokes": "Blend",
+        "Neighbor": {
+            "Drinks": "Water"
+        }
+    })
+    .addClause({
+        "Nationality": "Swede",
+        "Animals": "Dogs"
+    })
+    .addClause({
+        "Nationality": "Dane",
+        "Drinks": "Tea"
+    })
+    .addClause({
+        "Color": "Green",
+        "Neighbor_Before": {
+            "Color": "White"
+        }
+    })
+    .addClause({
+        "Color": "Green",
+        "Drinks": "Coffee"
+    })
+    .addClause({
+        "Smokes": "PallMall",
+        "Animals": "Birds"
+    })
+    .addClause({
+        "Color": "Yellow",
+        "Smokes": "Dunhill"
+    })
+    .addClause({
+        "Smokes": "Blend",
+        "Neighbor": {
+            "Animals": "Cats"
+        }
+    })
+    .addClause({
+        "Animals": "Horses",
+        "Neighbor": {
+            "Smokes": "Dunhill"
+        }
+    })
+    .addClause({
+        "Smokes": "BlueMasters",
+        "Drinks": "Bier"
+    })
+    .addClause({
+        "Nationality": "German",
+        "Smokes": "Prince"
+    })
+    
+ 
+t.solve();
+
+
+/*
+    The Englishman lives in the red house.<br>
+    The Swede keeps dogs.<br>
+    The Dane drinks tea.<br>
+    The green house is just to the left of the white one.<br>
+    The owner of the green house drinks coffee.<br>
+    The Pall Mall smoker keeps birds.<br>
+    The owner of the yellow house smokes Dunhills.<br>
+    The man in the center house drinks milk.<br>
+    The Norwegian lives in the first house.<br>
+    The Blend smoker has a neighbor who keeps cats.<br>
+    The man who smokes Blue Masters drinks bier.<br>
+    The man who keeps horses lives next to the Dunhill smoker.<br>
+    The German smokes Prince.<br>
+    The Norwegian lives next to the blue house.<br>
+    The Blend smoker has a neighbor who drinks water.<br>
+*/
+
+
+//console.log(t.randoma("House"));
+//t.stats();
+
+
+/*
+var Colors = ["Red", "White", "Yellow", "Blue", "Green"],
+    Nationality = ["Norwegian", "Dane", "Swede", "Englishman", "German"],
+    Cigarettes = ["Prince", "Blend", "Dunhill", "Blue Masters", "Pall Mall"],
+    Drinks = ["Water", "Bier", "Milk", "Tea", "Coffee"],
+    Animals = ["Dogs", "Birds", "Cat", "Horses", "Fish"];*/

+ 301 - 0
ein2.js.c.js

@@ -0,0 +1,301 @@
+function mo() {
+    this.variabler = {};
+    this.tabel = {};
+    this.tabel_navn = "";
+    this.regler = [];
+    this._internal_step_counter = 0;
+    this.funcs = {};
+}
+
+mo.prototype.addVariabelSet = function(navn, arr) {
+    this.variabler[navn] = arr;
+    return this;
+}
+mo.prototype.addVariableTable = function(navn, arr) {
+    this.tabel[navn] = arr;
+    this.tabel_navn = navn;
+    return this;
+}
+
+mo.prototype.addClause = function() {
+    var args = Array.prototype.slice.apply(arguments, []);
+    this.regler.push(args.shift());
+    return this;
+}
+mo.prototype.addFunction = function(name,func) {
+    this.funcs[name] = func;
+    return this;
+}
+
+/*mo.prototype.randoma = function(tabl) {
+    var ll = this.tabel[tabl].length,
+        l = 0;
+    var r = [];
+    var taken = {}
+    for (var navn in this.variabler) {
+        taken[navn] = {}
+    }
+    while (l < ll) {
+        var o = {}
+        o[tabl] = this.tabel[tabl][l];
+        for (var navn in this.variabler) {
+
+            var m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+            
+            while (taken[navn][m]) {
+                m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+                this._internal_step_counter++;
+            }
+            taken[navn][m] = 1;
+            o[navn] = m
+        }
+        r.push(o);
+        l++
+    }
+    return r;
+}*/
+mo.prototype.buildBase = function() {
+    var tabl = this.tabel_navn;
+    var ll = this.tabel[tabl].length,
+        l = 0;
+    var r = [];
+    var taken = {}
+    for (var navn in this.variabler) {
+        taken[navn] = {}
+    }
+    while (l < ll) {
+        var o = {}
+
+        o[tabl] = this.tabel[tabl][l];
+        
+        for (var navn in this.variabler) {
+            
+
+            var m = this.variabler[navn][l];
+            
+           /* while (taken[navn][m]) {
+                m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+                this._internal_step_counter++;
+            }*/
+
+//            taken[navn][m] = 1;
+            o[navn] = m
+            
+        }
+
+        r.push(o);
+        o._sure = [];
+        l++
+    }
+
+
+
+    return r;
+}
+function rra(w){
+return function(a){
+    return a!==w
+}    
+}
+
+mo.prototype.solve = function() {
+    var current = this.buildBase()
+    var tabl = this.tabel_navn;
+    this.regler.map(function(rule){
+        if(rule[tabl]){
+            var ruleTarget = current.filter(function(a){ return a[tabl] === rule[tabl]}).shift();
+            Object.keys(rule).filter(rra(tabl)).map(function(prop){
+                var currentHolder = current.filter(function(a){ return a[prop]===rule[prop]}).shift();
+                currentHolder[prop] = ruleTarget[prop]
+                ruleTarget[prop] = rule[prop];
+                ruleTarget._sure.push(prop)
+            })
+        }
+    })
+
+    var rep = this.regler.filter(function(rule){ return !rule[tabl] })
+
+    //this.randoma("House");
+
+    var sat = false;
+    var ii = 0;
+  
+
+    while (!sat && ii < 100000) {
+        ii++
+
+
+                
+
+//        console.log(this.regler.length);
+
+        /*        var ffs = this.regler.map(function(reg) {
+            var t = false;
+            try {
+                t = eval(reg);
+            } catch (e) {
+                // console.log("EE",e);
+            }
+            return t;
+        })
+        var longa = ffs.filter(function(a) {
+            return a === true
+        }).length;
+        if(longa >= longest){
+            longest = longa;
+            ffou = current; 
+        }
+*/
+
+        /*        if (longa === ffs.length) {
+            sat = true;
+        } else {
+           current = this.randoma("House");
+        }
+*/
+        if (ii % 100000 === 0) {
+            console.log(ii);
+
+        }
+
+
+    }
+
+
+    //    console.log(longest);
+
+    //        console.log("TEST",t);
+
+
+    //    console.log(current);
+
+    //  console.log(this.regler);
+
+    if (sat) {
+        console.log("Found Solution:", current);
+
+    }
+
+   console.log(current);
+}
+
+
+mo.prototype.stats = function() {
+    console.log("steps ", this._internal_step_counter)
+    console.log(this);
+}
+
+var t = new mo()
+    .addVariabelSet("Color", ["Green","Red", "White", "Yellow", "Blue" ])
+    .addVariabelSet("Nationality", ["Norwegian", "Dane", "Swede", "Englishman", "German"])
+    .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
+    .addVariabelSet("Drinks", ["Water", "Bier", "Milk", "Tea", "Coffee"])
+    .addVariabelSet("Animals", ["Dogs", "Birds", "Cat", "Horses", "Fish"])
+    .addVariableTable("House", [1, 2, 3, 4, 5])
+    .addFunction("Neighbor", function() {})
+    .addFunction("Neighbor_Before", function() {})
+    .addFunction("Neighbor_After", function() {})
+    .addClause({
+        "Nationality": "Norwegian",
+        "House": 1
+    })
+    .addClause({
+        "Drinks": "Milk",
+        "House": 3
+    })
+    .addClause({
+        "Nationality": "Norwegian",
+        "Neighbor": {
+            "Color": "Blue"
+        }
+    })
+    .addClause({
+        "Nationality": "Englishman",
+        "Color": "Red"
+    })
+    .addClause({
+        "Smokes": "Blend",
+        "Neighbor": {
+            "Drinks": "Water"
+        }
+    })
+    .addClause({
+        "Nationality": "Swede",
+        "Animals": "Dogs"
+    })
+    .addClause({
+        "Nationality": "Dane",
+        "Drinks": "Tea"
+    })
+    .addClause({
+        "Color": "Green",
+        "Neighbor_Before": {
+            "Color": "White"
+        }
+    })
+    .addClause({
+        "Color": "Green",
+        "Drinks": "Coffee"
+    })
+    .addClause({
+        "Smokes": "PallMall",
+        "Animals": "Birds"
+    })
+    .addClause({
+        "Color": "Yellow",
+        "Smokes": "Dunhill"
+    })
+    .addClause({
+        "Smokes": "Blend",
+        "Neighbor": {
+            "Animals": "Cats"
+        }
+    })
+    .addClause({
+        "Animals": "Horses",
+        "Neighbor": {
+            "Smokes": "Dunhill"
+        }
+    })
+    .addClause({
+        "Smokes": "BlueMasters",
+        "Drinks": "Bier"
+    })
+    .addClause({
+        "Nationality": "German",
+        "Smokes": "Prince"
+    })
+    
+ 
+t.solve();
+
+
+/*
+    The Englishman lives in the red house.<br>
+    The Swede keeps dogs.<br>
+    The Dane drinks tea.<br>
+    The green house is just to the left of the white one.<br>
+    The owner of the green house drinks coffee.<br>
+    The Pall Mall smoker keeps birds.<br>
+    The owner of the yellow house smokes Dunhills.<br>
+    The man in the center house drinks milk.<br>
+    The Norwegian lives in the first house.<br>
+    The Blend smoker has a neighbor who keeps cats.<br>
+    The man who smokes Blue Masters drinks bier.<br>
+    The man who keeps horses lives next to the Dunhill smoker.<br>
+    The German smokes Prince.<br>
+    The Norwegian lives next to the blue house.<br>
+    The Blend smoker has a neighbor who drinks water.<br>
+*/
+
+
+//console.log(t.randoma("House"));
+//t.stats();
+
+
+/*
+var Colors = ["Red", "White", "Yellow", "Blue", "Green"],
+    Nationality = ["Norwegian", "Dane", "Swede", "Englishman", "German"],
+    Cigarettes = ["Prince", "Blend", "Dunhill", "Blue Masters", "Pall Mall"],
+    Drinks = ["Water", "Bier", "Milk", "Tea", "Coffee"],
+    Animals = ["Dogs", "Birds", "Cat", "Horses", "Fish"];*/

+ 301 - 0
ein2.js.c.js_tmp

@@ -0,0 +1,301 @@
+function mo() {
+    this.variabler = {};
+    this.tabel = {};
+    this.tabel_navn = "";
+    this.regler = [];
+    this._internal_step_counter = 0;
+    this.funcs = {};
+}
+
+mo.prototype.addVariabelSet = function(navn, arr) {
+    this.variabler[navn] = arr;
+    return this;
+}
+mo.prototype.addVariableTable = function(navn, arr) {
+    this.tabel[navn] = arr;
+    this.tabel_navn = navn;
+    return this;
+}
+
+mo.prototype.addClause = function() {
+    var args = Array.prototype.slice.apply(arguments, []);
+    this.regler.push(args.shift());
+    return this;
+}
+mo.prototype.addFunction = function(name,func) {
+    this.funcs[name] = func;
+    return this;
+}
+
+/*mo.prototype.randoma = function(tabl) {
+    var ll = this.tabel[tabl].length,
+        l = 0;
+    var r = [];
+    var taken = {}
+    for (var navn in this.variabler) {
+        taken[navn] = {}
+    }
+    while (l < ll) {
+        var o = {}
+        o[tabl] = this.tabel[tabl][l];
+        for (var navn in this.variabler) {
+
+            var m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+            
+            while (taken[navn][m]) {
+                m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+                this._internal_step_counter++;
+            }
+            taken[navn][m] = 1;
+            o[navn] = m
+        }
+        r.push(o);
+        l++
+    }
+    return r;
+}*/
+mo.prototype.buildBase = function() {
+    var tabl = this.tabel_navn;
+    var ll = this.tabel[tabl].length,
+        l = 0;
+    var r = [];
+    var taken = {}
+    for (var navn in this.variabler) {
+        taken[navn] = {}
+    }
+    while (l < ll) {
+        var o = {}
+
+        o[tabl] = this.tabel[tabl][l];
+        
+        for (var navn in this.variabler) {
+            
+
+            var m = this.variabler[navn][l];
+            
+           /* while (taken[navn][m]) {
+                m = this.variabler[navn][Math.floor(Math.random() * this.variabler[navn].length)];
+                this._internal_step_counter++;
+            }*/
+
+//            taken[navn][m] = 1;
+            o[navn] = m
+            
+        }
+
+        r.push(o);
+        o._sure = [];
+        l++
+    }
+
+
+
+    return r;
+}
+function rra(w){
+return function(a){
+    return a!==w
+}    
+}
+
+mo.prototype.solve = function() {
+    var current = this.buildBase()
+    var tabl = this.tabel_navn;
+    this.regler.map(function(rule){
+        if(rule[tabl]){
+            var ruleTarget = current.filter(function(a){ return a[tabl] === rule[tabl]}).shift();
+            Object.keys(rule).filter(rra(tabl)).map(function(prop){
+                var currentHolder = current.filter(function(a){ return a[prop]===rule[prop]}).shift();
+                currentHolder[prop] = ruleTarget[prop]
+                ruleTarget[prop] = rule[prop];
+                ruleTarget._sure.push(prop)
+            })
+        }
+    })
+
+    var rep = this.regler.filter(function(rule){ return !rule[tabl] })
+
+    //this.randoma("House");
+
+    var sat = false;
+    var ii = 0;
+  
+
+    while (!sat && ii < 100000) {
+        ii++
+
+
+                
+
+//        console.log(this.regler.length);
+
+        /*        var ffs = this.regler.map(function(reg) {
+            var t = false;
+            try {
+                t = eval(reg);
+            } catch (e) {
+                // console.log("EE",e);
+            }
+            return t;
+        })
+        var longa = ffs.filter(function(a) {
+            return a === true
+        }).length;
+        if(longa >= longest){
+            longest = longa;
+            ffou = current; 
+        }
+*/
+
+        /*        if (longa === ffs.length) {
+            sat = true;
+        } else {
+           current = this.randoma("House");
+        }
+*/
+        if (ii % 100000 === 0) {
+            console.log(ii);
+
+        }
+
+
+    }
+
+
+    //    console.log(longest);
+
+    //        console.log("TEST",t);
+
+
+    //    console.log(current);
+
+    //  console.log(this.regler);
+
+    if (sat) {
+        console.log("Found Solution:", current);
+
+    }
+
+   console.log(current);
+}
+
+
+mo.prototype.stats = function() {
+    console.log("steps ", this._internal_step_counter)
+    console.log(this);
+}
+
+var t = new mo()
+    .addVariabelSet("Color", ["Green","Red", "White", "Yellow", "Blue" ])
+    .addVariabelSet("Nationality", ["Norwegian", "Dane", "Swede", "Englishman", "German"])
+    .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
+    .addVariabelSet("Drinks", ["Water", "Bier", "Milk", "Tea", "Coffee"])
+    .addVariabelSet("Animals", ["Dogs", "Birds", "Cat", "Horses", "Fish"])
+    .addVariableTable("House", [1, 2, 3, 4, 5])
+    .addFunction("Neighbor", function() {})
+    .addFunction("Neighbor_Before", function() {})
+    .addFunction("Neighbor_After", function() {})
+    .addClause({
+        "Nationality": "Norwegian",
+        "House": 1
+    })
+    .addClause({
+        "Drinks": "Milk",
+        "House": 3
+    })
+    .addClause({
+        "Nationality": "Norwegian",
+        "Neighbor": {
+            "Color": "Blue"
+        }
+    })
+    .addClause({
+        "Nationality": "Englishman",
+        "Color": "Red"
+    })
+    .addClause({
+        "Smokes": "Blend",
+        "Neighbor": {
+            "Drinks": "Water"
+        }
+    })
+    .addClause({
+        "Nationality": "Swede",
+        "Animals": "Dogs"
+    })
+    .addClause({
+        "Nationality": "Dane",
+        "Drinks": "Tea"
+    })
+    .addClause({
+        "Color": "Green",
+        "Neighbor_Before": {
+            "Color": "White"
+        }
+    })
+    .addClause({
+        "Color": "Green",
+        "Drinks": "Coffee"
+    })
+    .addClause({
+        "Smokes": "PallMall",
+        "Animals": "Birds"
+    })
+    .addClause({
+        "Color": "Yellow",
+        "Smokes": "Dunhill"
+    })
+    .addClause({
+        "Smokes": "Blend",
+        "Neighbor": {
+            "Animals": "Cats"
+        }
+    })
+    .addClause({
+        "Animals": "Horses",
+        "Neighbor": {
+            "Smokes": "Dunhill"
+        }
+    })
+    .addClause({
+        "Smokes": "BlueMasters",
+        "Drinks": "Bier"
+    })
+    .addClause({
+        "Nationality": "German",
+        "Smokes": "Prince"
+    })
+    
+ 
+t.solve();
+
+
+/*
+    The Englishman lives in the red house.<br>
+    The Swede keeps dogs.<br>
+    The Dane drinks tea.<br>
+    The green house is just to the left of the white one.<br>
+    The owner of the green house drinks coffee.<br>
+    The Pall Mall smoker keeps birds.<br>
+    The owner of the yellow house smokes Dunhills.<br>
+    The man in the center house drinks milk.<br>
+    The Norwegian lives in the first house.<br>
+    The Blend smoker has a neighbor who keeps cats.<br>
+    The man who smokes Blue Masters drinks bier.<br>
+    The man who keeps horses lives next to the Dunhill smoker.<br>
+    The German smokes Prince.<br>
+    The Norwegian lives next to the blue house.<br>
+    The Blend smoker has a neighbor who drinks water.<br>
+*/
+
+
+//console.log(t.randoma("House"));
+//t.stats();
+
+
+/*
+var Colors = ["Red", "White", "Yellow", "Blue", "Green"],
+    Nationality = ["Norwegian", "Dane", "Swede", "Englishman", "German"],
+    Cigarettes = ["Prince", "Blend", "Dunhill", "Blue Masters", "Pall Mall"],
+    Drinks = ["Water", "Bier", "Milk", "Tea", "Coffee"],
+    Animals = ["Dogs", "Birds", "Cat", "Horses", "Fish"];*/

+ 37 - 0
ein3.js

@@ -0,0 +1,37 @@
+var t = [
+    ["Red", "White", "Yellow", "Blue", "Green"],
+    ["Norwegian", "Dane", "Swede", "Englishman", "German"],
+    ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"],
+    ["Water", "Bier", "Milk", "Tea", "Coffee"],
+    ["Dogs", "Birds", "Cat", "Horses", "Fish"]
+]
+
+/*
+    The Englishman lives in the red house.<br>
+    The Swede keeps dogs.<br>
+    The Dane drinks tea.<br>
+    The green house is just to the left of the white one.<br>
+    The owner of the green house drinks coffee.<br>
+    The Pall Mall smoker keeps birds.<br>
+    The owner of the yellow house smokes Dunhills.<br>
+    The man in the center house drinks milk.<br>
+    The Norwegian lives in the first house.<br>
+    The Blend smoker has a neighbor who keeps cats.<br>
+    The man who smokes Blue Masters drinks bier.<br>
+    The man who keeps horses lives next to the Dunhill smoker.<br>
+    The German smokes Prince.<br>
+    The Norwegian lives next to the blue house.<br>
+    The Blend smoker has a neighbor who drinks water.<br>
+*/
+var tt=[
+    ["*", t[1][0], "*", "*", "*"],
+    ["*", "*", "*", "*", "*"],
+    ["*", "*", "*", t[3][2], "*"],
+    ["*", "*", "*", "*", "*"],
+    ["*", "*", "*", "*", "*"]
+
+
+]
+
+
+console.log(tt)

+ 1 - 0
ein3.js.c.js

@@ -0,0 +1 @@
+var e=[["Red","White","Yellow","Blue","Green"],["Norwegian","Dane","Swede","Englishman","German"],["Prince","Blend","Dunhill","BlueMasters","PallMall"],["Water","Bier","Milk","Tea","Coffee"],["Dogs","Birds","Cat","Horses","Fish"]],l=[["*",e[1][0],"*","*","*"],["*","*","*","*","*"],["*","*","*","Milk","*"],["*","*","*","*","*"],["*","*","*","*","*"]];console.log(l);

+ 1 - 0
ein3.js.c.js_tmp

@@ -0,0 +1 @@
+var e=[["Red","White","Yellow","Blue","Green"],["Norwegian","Dane","Swede","Englishman","German"],["Prince","Blend","Dunhill","BlueMasters","PallMall"],["Water","Bier","Milk","Tea","Coffee"],["Dogs","Birds","Cat","Horses","Fish"]],l=[["*",e[1][0],"*","*","*"],["*","*","*","*","*"],["*","*","*","Milk","*"],["*","*","*","*","*"],["*","*","*","*","*"]];console.log(l);

+ 481 - 0
ein_sol.js

@@ -0,0 +1,481 @@
+ function EV() {
+     this.__e = {};
+ }
+ EV.prototype.__e = {};
+ EV.prototype.emit = function(n) {
+     var that = this;
+     var args = [].slice.apply(arguments, [1]);
+     (this.__e[n] || []).map(function(lis) {
+         lis.map(function(fn) {
+             fn.apply(that, args)
+         })
+     })
+     return this;
+ }
+ EV.prototype.on = function(n) {
+     var args = [].slice.apply(arguments, [1]);
+     this.__e[n] = this.__e[n] || [];
+     this.__e[n].push(args);
+     return this;
+ }
+
+ function inherits(ctor, superCtor) {
+     var Obj = function() {};
+     Obj.prototype = superCtor.prototype;
+     ctor.prototype = new Obj
+ }
+
+
+ function permutates(xs) {
+     var ret = [];
+
+     for (var i = 0; i < xs.length; i = i + 1) {
+         var rest = permutates(xs.slice(0, i).concat(xs.slice(i + 1)));
+
+         if (!rest.length) {
+             ret.push([xs[i]])
+         } else {
+             for (var j = 0; j < rest.length; j = j + 1) {
+                 ret.push([xs[i]].concat(rest[j]))
+             }
+         }
+     }
+     return ret;
+ }
+
+
+ function mo() {
+     this.variabler = {};
+     this.tabel = {};
+     this.tableHead = [];
+     this.tableName = "";
+     this.regler = [];
+     this._internal_step_counter = 0;
+     this.rmat = [];
+     this.funcs = {};
+     this.rulas = [];
+ }
+ inherits(mo, EV)
+
+ mo.prototype.addVariabelSet = function(navn, arr) {
+     this.variabler[navn] = arr;
+     return this;
+ }
+ mo.prototype.addVariableTable = function(navn, arr) {
+     this.tableHead = arr;
+     this.tableName = navn;
+     return this;
+ }
+ mo.prototype.addFunction = function(name, func) {
+     this.funcs[name] = func;
+     return this;
+ }
+ mo.prototype.addClause = function() {
+     var args = Array.prototype.slice.apply(arguments, []);
+     while (args.length) {
+         var arg = args.shift();
+
+         var props = Object.keys(arg);
+         var propid1, propid2;
+
+         if (this.variabler[props[0]]) {
+             propid1 = Object.keys(this.variabler).indexOf(props[0]);
+         }
+         if (this.variabler[props[1]]) {
+             propid2 = Object.keys(this.variabler).indexOf(props[1]);
+         } else {}
+         var arr = []
+         if (propid1 > -1 && propid2 > -1) {
+             val1 = this.variabler[props[0]].indexOf(arg[props[0]])
+             val2 = this.variabler[props[1]].indexOf(arg[props[1]])
+             arr = ["check", propid1, propid2, val1, val2, [props[0], arg[props[0]], props[1], arg[props[1]]].join(" ")];
+         } else {
+             var lookfor = props[props.length - 1];
+             if (this.funcs[lookfor]) {
+                 arr = this.funcs[lookfor].apply(this, [arg])
+             }
+         }
+     }
+     this.rulas.push(arr);
+     return this;
+ }
+
+ mo.prototype.build = function(tabl) {
+     var r = [];
+     var arr = [];
+     var pertable = []
+
+     for (var navn in this.variabler) {
+         pertable.push(permutates((this.variabler[navn]).map(function(a, i) {
+             return i
+         })));
+     }
+
+     return pertable;
+ }
+
+ mo.prototype.checkn = function(prop1, prop2, val1, val2) {
+
+     return this.current[this.sos[prop1]][val1] == val2
+
+ }
+
+ mo.prototype.check = function(prop1, prop2, val1, val2) {
+     var i;
+     //   console.log(prop1,this.sos[prop1], prop2, this.current[this.sos[prop1]],this.current[this.sos[prop2]],val1,val2)
+     for (i = 0; i < 5; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             //         console.log("II,",i,this.current[this.sos[prop1]][i],"=",val1,"&", this.current[this.sos[prop2]][i],"=",val2 );
+             var p;
+             p = (this.current[this.sos[prop2]][i] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+ mo.prototype.checkLeft = function(prop1, prop2, val1, val2) {
+     var i;
+     for (i = 0; i < 4; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             var p;
+             p = (this.current[this.sos[prop2]][i + 1] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+ mo.prototype.checkRight = function(prop1, prop2, val1, val2) {
+     var i;
+     for (i = 1; i < 5; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             var p;
+             p = (this.current[this.sos[prop2]][i - 1] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+
+ mo.prototype.checkBoth = function(prop1, prop2, val1, val2) {
+
+     return this.checkLeft(prop1, prop2, val1, val2) || this.checkRight(prop1, prop2, val1, val2)
+ }
+
+ mo.prototype.solve = function() {
+     var self = this;
+     self.current = this.build("House").shift();
+     var sa = Object.keys(this.variabler);
+     self.sos = sa.map(function(a) {
+         return 0; //self.current.length - 1; //Math.floor(Math.random()*self.current.length-1);
+     })
+     self.subspace = self.current.length;
+     self.varspace = sa.length;
+     self.space = Math.pow(self.subspace, self.varspace);
+
+
+     var iteration = 0;
+     var maxi = 0;
+     var ioa = -1;
+
+     var soso = [];
+
+     var sat = false;
+
+
+     self.rulas = self.rulas;//slice(0, 9);
+
+
+/*     self.rulas.sort(function(a, b) {
+         return a[1] > b[1] ? -1 : a[1] < b[1] ? 1 : a[2] > b[2] ? 1 : a[2] < b[2] ? -1 : 0
+     })
+*/
+     //    console.log(self.rulas);
+
+
+     //  return false;
+     var iomax = self.rulas.length;
+
+     while (!sat && iteration < self.space) {
+
+         var io = 0;
+         var ff = true;
+         while (io < iomax && ff) {
+             var t = self.rulas[io];
+             ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+             if(ff){
+                 io++;
+             }
+         }
+         if (io > ioa) {
+             soso.push([].concat(self.sos));
+             ioa = io;
+
+             var tt = self.rulas.map(function(t) {
+                 return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+             })
+             console.log(iteration, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                 return a.join(" ")
+             }));
+
+
+         }
+
+         if (io >= iomax) {
+             sat = true;
+             //            console.log((iteration).toFixed(0) + " ", ioa, "::", self.sos.join(" "), soso.join(" | "));
+
+         } else {
+             self.sos[4] = iteration % self.subspace;
+             self.sos[1] = Math.floor(iteration / self.subspace) % self.subspace;
+             self.sos[2] = Math.floor(iteration / (self.subspace * self.subspace)) % self.subspace;
+             self.sos[3] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace)) % self.subspace;
+             self.sos[0] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace * self.subspace)) % self.subspace;
+
+         }
+         if (iteration % 10000000 === 0) {
+             //        console.log((iteration/1000000).toFixed(0)+"m", ioa,"::", self.sos.join(" "));        
+
+             self.emit("status", (iteration / (self.space / 100)).toFixed(2), self.sos.join(" ") )
+ 
+
+         }
+
+         iteration++;
+     }
+
+     if (sat) {
+         console.log("SOLUTION FOUND");
+     }
+
+     var tt = self.rulas.map(function(t) {
+         return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+     })
+     console.log(iteration, io, ioa, self.sos.join(" "), tt.map(function(a) {
+         return a.join(" ")
+     }));
+     self.printit()
+
+
+ }
+
+
+ mo.prototype.printit = function() {
+     var lpad = function(s, l) {
+         while (s.length < l) {
+             s = " " + s
+         };
+         return s;
+     }
+     var rpad = function(s, l) {
+         while (s.length < l) {
+             s = s + " "
+         };
+         return s;
+     }
+     var self = this;
+
+     var s = [];
+     s.push([" ", 1, 2, 3, 4, 5].map(function(a) {
+         return lpad("" + a, 12)
+     }).join(" "));
+
+
+     Object.keys(self.variabler).map(function(k, ia) {
+
+         s.push([k, 0, 1, 2, 3, 4].map(function(a, io) {
+             return a == k ? rpad(k + ":" + self.sos[ia], 20) : lpad("" + self.variabler[k][self.current[self.sos[ia]][a]], 12)
+         }).join(" "))
+
+         //            s.push( )
+     })
+     console.log(s.join("\n") + "\n")
+ }
+
+ mo.prototype.stats = function() {
+     console.log("steps ", this._internal_step_counter)
+     console.log(this);
+ }
+
+ var t = new mo()
+     .addVariabelSet("Nationality", ["Norwegian", "Dane", "Englishman", "German","Swede"])
+     .addVariabelSet("Color", ["Red","Green", "White", "Yellow", "Blue" ])
+     .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
+     .addVariabelSet("Drinks", ["Water", "Bier", "Milk", "Tea", "Coffee"])
+     .addVariabelSet("Animals", ["Dogs", "Birds", "Cats", "Horses", "Fish"])
+     .addVariableTable("House", [0, 1, 2, 3, 4])
+     .addFunction("Neighbor", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkBoth", propid1, propid2, valid1, valid2, [prop1, val1, "Besides", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_Before", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_Before"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkLeft", propid1, propid2, valid1, valid2, [prop1, val1, "Before", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_After", function() {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_After"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkRight", propid1, propid2, valid1, valid2, [prop1, val1, "After", prop2, val2].join(" ")]
+     })
+     .addFunction("House", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = prop1
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var val1 = arg[prop1];
+         var val2 = arg["House"];
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         return ['checkn', propid1, propid1, valid1, val2, [prop1, val1, "House", val2].join(" ")]
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "House": 0
+     })
+     .addClause({
+         "Drinks": "Milk",
+         "House": 2
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "Neighbor": {
+             "Color": "Blue"
+         }
+     })
+     .addClause({
+         "Nationality": "Englishman",
+         "Color": "Red"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Drinks": "Water"
+         }
+     })
+     .addClause({
+         "Nationality": "Swede",
+         "Animals": "Dogs"
+     })
+     .addClause({
+         "Nationality": "Dane",
+         "Drinks": "Tea"
+     })
+     .addClause({
+         "Color": "Green",
+         "Neighbor_Before": {
+             "Color": "White"
+         }
+     })
+     .addClause({
+         "Color": "Green",
+         "Drinks": "Coffee"
+     })
+     .addClause({
+         "Smokes": "PallMall",
+         "Animals": "Birds"
+     })
+     .addClause({
+         "Color": "Yellow",
+         "Smokes": "Dunhill"
+     })
+     .addClause({
+         "Nationality": "German",
+         "Smokes": "Prince"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Animals": "Cats"
+         }
+     })
+     .addClause({
+         "Animals": "Horses",
+         "Neighbor": {
+             "Smokes": "Dunhill"
+         }
+     })
+     .addClause({
+         "Smokes": "BlueMasters",
+         "Drinks": "Bier"
+     })
+
+
+ /*  .addClause("$House('Nationality','Norwegian')","eq","$House().first")
+    .addClause("$House('Drinks','Milk')","eq","$House().mid")
+    .addClause("$House('Nationality','Englishman')","eq","$House('Color','Red')")
+    .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
+   */
+ /*.addClause(0,"Norwegian",-1,-1,-1,-1)
+    .addClause(2,-1,-1,-1,"Milk",-1)
+    .addClause(-1,"Englishman","Red",-1,-1,-1,-1)
+    .addClause(-1,"N Norwegian","Blue",-1,-1,-1,-1)
+
+    .addClause("Math.abs($House('Nationality','Norwegian') - $House('Color','Blue'))===1")
+    .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
+    .addClause("$House('Nationality','Swede')===$House('Animals','Dogs')")
+    .addClause("$House('Nationality','Dane')===$House('Drinks','Tea')")
+    .addClause("($House('Color','Green')+1)===$House('Color','White')")
+    .addClause("$House('Color','Green')===$House('Drinks','Coffee')")
+    .addClause("$House('Smokes','PallMall')===$House('Animals','Birds')")
+    .addClause("$House('Color','Yellow')===$House('Smokes','Dunhill')")
+    .addClause("Math.abs($House('Smokes','Blend')-$House('Animals','Cats'))===1")
+    .addClause("$House('Smokes','BlueMasters')===$House('Drinks','Bier')")
+    //.addClause("Math.abs($House('Animals','Horses')-$House('Smokes','Dunhill'))===1")
+    //.addClause("$House('Nationality','German')===$House('Smokes','Prince')")
+*/
+
+
+ /*
+    The Englishman lives in the red house.<br>
+    The Swede keeps dogs.<br>
+    The Dane drinks tea.<br>
+    The green house is just to the left of the white one.<br>
+    The owner of the green house drinks coffee.<br>
+    The Pall Mall smoker keeps birds.<br>
+    The owner of the yellow house smokes Dunhills.<br>
+    The man in the center house drinks milk.<br>
+    The Norwegian lives in the first house.<br>
+    The Blend smoker has a neighbor who keeps cats.<br>
+    The man who smokes Blue Masters drinks bier.<br>
+    The man who keeps horses lives next to the Dunhill smoker.<br>
+    The German smokes Prince.<br>
+    The Norwegian lives next to the blue house.<br>
+    The Blend smoker has a neighbor who drinks water.<br>
+*/
+
+
+ //console.log(t.randoma("House"));
+ //t.stats();
+
+
+
+ t.on("status", function(per, found) {
+
+     console.log("PER", per, found);
+ })
+
+ t.solve();
+
+ /*
+var Colors = ["Red", "White", "Yellow", "Blue", "Green"],
+    Nationality = ["Norwegian", "Dane", "Swede", "Englishman", "German"],
+    Cigarettes = ["Prince", "Blend", "Dunhill", "Blue Masters", "Pall Mall"],
+    Drinks = ["Water", "Bier", "Milk", "Tea", "Coffee"],
+    Animals = ["Dogs", "Birds", "Cat", "Horses", "Fish"];*/

+ 761 - 0
ein_work2.js

@@ -0,0 +1,761 @@
+ function EV() {
+     this.__e = {};
+ }
+ EV.prototype.__e = {};
+ EV.prototype.emit = function(n) {
+     var that = this;
+     var args = [].slice.apply(arguments, [1]);
+     (this.__e[n] || []).map(function(lis) {
+         lis.map(function(fn) {
+             fn.apply(that, args)
+         })
+     })
+     return this;
+ }
+ EV.prototype.on = function(n) {
+     var args = [].slice.apply(arguments, [1]);
+     this.__e[n] = this.__e[n] || [];
+     this.__e[n].push(args);
+     return this;
+ }
+
+ function inherits(ctor, superCtor) {
+     var Obj = function() {};
+     Obj.prototype = superCtor.prototype;
+     ctor.prototype = new Obj
+ }
+
+
+ function permutates(xs) {
+     var ret = [];
+
+     for (var i = 0; i < xs.length; i = i + 1) {
+         var rest = permutates(xs.slice(0, i).concat(xs.slice(i + 1)));
+
+         if (!rest.length) {
+             ret.push([xs[i]])
+         } else {
+             for (var j = 0; j < rest.length; j = j + 1) {
+                 ret.push([xs[i]].concat(rest[j]))
+             }
+         }
+     }
+     return ret;
+ }
+
+
+ function mo() {
+     this.variabler = {};
+     this.tabel = {};
+     this.tableHead = [];
+     this.tableName = "";
+     this.regler = [];
+     this._internal_step_counter = 0;
+     this.rmat = [];
+     this.funcs = {};
+     this.rulas = [];
+ }
+ inherits(mo, EV)
+
+ mo.prototype.addVariabelSet = function(navn, arr) {
+     this.variabler[navn] = arr;
+     return this;
+ }
+ mo.prototype.addVariableTable = function(navn, arr) {
+     this.tableHead = arr;
+     this.tableName = navn;
+     return this;
+ }
+ mo.prototype.addFunction = function(name, func) {
+     this.funcs[name] = func;
+     return this;
+ }
+ mo.prototype.addClause = function() {
+     var args = Array.prototype.slice.apply(arguments, []);
+     while (args.length) {
+         var arg = args.shift();
+
+         var props = Object.keys(arg);
+         var propid1, propid2;
+
+         if (this.variabler[props[0]]) {
+             propid1 = Object.keys(this.variabler).indexOf(props[0]);
+         }
+         if (this.variabler[props[1]]) {
+             propid2 = Object.keys(this.variabler).indexOf(props[1]);
+         } else {}
+         var arr = []
+         if (propid1 > -1 && propid2 > -1) {
+             val1 = this.variabler[props[0]].indexOf(arg[props[0]])
+             val2 = this.variabler[props[1]].indexOf(arg[props[1]])
+             arr = ["check", propid1, propid2, val1, val2, [props[0], arg[props[0]], props[1], arg[props[1]]].join(" ")];
+         } else {
+             var lookfor = props[props.length - 1];
+             if (this.funcs[lookfor]) {
+                 arr = this.funcs[lookfor].apply(this, [arg])
+             }
+         }
+     }
+     this.rulas.push(arr);
+     return this;
+ }
+
+ mo.prototype.build = function(tabl) {
+     var r = [];
+     var arr = [];
+     var pertable = []
+
+     for (var navn in this.variabler) {
+         pertable.push(permutates((this.variabler[navn]).map(function(a, i) {
+             return i
+         })));
+     }
+
+     return pertable;
+ }
+
+ mo.prototype.checkn = function(prop1, prop2, val1, val2) {
+
+     return this.current[this.sos[prop1]][val1] == val2
+
+ }
+
+ mo.prototype.check = function(prop1, prop2, val1, val2) {
+     var i;
+     //   console.log(prop1,this.sos[prop1], prop2, this.current[this.sos[prop1]],this.current[this.sos[prop2]],val1,val2)
+     for (i = 0; i < 5; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             //         console.log("II,",i,this.current[this.sos[prop1]][i],"=",val1,"&", this.current[this.sos[prop2]][i],"=",val2 );
+             var p;
+             p = (this.current[this.sos[prop2]][i] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+ mo.prototype.checkLeft = function(prop1, prop2, val1, val2) {
+     var i;
+     for (i = 0; i < 4; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             var p;
+             p = (this.current[this.sos[prop2]][i + 1] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+ mo.prototype.checkRight = function(prop1, prop2, val1, val2) {
+     var i;
+     for (i = 1; i < 5; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             var p;
+             p = (this.current[this.sos[prop2]][i - 1] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+
+ mo.prototype.checkBoth = function(prop1, prop2, val1, val2) {
+
+     return this.checkLeft(prop1, prop2, val1, val2) || this.checkRight(prop1, prop2, val1, val2)
+ }
+
+ function intersection() {
+     var result = [];
+     var lists;
+
+     if (arguments.length === 1) {
+         lists = arguments[0];
+     } else {
+         lists = arguments;
+     }
+
+     for (var i = 0; i < lists.length; i++) {
+         var currentList = lists[i];
+         for (var y = 0; y < currentList.length; y++) {
+             var currentValue = currentList[y];
+             if (result.indexOf(currentValue) === -1) {
+                 var existsInAll = true;
+                 for (var x = 0; x < lists.length; x++) {
+                     if (lists[x].indexOf(currentValue) === -1) {
+                         existsInAll = false;
+                         break;
+                     }
+                 }
+                 if (existsInAll) {
+                     result.push(currentValue);
+                 }
+             }
+         }
+     }
+     return result;
+ }
+ mo.prototype.solve = function() {
+     var self = this;
+     self.current = this.build("House").shift();
+     var sa = Object.keys(this.variabler);
+     self.sos = sa.map(function(a) {
+         return 0; //self.current.length - 1; //Math.floor(Math.random()*self.current.length-1);
+     })
+     self.subspace = self.current.length;
+     self.varspace = sa.length;
+     self.space = Math.pow(self.subspace, self.varspace - 1);
+
+
+     var iteration = 0;
+     var maxi = 0;
+     var ioa = -1;
+
+     var soso = [];
+
+     var sat = false;
+
+
+     self.rulas = self.rulas; //slice(0, 9);
+
+
+     /*     self.rulas.sort(function(a, b) {
+         return a[1] > b[1] ? -1 : a[1] < b[1] ? 1 : a[2] > b[2] ? 1 : a[2] < b[2] ? -1 : 0
+     })
+*/
+     //    console.log(self.rulas);
+
+
+     //  return false;
+
+
+     // først find variabler som bruges i samme opslag.
+     var tas = {}
+     var firsta = [];
+     self.rulas.map(function(ru) {
+         console.log(ru);
+         if (ru[1] == ru[2]) {
+             firsta.push(ru);
+         }
+     })
+
+     self.sos = self.sos.map(function(a) {
+         return 0
+     })
+
+     var osa = -1
+     console.log(firsta);
+
+     var cands = [];
+
+
+     for (var x = 0; x < firsta.length; x++) {
+         self.sos = self.sos.map(function(a) {
+             return 0
+         })
+
+         var t = firsta[x];
+         var ca = [];
+         for (var i = 0; i < self.subspace; i++) {
+             var ff = false;
+             self.sos[t[1]] = i
+             ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+             if (ff) {
+                 ca.push(i);
+             }
+         }
+         cands.push([t[1], ca]);
+     }
+
+     console.log(cands);
+
+     //   var inta=intersection.apply(this,cands.map(function(a){ return a[1]}));
+     self.sos = self.sos.map(function(a) {
+         return 0
+     })
+
+
+     var cc = cands.length;
+     var ticks = [0, 0, 0, 0, 0];
+     var ic = 0;
+     var iomax = self.rulas.length;
+     var ioa = 0;
+
+     for (var i0 = 0; i0 < cands[0][1].length; i0++) {
+         if (cands[1]) {
+
+             for (var i1 = 0; i1 < cands[1][1].length; i1++) {
+                 if (cands[2]) {
+
+                     for (var i2 = 0; i2 < cands[2][1].length; i2++) {
+                         if (cands[3]) {
+
+                         } else {
+                             var st = [0, 1, 2, 3, 4]
+                             self.sos[cands[0][0]] = cands[0][1][i0]
+                             self.sos[cands[1][0]] = cands[1][1][i1]
+                             self.sos[cands[2][0]] = cands[2][1][i2]
+
+                             st.splice(st.indexOf(cands[0][0]), 1);
+                             st.splice(st.indexOf(cands[1][0]), 1);
+                             st.splice(st.indexOf(cands[2][0]), 1);
+                             for (var i3 = 0; i3 < self.subspace; i3++) {
+                                 for (var i4 = 0; i4 < self.subspace; i4++) {
+                                     ic++
+                                     self.sos[st[0]] = i3
+                                     self.sos[st[1]] = i4
+                                     var io = 0;
+                                     var ff = true;
+                                     while (io < iomax && ff) {
+                                         ff = false;
+                                         var t = self.rulas[io];
+                                         ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                                         if (ff) {
+                                             io++;
+                                         }
+                                     }
+                                     if (io > ioa) {
+                                         ioa = io;
+                                         var tt = self.rulas.map(function(t) {
+                                             return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                                         })
+                                         self.emit("part", ic, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                                             return a.join(" ")
+                                         }))
+                                     }
+                                     if (ioa >= iomax) {
+                                         return self.sos;
+                                     }
+                                     if (ic % 1000000 === 0) {
+                                         console.log("X2", ic, io, ioa, iomax, self.sos[cands[0][0]], self.sos[cands[1][0]], self.sos[cands[2][0]], i3, i4);
+                                     }
+                                 }
+                             }
+                         }
+                     }
+                 } else {
+
+
+                     var st = [0, 1, 2, 3, 4]
+                     self.sos[cands[0][0]] = cands[0][1][i0]
+                     self.sos[cands[1][0]] = cands[1][1][i1]
+                     //                           self.sos[cands[2][0]] = cands[2][1][i2]
+
+                     st.splice(st.indexOf(cands[0][0]), 1);
+                     st.splice(st.indexOf(cands[1][0]), 1);
+                     //                             st.splice(st.indexOf(cands[2][0]), 1);
+
+                     for (var i2 = 0; i2 < self.subspace; i2++) {
+                         for (var i3 = 0; i3 < self.subspace; i3++) {
+                             for (var i4 = 0; i4 < self.subspace; i4++) {
+                                 ic++
+                                 self.sos[st[0]] = i2
+                                 self.sos[st[1]] = i3
+                                 self.sos[st[2]] = i4
+                                 var io = 0;
+                                 var ff = true;
+                                 while (io < iomax && ff) {
+                                     ff = false;
+                                     var t = self.rulas[io];
+                                     ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                                     if (ff) {
+                                         io++;
+                                     }
+                                 }
+                                 if (io > ioa) {
+                                     ioa = io;
+                                     var tt = self.rulas.map(function(t) {
+                                         return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                                     })
+                                     self.emit("part", ic, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                                         return a.join(" ")
+                                     }))
+                                 }
+                                 if (ioa >= iomax) {
+                                     return self.sos;
+                                 }
+                                 if (ic % 1000000 === 0) {
+                                     console.log("X3", ic, io, ioa, iomax, ":>", self.sos[cands[0][0]], self.sos[cands[1][0]], i2, i3, i4);
+                                 }
+                             }
+                         }
+
+                     }
+
+
+
+
+
+
+
+                 }
+
+             }
+
+
+         }
+
+     }
+
+
+
+     return false;
+
+     //     console.log("II",inta);
+
+
+
+
+     /* for (var i = 0; i < self.subspace; i++) {
+         self.sos[0] = i;
+         var mio = 0;
+         var ff = true;
+         var iomax = 1; // firsta.length;
+         while (mio < iomax && ff) {
+             var t = firsta[mio];
+             ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+             if (ff) {
+                 mio++;
+             }
+         }
+         if (mio > 0) {
+             cands.push(i);
+         } else {}
+     }
+     self.sos[0] = 0;
+*/
+
+
+     //cands = [105,81]
+
+
+     var iomax = self.rulas.length;
+
+     while (!sat && cands.length > 0) {
+         var cand1 = cands.shift();
+         self.sos[0] = cand1;
+         iteration = 0;
+
+         while (!sat && iteration < self.space) {
+             var io = 0;
+             var ff = true;
+             while (io < iomax && ff) {
+                 var t = self.rulas[io];
+                 ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                 if (ff) {
+                     io++;
+                 }
+             }
+             if (io > ioa) {
+                 soso.push([].concat(self.sos));
+                 ioa = io;
+                 var tt = self.rulas.map(function(t) {
+                     return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                 })
+                 console.log(iteration, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                     return a.join(" ")
+                 }));
+             }
+             if (io >= iomax) {
+                 sat = true;
+                 //            console.log((iteration).toFixed(0) + " ", ioa, "::", self.sos.join(" "), soso.join(" | "));
+             } else {
+                 self.sos[1] = iteration % self.subspace;
+                 self.sos[2] = Math.floor(iteration / self.subspace) % self.subspace;
+                 self.sos[3] = Math.floor(iteration / (self.subspace * self.subspace)) % self.subspace;
+                 self.sos[4] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace)) % self.subspace;
+                 //             self.sos[0] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace * self.subspace)) % self.subspace;
+             }
+             if (iteration % 10000000 === 0) {
+                 self.emit("status", (iteration / (self.space / 100)).toFixed(2), ioa + ":: " + cands.length + ":: " + self.sos.join(" "))
+             }
+
+             // console.log(iteration, self.sos.join(" "));
+             iteration++;
+         }
+
+
+
+     }
+
+
+
+
+
+
+     /*     while (!sat && iteration < self.space) {
+
+         var io = 0;
+         var ff = true;
+         while (io < iomax && ff) {
+             var t = self.rulas[io];
+             ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+             if (ff) {
+                 io++;
+             }
+         }
+         if (io > ioa) {
+             soso.push([].concat(self.sos));
+             ioa = io;
+             var tt = self.rulas.map(function(t) {
+                 return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+             })
+             console.log(iteration, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                 return a.join(" ")
+             }));
+         }
+         if (io >= iomax) {
+             sat = true;
+             //            console.log((iteration).toFixed(0) + " ", ioa, "::", self.sos.join(" "), soso.join(" | "));
+         } else {
+             self.sos[4] = iteration % self.subspace;
+             self.sos[1] = Math.floor(iteration / self.subspace) % self.subspace;
+             self.sos[2] = Math.floor(iteration / (self.subspace * self.subspace)) % self.subspace;
+             self.sos[3] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace)) % self.subspace;
+             self.sos[0] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace * self.subspace)) % self.subspace;
+         }
+         if (iteration % 10000000 === 0) {
+             self.emit("status", (iteration / (self.space / 100)).toFixed(2), self.sos.join(" "))
+         }
+         iteration++;
+     }*/
+
+     if (sat) {
+         console.log("SOLUTION FOUND");
+     }
+
+     var tt = self.rulas.map(function(t) {
+         return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+     })
+     console.log(iteration, self.sos.join(" "), tt.map(function(a) {
+         return a.join(" ")
+     }));
+     self.printit()
+
+
+ }
+
+
+ mo.prototype.printit = function(vals) {
+     var self = this;
+     var vals = vals || self.sos;
+     var lpad = function(s, l) {
+         while (s.length < l) {
+             s = " " + s
+         };
+         return s;
+     }
+     var rpad = function(s, l) {
+         while (s.length < l) {
+             s = s + " "
+         };
+         return s;
+     }
+
+     var s = [];
+     s.push([" ", 1, 2, 3, 4, 5].map(function(a) {
+         return lpad("" + a, 12)
+     }).join(" "));
+
+
+     Object.keys(self.variabler).map(function(k, ia) {
+
+         s.push([k, 0, 1, 2, 3, 4].map(function(a, io) {
+             return a == k ? rpad(k + ":" + vals[ia], 20) : lpad("" + self.variabler[k][self.current[vals[ia]][a]], 12)
+         }).join(" "))
+
+         //            s.push( )
+     })
+     console.log(s.join("\n") + "\n")
+ }
+
+ mo.prototype.stats = function() {
+     console.log("steps ", this._internal_step_counter)
+     console.log(this);
+ }
+
+
+ var t = new mo()
+     .addVariabelSet("Nationality", ["Norwegian","Dane",  "Swede", "Englishman", "German"])
+     .addVariabelSet("Color", ["Red", "White", "Yellow", "Blue", "Green"])
+     .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
+     .addVariabelSet("Drinks", [ "Bier","Water", "Coffee","Milk", "Tea" ])
+     .addVariabelSet("Animals", ["Dogs", "Birds", "Cats", "Horses", "Fish"])
+     .addVariableTable("House", [0, 1, 2, 3, 4])
+     .addFunction("Neighbor", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkBoth", propid1, propid2, valid1, valid2, [prop1, val1, "Besides", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_Before", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_Before"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkLeft", propid1, propid2, valid1, valid2, [prop1, val1, "Before", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_After", function() {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_After"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkRight", propid1, propid2, valid1, valid2, [prop1, val1, "After", prop2, val2].join(" ")]
+     })
+     .addFunction("House", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = prop1
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var val1 = arg[prop1];
+         var val2 = arg["House"];
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         return ['checkn', propid1, propid1, valid1, val2, [prop1, val1, "House", val2].join(" ")]
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "House": 0
+     })
+     .addClause({
+         "Drinks": "Milk",
+         "House": 2
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "Neighbor": {
+             "Color": "Blue"
+         }
+     })
+     .addClause({
+         "Nationality": "Englishman",
+         "Color": "Red"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Drinks": "Water"
+         }
+     })
+     .addClause({
+         "Nationality": "Swede",
+         "Animals": "Dogs"
+     })
+     .addClause({
+         "Nationality": "Dane",
+         "Drinks": "Tea"
+     })
+     .addClause({
+         "Color": "Green",
+         "Drinks": "Coffee"
+     })
+     .addClause({
+         "Smokes": "PallMall",
+         "Animals": "Birds"
+     })
+     .addClause({
+         "Color": "Yellow",
+         "Smokes": "Dunhill"
+     })
+     .addClause({
+         "Nationality": "German",
+         "Smokes": "Prince"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Animals": "Cats"
+         }
+     })
+     .addClause({
+         "Animals": "Horses",
+         "Neighbor": {
+             "Smokes": "Dunhill"
+         }
+     })
+     .addClause({
+         "Smokes": "BlueMasters",
+         "Drinks": "Bier"
+     })
+     .addClause({
+         "Color": "Green",
+         "Neighbor_Before": {
+             "Color": "White"
+         }
+     })
+
+
+ /*  .addClause("$House('Nationality','Norwegian')","eq","$House().first")
+    .addClause("$House('Drinks','Milk')","eq","$House().mid")
+    .addClause("$House('Nationality','Englishman')","eq","$House('Color','Red')")
+    .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
+   */
+ /*.addClause(0,"Norwegian",-1,-1,-1,-1)
+    .addClause(2,-1,-1,-1,"Milk",-1)
+    .addClause(-1,"Englishman","Red",-1,-1,-1,-1)
+    .addClause(-1,"N Norwegian","Blue",-1,-1,-1,-1)
+
+    .addClause("Math.abs($House('Nationality','Norwegian') - $House('Color','Blue'))===1")
+    .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
+    .addClause("$House('Nationality','Swede')===$House('Animals','Dogs')")
+    .addClause("$House('Nationality','Dane')===$House('Drinks','Tea')")
+    .addClause("($House('Color','Green')+1)===$House('Color','White')")
+    .addClause("$House('Color','Green')===$House('Drinks','Coffee')")
+    .addClause("$House('Smokes','PallMall')===$House('Animals','Birds')")
+    .addClause("$House('Color','Yellow')===$House('Smokes','Dunhill')")
+    .addClause("Math.abs($House('Smokes','Blend')-$House('Animals','Cats'))===1")
+    .addClause("$House('Smokes','BlueMasters')===$House('Drinks','Bier')")
+    //.addClause("Math.abs($House('Animals','Horses')-$House('Smokes','Dunhill'))===1")
+    //.addClause("$House('Nationality','German')===$House('Smokes','Prince')")
+*/
+
+
+ /*
+    The Englishman lives in the red house.<br>
+    The Swede keeps dogs.<br>
+    The Dane drinks tea.<br>
+    The green house is just to the left of the white one.<br>
+    The owner of the green house drinks coffee.<br>
+    The Pall Mall smoker keeps birds.<br>
+    The owner of the yellow house smokes Dunhills.<br>
+    The man in the center house drinks milk.<br>
+    The Norwegian lives in the first house.<br>
+    The Blend smoker has a neighbor who keeps cats.<br>
+    The man who smokes Blue Masters drinks bier.<br>
+    The man who keeps horses lives next to the Dunhill smoker.<br>
+    The German smokes Prince.<br>
+    The Norwegian lives next to the blue house.<br>
+    The Blend smoker has a neighbor who drinks water.<br>
+*/
+
+
+ //console.log(t.randoma("House"));
+ //t.stats();
+
+
+
+ t.on("status", function(per, found) {
+     console.log("PER", per, found);
+ })
+
+ t.on("part", function() {
+     console.log("PART", arguments);
+ })
+
+
+ var result = t.solve();
+ console.log(t.printit(result));
+
+ /*
+var Colors = ["Red", "White", "Yellow", "Blue", "Green"],
+    Nationality = ["Norwegian", "Dane", "Swede", "Englishman", "German"],
+    Cigarettes = ["Prince", "Blend", "Dunhill", "Blue Masters", "Pall Mall"],
+    Drinks = ["Water", "Bier", "Milk", "Tea", "Coffee"],
+    Animals = ["Dogs", "Birds", "Cat", "Horses", "Fish"];*/

+ 725 - 0
einwork.js

@@ -0,0 +1,725 @@
+ function EV() {
+     this.__e = {};
+ }
+ EV.prototype.__e = {};
+ EV.prototype.emit = function(n) {
+     var that = this;
+     var args = [].slice.apply(arguments, [1]);
+     (this.__e[n] || []).map(function(lis) {
+         lis.map(function(fn) {
+             fn.apply(that, args)
+         })
+     })
+     return this;
+ }
+ EV.prototype.on = function(n) {
+     var args = [].slice.apply(arguments, [1]);
+     this.__e[n] = this.__e[n] || [];
+     this.__e[n].push(args);
+     return this;
+ }
+
+ function inherits(ctor, superCtor) {
+     var Obj = function() {};
+     Obj.prototype = superCtor.prototype;
+     ctor.prototype = new Obj
+ }
+
+
+ function permutates(xs) {
+     var ret = [];
+
+     for (var i = 0; i < xs.length; i = i + 1) {
+         var rest = permutates(xs.slice(0, i).concat(xs.slice(i + 1)));
+
+         if (!rest.length) {
+             ret.push([xs[i]])
+         } else {
+             for (var j = 0; j < rest.length; j = j + 1) {
+                 ret.push([xs[i]].concat(rest[j]))
+             }
+         }
+     }
+     return ret;
+ }
+
+
+ function mo() {
+     this.variabler = {};
+     this.tabel = {};
+     this.tableHead = [];
+     this.tableName = "";
+     this.regler = [];
+     this._internal_step_counter = 0;
+     this.rmat = [];
+     this.funcs = {};
+     this.rulas = [];
+ }
+ inherits(mo, EV)
+
+ mo.prototype.addVariabelSet = function(navn, arr) {
+     this.variabler[navn] = arr;
+     return this;
+ }
+ mo.prototype.addVariableTable = function(navn, arr) {
+     this.tableHead = arr;
+     this.tableName = navn;
+     return this;
+ }
+ mo.prototype.addFunction = function(name, func) {
+     this.funcs[name] = func;
+     return this;
+ }
+ mo.prototype.addClause = function() {
+     var args = Array.prototype.slice.apply(arguments, []);
+     while (args.length) {
+         var arg = args.shift();
+
+         var props = Object.keys(arg);
+         var propid1, propid2;
+
+         if (this.variabler[props[0]]) {
+             propid1 = Object.keys(this.variabler).indexOf(props[0]);
+         }
+         if (this.variabler[props[1]]) {
+             propid2 = Object.keys(this.variabler).indexOf(props[1]);
+         } else {}
+         var arr = []
+         if (propid1 > -1 && propid2 > -1) {
+             val1 = this.variabler[props[0]].indexOf(arg[props[0]])
+             val2 = this.variabler[props[1]].indexOf(arg[props[1]])
+             arr = ["check", propid1, propid2, val1, val2, [props[0], arg[props[0]], props[1], arg[props[1]]].join(" ")];
+         } else {
+             var lookfor = props[props.length - 1];
+             if (this.funcs[lookfor]) {
+                 arr = this.funcs[lookfor].apply(this, [arg])
+             }
+         }
+     }
+     this.rulas.push(arr);
+     return this;
+ }
+
+ mo.prototype.build = function(tabl) {
+     var r = [];
+     var arr = [];
+     var pertable = []
+
+     for (var navn in this.variabler) {
+         pertable.push(permutates((this.variabler[navn]).map(function(a, i) {
+             return i
+         })));
+     }
+
+     return pertable;
+ }
+
+ mo.prototype.checkn = function(prop1, prop2, val1, val2) {
+
+     return this.current[this.sos[prop1]][val1] == val2
+
+ }
+
+ mo.prototype.check = function(prop1, prop2, val1, val2) {
+     var i;
+     //   console.log(prop1,this.sos[prop1], prop2, this.current[this.sos[prop1]],this.current[this.sos[prop2]],val1,val2)
+     for (i = 0; i < 5; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             //         console.log("II,",i,this.current[this.sos[prop1]][i],"=",val1,"&", this.current[this.sos[prop2]][i],"=",val2 );
+             var p;
+             p = (this.current[this.sos[prop2]][i] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+ mo.prototype.checkLeft = function(prop1, prop2, val1, val2) {
+     var i;
+     for (i = 0; i < 4; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             var p;
+             p = (this.current[this.sos[prop2]][i + 1] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+ mo.prototype.checkRight = function(prop1, prop2, val1, val2) {
+     var i;
+     for (i = 1; i < 5; i++) {
+         if (this.current[this.sos[prop1]][i] == val1) {
+             var p;
+             p = (this.current[this.sos[prop2]][i - 1] == val2)
+             return p;
+         }
+     }
+     return false;
+ }
+
+ mo.prototype.checkBoth = function(prop1, prop2, val1, val2) {
+
+     return this.checkLeft(prop1, prop2, val1, val2) || this.checkRight(prop1, prop2, val1, val2)
+ }
+
+ function intersection() {
+     var result = [];
+     var lists;
+
+     if (arguments.length === 1) {
+         lists = arguments[0];
+     } else {
+         lists = arguments;
+     }
+
+     for (var i = 0; i < lists.length; i++) {
+         var currentList = lists[i];
+         for (var y = 0; y < currentList.length; y++) {
+             var currentValue = currentList[y];
+             if (result.indexOf(currentValue) === -1) {
+                 var existsInAll = true;
+                 for (var x = 0; x < lists.length; x++) {
+                     if (lists[x].indexOf(currentValue) === -1) {
+                         existsInAll = false;
+                         break;
+                     }
+                 }
+                 if (existsInAll) {
+                     result.push(currentValue);
+                 }
+             }
+         }
+     }
+     return result;
+ }
+ mo.prototype.solve = function() {
+     var self = this;
+     self.current = this.build("House").shift();
+     var sa = Object.keys(this.variabler);
+     self.sos = sa.map(function(a) {
+         return 0; //self.current.length - 1; //Math.floor(Math.random()*self.current.length-1);
+     })
+     self.subspace = self.current.length;
+     self.varspace = sa.length;
+     self.space = Math.pow(self.subspace, self.varspace - 1);
+
+
+     var iteration = 0;
+     var maxi = 0;
+     var ioa = -1;
+
+     var soso = [];
+
+     var sat = false;
+
+
+     self.rulas = self.rulas; //slice(0, 9);
+
+
+     /*     self.rulas.sort(function(a, b) {
+         return a[1] > b[1] ? -1 : a[1] < b[1] ? 1 : a[2] > b[2] ? 1 : a[2] < b[2] ? -1 : 0
+     })
+*/
+     //    console.log(self.rulas);
+
+
+     //  return false;
+
+
+     // først find variabler som bruges i samme opslag.
+     var tas = {}
+     var firsta = [];
+     self.rulas.map(function(ru) {
+        console.log(ru);
+         if (ru[1] == ru[2]) {
+             firsta.push(ru);
+         }
+     })
+
+     self.sos = self.sos.map(function(a) {
+         return 0
+     })
+
+     var osa = -1
+     console.log(firsta);
+
+     var cands = [];
+
+ 
+     for (var x = 0; x < firsta.length; x++) {
+         self.sos = self.sos.map(function(a) {
+             return 0
+         })
+
+         var t = firsta[x];
+         var ca = [];
+         for (var i = 0; i < self.subspace; i++) {
+             var ff = false;
+             self.sos[t[1]] = i
+             console.log(self.sos);
+             ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+             if (ff) {
+                 ca.push(i);
+             }
+         }
+         cands.push([t[1], ca]);
+     }
+
+     console.log(cands);
+
+     //   var inta=intersection.apply(this,cands.map(function(a){ return a[1]}));
+     self.sos = self.sos.map(function(a) {
+         return 0
+     })
+
+
+     var cc = cands.length;
+     var ticks = [0, 0, 0, 0, 0];
+     var ic = 0;
+     var iomax = self.rulas.length;
+     var ioa = 0;
+
+     for (var i0 = 0; i0 < cands[0][1].length; i0++) {
+         if (cands[1]) {
+
+             for (var i1 = 0; i1 < cands[1][1].length; i1++) {
+                 if (cands[2]) {
+
+                     for (var i2 = 0; i2 < cands[2][1].length; i2++) {
+                         if (cands[3]) {
+
+                         } else {
+                             var st = [0, 1, 2, 3, 4]
+                             self.sos[cands[0][0]] = cands[0][1][i0]
+                             self.sos[cands[1][0]] = cands[1][1][i1]
+                             self.sos[cands[2][0]] = cands[2][1][i2]
+
+                             st.splice(st.indexOf(cands[0][0]), 1);
+                             st.splice(st.indexOf(cands[1][0]), 1);
+                             st.splice(st.indexOf(cands[2][0]), 1);
+
+                             for (var i3 = 0; i3 < 120; i3++) {
+
+                                 for (var i4 = 0; i4 < 120; i4++) {
+                                     ic++
+
+                                     self.sos[st[0]] = i3
+                                     self.sos[st[1]] = i4
+
+
+                                     var io = 0;
+                                     var ff = true;
+                                     while (io < iomax && ff) {
+                                         ff = false;
+                                         var t = self.rulas[io];
+                                         ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                                         if (ff) {
+                                             io++;
+                                         }
+                                     }
+
+                                     if (io > ioa) {
+                                         // soso.push([].concat(self.sos));
+                                         ioa = io;
+                                         var tt = self.rulas.map(function(t) {
+                                             return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                                         })
+                                         console.log(ic, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                                             return a.join(" ")
+                                         }));
+                                     }
+
+                                     if(ioa >= iomax){
+                                        return self.sos;
+
+                                     }
+
+                                     if(ic % 1000000 === 0){
+
+                                    console.log("X", ic, io,ioa,iomax, self.sos[cands[0][0]], self.sos[cands[1][0]], self.sos[cands[2][0]], i3, i4);
+                                     }
+
+                                 }
+
+
+                             }
+
+
+
+
+                         }
+                     }
+                 } else {
+                     console.log(cands[0][1][i1], cands[1][1][i2])
+
+                 }
+
+             }
+
+
+         }
+
+     }
+
+
+
+     return false;
+
+     //     console.log("II",inta);
+
+
+
+
+     /* for (var i = 0; i < self.subspace; i++) {
+         self.sos[0] = i;
+         var mio = 0;
+         var ff = true;
+         var iomax = 1; // firsta.length;
+         while (mio < iomax && ff) {
+             var t = firsta[mio];
+             ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+             if (ff) {
+                 mio++;
+             }
+         }
+         if (mio > 0) {
+             cands.push(i);
+         } else {}
+     }
+     self.sos[0] = 0;
+*/
+
+
+     //cands = [105,81]
+
+
+     var iomax = self.rulas.length;
+
+     while (!sat && cands.length > 0) {
+         var cand1 = cands.shift();
+         self.sos[0] = cand1;
+         iteration = 0;
+
+         while (!sat && iteration < self.space) {
+             var io = 0;
+             var ff = true;
+             while (io < iomax && ff) {
+                 var t = self.rulas[io];
+                 ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                 if (ff) {
+                     io++;
+                 }
+             }
+             if (io > ioa) {
+                 soso.push([].concat(self.sos));
+                 ioa = io;
+                 var tt = self.rulas.map(function(t) {
+                     return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                 })
+                 console.log(iteration, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                     return a.join(" ")
+                 }));
+             }
+             if (io >= iomax) {
+                 sat = true;
+                 //            console.log((iteration).toFixed(0) + " ", ioa, "::", self.sos.join(" "), soso.join(" | "));
+             } else {
+                 self.sos[1] = iteration % self.subspace;
+                 self.sos[2] = Math.floor(iteration / self.subspace) % self.subspace;
+                 self.sos[3] = Math.floor(iteration / (self.subspace * self.subspace)) % self.subspace;
+                 self.sos[4] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace)) % self.subspace;
+                 //             self.sos[0] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace * self.subspace)) % self.subspace;
+             }
+             if (iteration % 10000000 === 0) {
+                 self.emit("status", (iteration / (self.space / 100)).toFixed(2), ioa + ":: " + cands.length + ":: " + self.sos.join(" "))
+             }
+
+             // console.log(iteration, self.sos.join(" "));
+             iteration++;
+         }
+
+
+
+     }
+
+
+
+
+
+
+     /*     while (!sat && iteration < self.space) {
+
+         var io = 0;
+         var ff = true;
+         while (io < iomax && ff) {
+             var t = self.rulas[io];
+             ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+             if (ff) {
+                 io++;
+             }
+         }
+         if (io > ioa) {
+             soso.push([].concat(self.sos));
+             ioa = io;
+             var tt = self.rulas.map(function(t) {
+                 return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+             })
+             console.log(iteration, io, ioa, iomax, self.sos.join(" "), tt.map(function(a) {
+                 return a.join(" ")
+             }));
+         }
+         if (io >= iomax) {
+             sat = true;
+             //            console.log((iteration).toFixed(0) + " ", ioa, "::", self.sos.join(" "), soso.join(" | "));
+         } else {
+             self.sos[4] = iteration % self.subspace;
+             self.sos[1] = Math.floor(iteration / self.subspace) % self.subspace;
+             self.sos[2] = Math.floor(iteration / (self.subspace * self.subspace)) % self.subspace;
+             self.sos[3] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace)) % self.subspace;
+             self.sos[0] = Math.floor(iteration / (self.subspace * self.subspace * self.subspace * self.subspace)) % self.subspace;
+         }
+         if (iteration % 10000000 === 0) {
+             self.emit("status", (iteration / (self.space / 100)).toFixed(2), self.sos.join(" "))
+         }
+         iteration++;
+     }*/
+
+     if (sat) {
+         console.log("SOLUTION FOUND");
+     }
+
+     var tt = self.rulas.map(function(t) {
+         return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+     })
+     console.log(iteration, self.sos.join(" "), tt.map(function(a) {
+         return a.join(" ")
+     }));
+     self.printit()
+
+
+ }
+
+
+ mo.prototype.printit = function(vals) {
+     var self = this;
+     var vals = vals || self.sos;
+     var lpad = function(s, l) {
+         while (s.length < l) {
+             s = " " + s
+         };
+         return s;
+     }
+     var rpad = function(s, l) {
+         while (s.length < l) {
+             s = s + " "
+         };
+         return s;
+     }
+
+     var s = [];
+     s.push([" ", 1, 2, 3, 4, 5].map(function(a) {
+         return lpad("" + a, 12)
+     }).join(" "));
+
+
+     Object.keys(self.variabler).map(function(k, ia) {
+
+         s.push([k, 0, 1, 2, 3, 4].map(function(a, io) {
+             return a == k ? rpad(k + ":" + vals[ia], 20) : lpad("" + self.variabler[k][self.current[vals[ia]][a]], 12)
+         }).join(" "))
+
+         //            s.push( )
+     })
+     console.log(s.join("\n") + "\n")
+ }
+
+ mo.prototype.stats = function() {
+     console.log("steps ", this._internal_step_counter)
+     console.log(this);
+ }
+ 
+
+ var t = new mo()
+     .addVariabelSet("Nationality", [ "Dane","Norwegian", "Swede", "Englishman", "German"])
+     .addVariabelSet("Color", ["Red",  "White", "Yellow", "Blue","Green"])
+     .addVariabelSet("Smokes", ["Prince", "Blend", "Dunhill", "BlueMasters", "PallMall"])
+     .addVariabelSet("Drinks", ["Water", "Bier", "Milk", "Tea", "Coffee"])
+     .addVariabelSet("Animals", ["Dogs", "Birds", "Cats", "Horses", "Fish"])
+     .addVariableTable("House", [0, 1, 2, 3, 4])
+     .addFunction("Neighbor", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkBoth", propid1, propid2, valid1, valid2, [prop1, val1, "Besides", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_Before", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_Before"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkLeft", propid1, propid2, valid1, valid2, [prop1, val1, "Before", prop2, val2].join(" ")]
+     })
+     .addFunction("Neighbor_After", function() {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = Object.keys(arg[Object.keys(arg)[1]])[0]
+         var val1 = arg[prop1];
+         var val2 = arg["Neighbor_After"][prop2];
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var propid2 = Object.keys(this.variabler).indexOf(prop2)
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         var valid2 = (this.variabler[prop2]).indexOf(val2)
+         return ["checkRight", propid1, propid2, valid1, valid2, [prop1, val1, "After", prop2, val2].join(" ")]
+     })
+     .addFunction("House", function(arg) {
+         var prop1 = Object.keys(arg)[0];
+         var prop2 = prop1
+         var propid1 = Object.keys(this.variabler).indexOf(prop1)
+         var val1 = arg[prop1];
+         var val2 = arg["House"];
+         var valid1 = (this.variabler[prop1]).indexOf(val1)
+         return ['checkn', propid1, propid1, valid1, val2, [prop1, val1, "House", val2].join(" ")]
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "House": 0
+     })
+     .addClause({
+         "Drinks": "Milk",
+         "House": 2
+     })
+     .addClause({
+         "Nationality": "Norwegian",
+         "Neighbor": {
+             "Color": "Blue"
+         }
+     })
+     .addClause({
+         "Nationality": "Englishman",
+         "Color": "Red"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Drinks": "Water"
+         }
+     })
+     .addClause({
+         "Nationality": "Swede",
+         "Animals": "Dogs"
+     })
+     .addClause({
+         "Nationality": "Dane",
+         "Drinks": "Tea"
+     })
+     .addClause({
+         "Color": "Green",
+         "Neighbor_Before": {
+             "Color": "White"
+         }
+     })
+     .addClause({
+         "Color": "Green",
+         "Drinks": "Coffee"
+     })
+     .addClause({
+         "Smokes": "PallMall",
+         "Animals": "Birds"
+     })
+     .addClause({
+         "Color": "Yellow",
+         "Smokes": "Dunhill"
+     })
+     .addClause({
+         "Nationality": "German",
+         "Smokes": "Prince"
+     })
+     .addClause({
+         "Smokes": "Blend",
+         "Neighbor": {
+             "Animals": "Cats"
+         }
+     })
+     .addClause({
+         "Animals": "Horses",
+         "Neighbor": {
+             "Smokes": "Dunhill"
+         }
+     })
+     .addClause({
+         "Smokes": "BlueMasters",
+         "Drinks": "Bier"
+     })
+
+
+ /*  .addClause("$House('Nationality','Norwegian')","eq","$House().first")
+    .addClause("$House('Drinks','Milk')","eq","$House().mid")
+    .addClause("$House('Nationality','Englishman')","eq","$House('Color','Red')")
+    .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
+   */
+ /*.addClause(0,"Norwegian",-1,-1,-1,-1)
+    .addClause(2,-1,-1,-1,"Milk",-1)
+    .addClause(-1,"Englishman","Red",-1,-1,-1,-1)
+    .addClause(-1,"N Norwegian","Blue",-1,-1,-1,-1)
+
+    .addClause("Math.abs($House('Nationality','Norwegian') - $House('Color','Blue'))===1")
+    .addClause("Math.abs($House('Smokes','Blend') - $House('Drinks','Water'))===1")
+    .addClause("$House('Nationality','Swede')===$House('Animals','Dogs')")
+    .addClause("$House('Nationality','Dane')===$House('Drinks','Tea')")
+    .addClause("($House('Color','Green')+1)===$House('Color','White')")
+    .addClause("$House('Color','Green')===$House('Drinks','Coffee')")
+    .addClause("$House('Smokes','PallMall')===$House('Animals','Birds')")
+    .addClause("$House('Color','Yellow')===$House('Smokes','Dunhill')")
+    .addClause("Math.abs($House('Smokes','Blend')-$House('Animals','Cats'))===1")
+    .addClause("$House('Smokes','BlueMasters')===$House('Drinks','Bier')")
+    //.addClause("Math.abs($House('Animals','Horses')-$House('Smokes','Dunhill'))===1")
+    //.addClause("$House('Nationality','German')===$House('Smokes','Prince')")
+*/
+
+
+ /*
+    The Englishman lives in the red house.<br>
+    The Swede keeps dogs.<br>
+    The Dane drinks tea.<br>
+    The green house is just to the left of the white one.<br>
+    The owner of the green house drinks coffee.<br>
+    The Pall Mall smoker keeps birds.<br>
+    The owner of the yellow house smokes Dunhills.<br>
+    The man in the center house drinks milk.<br>
+    The Norwegian lives in the first house.<br>
+    The Blend smoker has a neighbor who keeps cats.<br>
+    The man who smokes Blue Masters drinks bier.<br>
+    The man who keeps horses lives next to the Dunhill smoker.<br>
+    The German smokes Prince.<br>
+    The Norwegian lives next to the blue house.<br>
+    The Blend smoker has a neighbor who drinks water.<br>
+*/
+
+
+ //console.log(t.randoma("House"));
+ //t.stats();
+
+
+
+ t.on("status", function(per, found) {
+
+     console.log("PER", per, found);
+ })
+
+
+var result = t.solve();
+console.log(t.printit(result));
+
+ /*
+var Colors = ["Red", "White", "Yellow", "Blue", "Green"],
+    Nationality = ["Norwegian", "Dane", "Swede", "Englishman", "German"],
+    Cigarettes = ["Prince", "Blend", "Dunhill", "Blue Masters", "Pall Mall"],
+    Drinks = ["Water", "Bier", "Milk", "Tea", "Coffee"],
+    Animals = ["Dogs", "Birds", "Cat", "Horses", "Fish"];*/

+ 19 - 0
ena.js

@@ -0,0 +1,19 @@
+
+
+
+console.log("KLK")
+
+
+
+var t = 120;
+
+var tt= Math.pow(120,5);
+
+/*
+console.log(120*120)
+console.log(120*120*120)
+console.log(120*120*120*120)
+console.log(120*120*120*120*120)
+console.log(120*120*120*120*120/1000000000)
+console.log(2.48832e10/1000000000)
+*/

+ 18 - 0
ena.js.c.js

@@ -0,0 +1,18 @@
+
+
+
+console.log("KLK")
+
+
+
+var t = 120;
+
+var tt= Math.pow(120,5);
+
+
+console.log(120*120)
+console.log(120*120*120)
+console.log(120*120*120*120)
+console.log(120*120*120*120*120)
+console.log(120*120*120*120*120/1000000000)
+console.log(2.48832e10/1000000000)

+ 18 - 0
ena.js.c.js_tmp

@@ -0,0 +1,18 @@
+
+
+
+console.log("KLK")
+
+
+
+var t = 120;
+
+var tt= Math.pow(120,5);
+
+
+console.log(120*120)
+console.log(120*120*120)
+console.log(120*120*120*120)
+console.log(120*120*120*120*120)
+console.log(120*120*120*120*120/1000000000)
+console.log(2.48832e10/1000000000)

+ 197 - 0
sol.txt

@@ -0,0 +1,197 @@
+HAT
+[
+  [ 'checkn', 0, 0, 0, 0, 'Nationality Norwegian House 0' ],
+  [ 'checkn', 3, 3, 2, 2, 'Drinks Milk House 2' ],
+  [
+    'checkBoth',
+    0,
+    1,
+    0,
+    3,
+    'Nationality Norwegian Besides Color Blue'
+  ],
+  [ 'check', 0, 1, 3, 0, 'Nationality Englishman Color Red' ],
+  [ 'checkBoth', 2, 3, 1, 0, 'Smokes Blend Besides Drinks Water' ],
+  [ 'check', 0, 4, 2, 0, 'Nationality Swede Animals Dogs' ],
+  [ 'check', 0, 3, 1, 3, 'Nationality Dane Drinks Tea' ],
+  [ 'checkLeft', 1, 1, 4, 1, 'Color Green Before Color White' ],
+  [ 'check', 1, 3, 4, 4, 'Color Green Drinks Coffee' ],
+  [ 'check', 2, 4, 4, 1, 'Smokes PallMall Animals Birds' ],
+  [ 'check', 1, 2, 2, 2, 'Color Yellow Smokes Dunhill' ],
+  [ 'check', 0, 2, 4, 0, 'Nationality German Smokes Prince' ],
+  [ 'checkBoth', 2, 4, 1, 2, 'Smokes Blend Besides Animals Cats' ],
+  [ 'checkBoth', 4, 2, 3, 2, 'Animals Horses Besides Smokes Dunhill' ],
+  [ 'check', 2, 3, 3, 1, 'Smokes BlueMasters Drinks Bier' ]
+]
+0 1 1 12 0 0 0 0 0 [
+  'false check 0 4 2 0 Nationality Swede Animals Dogs',
+  'false check 0 3 1 3 Nationality Dane Drinks Tea',
+  'false check 0 2 4 0 Nationality German Smokes Prince',
+  'false checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'false check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'true check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'false checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'true checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'true checkn 3 3 2 2 Drinks Milk House 2'
+]
+0  1 :: 0 0 0 0 0 0,0,0,0,0
+31 2 2 12 0 0 0 0 30 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'false check 0 3 1 3 Nationality Dane Drinks Tea',
+  'false check 0 2 4 0 Nationality German Smokes Prince',
+  'false checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'false check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'true check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'false checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'true checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'true checkn 3 3 2 2 Drinks Milk House 2'
+]
+10000000  2 :: 0 53 94 5 40 0,0,0,0,0 | 0,0,0,0,30
+20000000  2 :: 0 106 68 11 80 0,0,0,0,0 | 0,0,0,0,30
+20736031 3 3 12 0 0 0 12 30 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'false check 0 2 4 0 Nationality German Smokes Prince',
+  'false checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'false check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'true check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'false checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'true checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+21211231 4 4 12 0 0 33 12 30 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'true check 0 2 4 0 Nationality German Smokes Prince',
+  'false checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'false check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'false check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'false checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'false checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+21212671 5 5 12 0 12 33 12 30 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'true check 0 2 4 0 Nationality German Smokes Prince',
+  'true checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'false check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'false check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'false checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'false checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+21215791 8 8 12 0 38 33 12 30 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'true check 0 2 4 0 Nationality German Smokes Prince',
+  'true checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'true check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'false check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'false checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'false checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+21302191 9 9 12 0 38 39 12 30 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'true check 0 2 4 0 Nationality German Smokes Prince',
+  'true checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'true check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'true check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'false checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'false checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+30000000  9 :: 0 40 43 17 0 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+40000000  9 :: 0 93 17 23 40 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+50000000  9 :: 0 26 112 28 80 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+60000000  9 :: 0 80 86 34 0 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+70000000  9 :: 0 13 61 40 40 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+80000000  9 :: 0 66 35 46 80 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+90000000  9 :: 0 0 10 52 0 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+100000000  9 :: 0 53 104 57 40 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+110000000  9 :: 0 106 78 63 80 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+120000000  9 :: 0 40 53 69 0 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+130000000  9 :: 0 93 27 75 40 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+140000000  9 :: 0 26 2 81 80 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+150000000  9 :: 0 80 96 86 0 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+160000000  9 :: 0 13 71 92 40 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+170000000  9 :: 0 66 45 98 80 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+180000000  9 :: 0 0 20 104 0 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+190000000  9 :: 0 53 114 109 40 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+200000000  9 :: 0 106 88 115 80 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+210000000  9 :: 1 40 63 1 0 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+220000000  9 :: 1 93 37 7 40 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+230000000  9 :: 1 26 12 13 80 0,0,0,0,0 | 0,0,0,0,30 | 0,0,0,12,30 | 0,0,33,12,30 | 0,12,33,12,30 | 0,38,33,12,30 | 0,38,39,12,30
+235822231 10 10 12 1 65 56 16 30 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'true check 0 2 4 0 Nationality German Smokes Prince',
+  'true checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'true check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'true check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'true checkLeft 1 1 4 1 Color Green Before Color White',
+  'false check 2 4 4 1 Smokes PallMall Animals Birds',
+  'true checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+235822262 12 12 12 1 65 56 16 61 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'true check 0 2 4 0 Nationality German Smokes Prince',
+  'true checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'true check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'true check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'true checkLeft 1 1 4 1 Color Green Before Color White',
+  'true check 2 4 4 1 Smokes PallMall Animals Birds',
+  'true checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+SOLUTION FOUND
+235822263 12 12 1 65 56 16 61 [
+  'true check 0 4 2 0 Nationality Swede Animals Dogs',
+  'true check 0 3 1 3 Nationality Dane Drinks Tea',
+  'true check 0 2 4 0 Nationality German Smokes Prince',
+  'true checkBoth 0 1 0 3 Nationality Norwegian Besides Color Blue',
+  'true check 0 1 3 0 Nationality Englishman Color Red',
+  'true checkn 0 0 0 0 Nationality Norwegian House 0',
+  'true check 1 3 4 4 Color Green Drinks Coffee',
+  'true check 1 2 2 2 Color Yellow Smokes Dunhill',
+  'true checkLeft 1 1 4 1 Color Green Before Color White',
+  'true check 2 4 4 1 Smokes PallMall Animals Birds',
+  'true checkBoth 2 3 1 0 Smokes Blend Besides Drinks Water',
+  'false checkn 3 3 2 2 Drinks Milk House 2'
+]
+                        1            2            3            4            5
+Nationality:1           Norwegian         Dane        Swede       German   Englishman
+Color:65                   Yellow         Blue        Green        White          Red
+Smokes:56                 Dunhill        Blend  BlueMasters       Prince     PallMall
+Drinks:16                   Water          Tea       Coffee         Bier         Milk
+Animals:61                   Cats       Horses         Dogs         Fish        Birds
+

+ 409 - 0
solver.js

@@ -0,0 +1,409 @@
+function EV() {
+    this.__e = {};
+}
+EV.prototype.__e = {};
+EV.prototype.emit = function(n) {
+    var that = this;
+    var args = [].slice.apply(arguments, [1]);
+    (this.__e[n] || []).map(function(lis) {
+        lis.map(function(fn) {
+            fn.apply(that, args)
+        })
+    })
+    return this;
+}
+EV.prototype.on = function(n) {
+    var args = [].slice.apply(arguments, [1]);
+    this.__e[n] = this.__e[n] || [];
+    this.__e[n].push(args);
+    return this;
+}
+
+function inherits(ctor, superCtor) {
+    var Obj = function() {};
+    Obj.prototype = superCtor.prototype;
+    ctor.prototype = new Obj
+}
+
+
+function permutates(xs) {
+    var ret = [];
+
+    for (var i = 0; i < xs.length; i = i + 1) {
+        var rest = permutates(xs.slice(0, i).concat(xs.slice(i + 1)));
+
+        if (!rest.length) {
+            ret.push([xs[i]])
+        } else {
+            for (var j = 0; j < rest.length; j = j + 1) {
+                ret.push([xs[i]].concat(rest[j]))
+            }
+        }
+    }
+    return ret;
+}
+
+function mo() {
+    this.variabler = {};
+    this.funcs = {};
+    this.rulas = [];
+}
+inherits(mo, EV)
+
+mo.prototype.addVariabelSet = function(navn, arr) {
+    this.variabler[navn] = arr
+    return this;
+}
+mo.prototype.addVariableTable = function(navn, arr) {
+    return this;
+}
+mo.prototype.addFunction = function(name, func) {
+    this.funcs[name] = func;
+    return this;
+}
+mo.prototype.addClause = function() {
+    var args = Array.prototype.slice.apply(arguments, []);
+    while (args.length) {
+        var arg = args.shift();
+
+        var props = Object.keys(arg);
+        var propid1, propid2;
+
+        if (this.variabler[props[0]]) {
+            propid1 = Object.keys(this.variabler).indexOf(props[0]);
+        }
+        if (this.variabler[props[1]]) {
+            propid2 = Object.keys(this.variabler).indexOf(props[1]);
+        } else {}
+        var arr = []
+        if (propid1 > -1 && propid2 > -1) {
+            val1 = this.variabler[props[0]].indexOf(arg[props[0]])
+            val2 = this.variabler[props[1]].indexOf(arg[props[1]])
+            arr = ["check", propid1, propid2, val1, val2, [props[0], arg[props[0]], props[1], arg[props[1]]].join(" ")];
+        } else {
+            var lookfor = props[props.length - 1];
+            if (this.funcs[lookfor]) {
+                arr = this.funcs[lookfor].apply(this, [arg])
+            }
+        }
+    }
+    this.rulas.push(arr);
+    return this;
+}
+
+mo.prototype.build = function(tabl) {
+    var r = [];
+    var arr = [];
+    var pertable = []
+
+    for (var navn in this.variabler) {
+        pertable.push(permutates((this.variabler[navn]).map(function(a, i) {
+            return i
+        })));
+    }
+
+    return pertable.sort(function(a,b){ a.length > b.length ? 1 : a.length < b.length ? -1 : 0 }).shift();
+}
+
+mo.prototype.checkPos = function(prop1, prop2, val1, val2) {
+
+    return this.current[this.sos[prop1]][val2] == val1
+
+}
+
+mo.prototype.check = function(prop1, prop2, val1, val2) {
+    var i;
+    //   console.log(prop1,this.sos[prop1], prop2, this.current[this.sos[prop1]],this.current[this.sos[prop2]],val1,val2)
+    for (i = 0; i < 5; i++) {
+        if (this.current[this.sos[prop1]][i] == val1) {
+            //         console.log("II,",i,this.current[this.sos[prop1]][i],"=",val1,"&", this.current[this.sos[prop2]][i],"=",val2 );
+            var p;
+            p = (this.current[this.sos[prop2]][i] == val2)
+            return p;
+        }
+    }
+    return false;
+}
+mo.prototype.checkLeft = function(prop1, prop2, val1, val2) {
+    var i;
+    for (i = 0; i < 4; i++) {
+        if (this.current[this.sos[prop1]][i] == val1) {
+            var p;
+            p = (this.current[this.sos[prop2]][i + 1] == val2)
+            return p;
+        }
+    }
+    return false;
+}
+mo.prototype.checkRight = function(prop1, prop2, val1, val2) {
+    var i;
+    for (i = 1; i < 5; i++) {
+        if (this.current[this.sos[prop1]][i] == val1) {
+            var p;
+            p = (this.current[this.sos[prop2]][i - 1] == val2)
+            return p;
+        }
+    }
+    return false;
+}
+
+mo.prototype.checkBoth = function(prop1, prop2, val1, val2) {
+
+    return this.checkLeft(prop1, prop2, val1, val2) || this.checkRight(prop1, prop2, val1, val2)
+}
+
+/*
+mo.prototype.inner_solve_l_1 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_2 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_3 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_4 = function(cands) {
+
+}
+mo.prototype.inner_solve_l_5 = function(cands) {
+
+}
+*/
+
+
+
+mo.prototype.inner_solve = function(cands) {
+    /*todo tada - slip fri for for for for for */
+    var self = this;
+
+    var cc = cands.length;
+    var ticks = [0, 0, 0, 0, 0];
+    var ic = 0;
+    var iomax = self.rulas.length;
+    var ioa = 0;
+    var suma = cands.reduce(function(a, b) {
+        return b[1].length * a
+    }, 1)
+
+
+    for (var i0 = 0; i0 < cands[0][1].length; i0++) {
+        if (cands[1]) {
+
+            for (var i1 = 0; i1 < cands[1][1].length; i1++) {
+                if (cands[2]) {
+
+                    for (var i2 = 0; i2 < cands[2][1].length; i2++) {
+                        if (cands[3]) {
+
+                        } else {
+                            total = suma * self.subspace * self.subspace
+                            var st = [0, 1, 2, 3, 4]
+                            self.sos[cands[0][0]] = cands[0][1][i0]
+                            self.sos[cands[1][0]] = cands[1][1][i1]
+                            self.sos[cands[2][0]] = cands[2][1][i2]
+
+                            st.splice(st.indexOf(cands[0][0]), 1);
+                            st.splice(st.indexOf(cands[1][0]), 1);
+                            st.splice(st.indexOf(cands[2][0]), 1);
+                            for (var i3 = 0; i3 < self.subspace; i3++) {
+                                for (var i4 = 0; i4 < self.subspace; i4++) {
+                                    ic++
+                                    self.sos[st[0]] = i3
+                                    self.sos[st[1]] = i4
+                                    var io = 0;
+                                    var ff = true;
+                                    while (io < iomax && ff) {
+                                        ff = false;
+                                        var t = self.rulas[io];
+                                        ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                                        if (ff) {
+                                            io++;
+                                        }
+                                    }
+                                    if (io > ioa) {
+                                        ioa = io;
+                                        var tt = self.rulas.map(function(t) {
+                                            return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                                        })
+                                        self.emit("part", ic, io, ioa, iomax, self.sos, tt.map(function(a) {
+                                            return a.join(" ")
+                                        }))
+                                    }
+                                    if (ioa >= iomax) {
+                                        return self.sos;
+                                    }
+                                    if (ic % 1000000 === 0) {
+                                        self.emit("status", (ic / (total / 100)).toFixed(2) + "%", total, ic, ioa, iomax)
+                                        // console.log("X2", ic, io, ioa, iomax,":>", self.sos[cands[0][0]], self.sos[cands[1][0]], self.sos[cands[2][0]], i3, i4);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+
+
+                    var st = [0, 1, 2, 3, 4]
+                    self.sos[cands[0][0]] = cands[0][1][i0]
+                    self.sos[cands[1][0]] = cands[1][1][i1]
+                    //                           self.sos[cands[2][0]] = cands[2][1][i2]
+
+                    st.splice(st.indexOf(cands[0][0]), 1);
+                    st.splice(st.indexOf(cands[1][0]), 1);
+                    //                             st.splice(st.indexOf(cands[2][0]), 1);
+                    total = suma * self.subspace * self.subspace * self.subspace;
+
+                    for (var i2 = 0; i2 < self.subspace; i2++) {
+                        for (var i3 = 0; i3 < self.subspace; i3++) {
+                            for (var i4 = 0; i4 < self.subspace; i4++) {
+                                ic++
+                                self.sos[st[0]] = i2
+                                self.sos[st[1]] = i3
+                                self.sos[st[2]] = i4
+                                var io = 0;
+                                var ff = true;
+                                while (io < iomax && ff) {
+                                    ff = false;
+                                    var t = self.rulas[io];
+                                    ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+                                    if (ff) {
+                                        io++;
+                                    }
+                                }
+                                if (io > ioa) {
+                                    ioa = io;
+                                    var tt = self.rulas.map(function(t) {
+                                        return [self[t.slice(0, 1)[0]].apply(self, t.slice(1))].concat(t);
+                                    })
+                                    self.emit("part", ic, io, ioa, iomax, self.sos, tt.map(function(a) {
+                                        return a.join(" ")
+                                    }))
+                                }
+                                if (ioa >= iomax) {
+                                    return self.sos;
+                                }
+                                if (ic % 1000000 === 0) {
+                                    console.log("X3", ic, io, ioa, iomax, ":>", self.sos[cands[0][0]], self.sos[cands[1][0]], i2, i3, i4);
+                                }
+                            }
+                        }
+
+                    }
+
+
+
+
+
+
+
+                }
+
+            }
+
+
+        }
+
+    }
+
+
+    return false;
+
+
+
+}
+
+
+mo.prototype.solve = function() {
+    var self = this;
+    self.current = this.build("House");
+    console.log(self.current);
+    
+    var sa = Object.keys(this.variabler);
+    self.sos = sa.map(function(a) {
+        return 0; //self.current.length - 1; //Math.floor(Math.random()*self.current.length-1);
+    })
+    self.subspace = self.current.length;
+    self.varspace = sa.length;
+
+
+    var iteration = 0;
+    var maxi = 0;
+    var ioa = -1;
+
+
+    // først find variabler som bruges i samme opslag.
+    var tas = {}
+    var firsta = [];
+    self.rulas.map(function(ru) {
+        console.log(ru);
+        if (ru[1] == ru[2]) {
+            firsta.push(ru);
+        }
+    })
+
+    self.sos = self.sos.map(function(a) {
+        return 0
+    })
+
+    var osa = -1
+    console.log(firsta);
+
+    var cands = [];
+
+
+    for (var x = 0; x < firsta.length; x++) {
+        self.sos = self.sos.map(function(a) {
+            return 0
+        })
+
+        var t = firsta[x];
+        var ca = [];
+        for (var i = 0; i < self.subspace; i++) {
+            var ff = false;
+            self.sos[t[1]] = i
+            ff = self[t.slice(0, 1)[0]].apply(self, t.slice(1))
+            if (ff) {
+                ca.push(i);
+            }
+        }
+        cands.push([t[1], ca]);
+    }
+
+
+    self.sos = self.sos.map(function(a) {
+        return 0
+    })
+    var result = this.inner_solve(cands);
+    this.emit("done", result);
+}
+
+
+mo.prototype.printit = function(vals) {
+    var self = this;
+    var vals = vals || self.sos;
+    var lpad = function(s, l) {
+        while (s.length < l) {
+            s = " " + s
+        };
+        return s;
+    }
+    var rpad = function(s, l) {
+        while (s.length < l) {
+            s = s + " "
+        };
+        return s;
+    }
+    var s = [];
+    s.push([" ", 1, 2, 3, 4, 5].map(function(a) {
+        return lpad("" + a, 12)
+    }).join(" "));
+    Object.keys(self.variabler).map(function(k, ia) {
+        s.push([k, 0, 1, 2, 3, 4].map(function(a, io) {
+            return a == k ? rpad(k + ":" + vals[ia], 20) : lpad("" + self.variabler[k][self.current[vals[ia]][a]], 12)
+        }).join(" "))
+    })
+    console.log(s.join("\n") + "\n")
+}
+
+
+module.exports = mo;

File diff suppressed because it is too large
+ 0 - 0
solver.js.c.js


File diff suppressed because it is too large
+ 0 - 0
solver.js.c.js_tmp


Some files were not shown because too many files changed in this diff