class BaseCircuitTest(MyClipsBaseTest): def setUp(self): self.network = Network() self.interpreter = Interpreter(self.network, None) MyClipsBaseTest.setUp(self) def _turnOnLogger(self): myclips.logger.disabled = False def _turnOffLogger(self): myclips.logger.disabled = True def forCircuits(self, *circuits): for s in circuits: self.interpreter.evaluate(s) aTrap = EventTrap().install(self.network.eventsManager) cExpect = CircuitExpect(aTrap) self.network.run() return cExpect
class SudokuDemo(wx.App): def OnInit(self): # Load the Sudoku solving programs #clips.Load("sudoku.clp") #clips.Load("solve.clp") self.engine = MyClipsEngine() self.interpreter = MyClipsInterpreter(self.engine) self.solvedCells = SudokuSolvedCells() self.solvedCells.install(self.engine.eventsManager) self.rulesUsed = SudokuTecniqueUsed() self.rulesUsed.install(self.engine.eventsManager) self.interpreter.evaluate('(load "../res/sudoku/sudoku.clp")') self.interpreter.evaluate('(load "../res/sudoku/solve.clp")') self.interpreter.evaluate('(load "../res/sudoku/output-frills.clp")') #self.interpreter.evaluate('(watch rules)') # Load the GUI from SudokuDemo.xrc resource = wx.xrc.XmlResource('SudokuDemo.xrc') self.frame = resource.LoadFrame(None, 'SudokuDemoFrame') # Store references to widgets that are being used at run-time. self.openfile = wx.xrc.XRCCTRL(self.frame, 'OpenFile') self.clear = wx.xrc.XRCCTRL(self.frame, 'Clear') self.reset = wx.xrc.XRCCTRL(self.frame, 'Reset') self.solve = wx.xrc.XRCCTRL(self.frame, 'Solve') self.techniques = wx.xrc.XRCCTRL(self.frame, 'Techniques') # Bind button events to handler functions self.openfile.Bind(wx.EVT_BUTTON, self.on_openfile) self.clear.Bind(wx.EVT_BUTTON, self.on_clear) self.reset.Bind(wx.EVT_BUTTON, self.on_reset) self.solve.Bind(wx.EVT_BUTTON, self.on_solve) self.techniques.Bind(wx.EVT_BUTTON, self.on_techniques) # Set max length in each of the wx.TextCtrls to 1. This can, # sadly, NOT be done using XRCEd. for g in range(1,10): for c in range(1,10): cell = wx.xrc.XRCCTRL(self.frame, '%d%d' % (g, c)) cell.SetMaxLength(1) self.solved = False self.resetvalues = {} # Bind the close event to the exit function and show the GUI self.frame.Bind(wx.EVT_CLOSE, self.exit) self.frame.Show(True) return True def on_openfile(self, event): """ Loads a Sudoku puzzle from disk. """ # Show a File Open Dialog dlg = wx.FileDialog(self.frame, message = "Open a Sudoku puzzle", style = wx.OPEN) if dlg.ShowModal() == wx.ID_OK: self.solved = False self.solve.Enable(True) self.techniques.Enable(False) path = dlg.GetPath() puzzle = open(path) positions = { 1 : [11, 12, 13, 21, 22, 23, 31, 32, 33], 2 : [14, 15, 16, 24, 25, 26, 34, 35, 36], 3 : [17, 18, 19, 27, 28, 29, 37, 38, 39], 4 : [41, 42, 43, 51, 52, 53, 61, 62, 63], 5 : [44, 45, 46, 54, 55, 56, 64, 65, 66], 6 : [47, 48, 49, 57, 58, 59, 67, 68, 69], 7 : [71, 72, 73, 81, 82, 83, 91, 92, 93], 8 : [74, 75, 76, 84, 85, 86, 94, 95, 96], 9 : [77, 78, 79, 87, 88, 89, 97, 98, 99] } lines = 0 for line in puzzle.readlines(): lines += 1 line = line.strip() if len(line) != 9: raise Exception("Malformed puzzle!") cells = positions[lines] for id, value in zip(cells, line): cell = wx.xrc.XRCCTRL(self.frame, '%d' % (id)) if value in ["1", "2", "3", "4", "5", "6", "7", "8", "9"]: cell.SetValue(str(value)) else: cell.SetValue("") cell.SetSize((20,20)) if lines != 9: raise Exception("Malformed puzzle!") puzzle.close() def on_clear(self, event): """ Clears the Sudoku grid. """ self.solved = False self.solve.Enable(True) self.techniques.Enable(False) for g in range(1,10): for c in range(1,10): cell = wx.xrc.XRCCTRL(self.frame, '%d%d' % (g, c)) cell.SetValue("") cell.SetSize((20,20)) def on_reset(self, event): """ Resets the Sudoku grid to the last puzzle solved. """ self.solved = False self.solve.Enable(True) self.techniques.Enable(False) for g in range(1,10): for r in range(3): for c in range(3): cell = wx.xrc.XRCCTRL(self.frame, '%d%d' % (g, (r* 3)+ c+ 1)) try: cell.SetValue(self.resetvalues[(g,r,c)]) except: cell.SetValue("") cell.SetSize((20,20)) def on_solve(self, event): """ Solves the Sudoku puzzle and updates the grid with the solution. """ #clips.Reset() #clips.Assert("(phase expand-any)") #clips.Assert("(size 3)") #self.engine.reset() #self.interpreter.evaluate('(assert (phase expand-any))') #self.interpreter.evaluate('(assert (size 3))') # Remember the initial starting values # of the puzzle for the reset command. grid_rule = ''' (defrule grid-values ?f <- (phase grid-values) => (retract ?f) (assert (phase expand-any)) (assert (size 3)) ''' self.resetvalues = {} for i in range(9): rowgroup = i / 3 colgroup = i % 3 for r in range(3): for c in range(3): cell = wx.xrc.XRCCTRL(self.frame, '%d%d' % (i+ 1, (r* 3)+ c+ 1)) self.resetvalues[(i+ 1,r,c)] = cell.GetValue() assertStr = "(possible (row %d) (column %d) (group %d) (id %d) " % \ ((r + (rowgroup * 3) + 1), (c + (colgroup * 3) + 1), (i + 1), ((i * 9) + (r * 3) + c + 1)) if self.resetvalues[(i+ 1,r,c)] == "": assertStr = assertStr + "(value any))" else: assertStr = assertStr + "(value " + self.resetvalues[(i+ 1, r, c)] + "))" #clips.Assert(str(assertStr)) #self.interpreter.evaluate('(assert %s)'%str(assertStr)) grid_rule += "(assert %s)\n"%str(assertStr) grid_rule += ")" #print grid_rule self.interpreter.evaluate(grid_rule) self.engine.reset() self.solved = True self.reset.Enable(True) self.solve.Enable(False) self.techniques.Enable(True) # Solve the puzzle #clips.Run() self.engine.run() #ff = self.engine.facts #for f in ff: # print f #print self.solvedCells.grid for i in range(9): rowgroup = i / 3 colgroup = i % 3 for r in range(3): for c in range(3): cell = wx.xrc.XRCCTRL(self.frame, '%d%d' % (i+ 1, (r* 3)+ c+ 1)) if cell.GetValue() == "": # Any cells that have not been assigned a value # are given a '?' for their content cell.SetValue("?") value = self.solvedCells.getValueAtCell(r + (rowgroup * 3) + 1, c + (colgroup * 3) + 1) cell.SetValue(str(value)) # Retrieve the solution from CLIPS. # for i in range(9): # rowgroup = i / 3 # colgroup = i % 3 # for r in range(3): # for c in range(3): # cell = wx.xrc.XRCCTRL(self.frame, '%d%d' % (i+ 1, (r* 3)+ c+ 1)) # if cell.GetValue() == "": # # Any cells that have not been assigned a value # # are given a '?' for their content # cell.SetValue("?") # # evalStr = "(find-all-facts ((?f possible)) (and (eq ?f:row %d) (eq ?f:column %d)))" % \ # ((r + (rowgroup * 3) + 1), # (c + (colgroup * 3) + 1)) # # pv = clips.Eval(evalStr) # if len(pv) == 1: # fv = pv[0] # cell.SetValue(str(fv.Slots["value"])) def on_techniques(self, event): """ Opens a wx.Dialog that displays which solution techniques was used to solve the current puzzle. """ # evalStr = "(find-all-facts ((?f technique)) TRUE)"; # techniques = clips.Eval(evalStr) # # message = "" # tNum = len(techniques) # for i in range(1, tNum+ 1): # evalStr = "(find-fact ((?f technique-employed)) (eq ?f:priority %d))" % (i) # pv = clips.Eval(evalStr) # # if len(pv) > 0: # fv = pv[0] # # message = "%s\n%s. %s" % (message, fv.Slots["priority"], fv.Slots["reason"]) #print self.rulesUsed.rules message = "\n".join(self.rulesUsed.rules) dlg = wx.MessageDialog(self.frame, message, "Solution Techniques", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() def exit(self, event): """ Destroys the GUI and exits the application. """ self.frame.Destroy() sys.exit(0)
def main(): ''' MyCLIPS main function!!! Show usage info for invalid params in sys.argv :) Read it for more info ''' if sys.argv[0].endswith("__main__.py"): sys.argv[0] = "python -m myclips" usage = { "progName" : os.path.basename(sys.argv[0]), "modes" : "\n".join([ " shell Start a MyCLIPS's Shell", #" xmlrpc Start a MyCLIPS XMLRPC server", " batch filename Load a batch and then (run) it", " functions Search for System Function and compile the manifest", " tests Run MyCLIPS's unittests", ]), "options" : "" } USAGE = """\ Usage: %(progName)s [modes] [options] Modes: %(modes)s Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output -b, --background Background service %(options)s Examples: %(progName)s - Show this message %(progName)s shell - run a MyCLIPS shell %(progName)s functions - run the system function manifest generator %(progName)s tests - run MyCLIPS env tests %(progName)s batch benchmark/manners.clpbat - run a file in batch mode %(progName)s bench benchmark/manners.clpbat - run a file in batch mode + bench-run """%usage try: theMode = sys.argv[1] except: print USAGE sys.exit(-2) if theMode == "shell": Shell().loop() elif (theMode == "batch" or theMode == "bench") and len(sys.argv) >= 3: i = Interpreter(Network()) i.evaluate("(batch \"%s\")"%sys.argv[2].strip('"')) if theMode == "batch": i.evaluate("(run)") else: print i.evaluate("(bench-run)") elif theMode == "functions": FunctionManifestGenerator.generate() elif theMode == "tests": if exists(os.path.dirname(__file__)+'/../../tests'): # prepare the sys.argv sys.argv = ["python -m unittest", "discover", "-p", '*Test.py', "-s", "../tests/"] unittest.main(module=None) else: print "Expected a tests dir in `%s`, but nothing found"%(os.path.dirname(__file__)+'/../../tests') else: print USAGE