DSPython  00.03.03 — 25 juin 2012
 Tout Classes Espaces de nommage Fichiers Fonctions Variables Pages
urmCutlandTk.py
Aller à la documentation de ce fichier.
1 #!/usr/bin/env python
2 # -*- coding: latin-1 -*-
3 ##\file
4 # Application <b>URM of Cutland Tk</b> permettant de manipuler
5 # une URM de <span style="font-variant:small-caps">Cutland</span>
6 # !!! Work in progress !!!
7 #
8 # \htmlonly <a class="relative" href="urmCutlandTk.png" target="_blank"><img
9 # src="urmCutlandTk_th.png" border="0" align="top" alt="[urmCutlandTk_th.png]"></a>\endhtmlonly\n
10 # Cf. \htmlonly <a href="http://www.opimedia.be/Bruno_Marchal/index.htm#Theo" target="_blank">
11 # <tt>http://www.opimedia.be/Bruno_Marchal/index.htm#Theo</tt></a>\endhtmlonly
12 
13 
14 # (c) Olivier Pirson --- DragonSoft
15 # http://www.opimedia.be/DS/
16 # Débuté le 24 janvier 2008
17 # v.00.00 --- 2 mars 2008
18 # --- 19 mai 2008
19 # --- 20 novembre 2008
20 # --- 26 février 2009
21 # --- 25 mars 2009
22 # --- 29 septembre 2009 : nouveau site web
23 # --- 14 décembre 2009 : from __future__ import division
24 # --- 20 décembre 2009 : adapte pour Python 3
25 # --- 16 mars 2010 : nouveau site web et changement des % en .format()
26 # --- 12 avril 2010 : cfr. -> cf.
27 ###############################################################################
28 from __future__ import division
29 
30 ## Version
31 VERSION = 'v.00.00 --- 2010 April 12'
32 
33 import sys, time
34 
35 if sys.version_info[0] >= 3: # Python >= 3
36  import tkinter as tk
37  import tkinter.font as tkFont
38  import tkinter.messagebox as tkMessageBox
39 else: # 2.6 <= Python < 3
40  import Tkinter as tk
41  import tkFont
42  import tkMessageBox
43 
44 import DSPython
45 import DSPython.factors as factors
46 import DSPython.urmCutland as urmCutland
47 
48 try:
49  if not 'profile' in dir():
50  import psyco
51  psyco.full()
52 except ImportError:
53  pass
54 
55 
56 
57 # ####################
58 # Variables globales #
59 ######################
60 ## Représentation du programme par un code à la Gödel
61 godel_prog = 1
62 
63 ## Représentation des registres par un code à la Gödel
64 godel_regs = 1
65 
66 ## Nombre d'instructions exécutée
67 nb_runned = 0
68 
69 ## Numéro de l'instruction courante
70 num_inst = 1
71 
72 ## Numéro de l'instruction courante précédante
73 num_inst_old = None
74 
75 ## Numéro du registre courant
76 num_reg = 1
77 
78 ## Numéro du registre courant précédant
79 num_reg_old = None
80 
81 ## Programme à faire exécuter par urm
82 prog = urmCutland.UrmCutlandProg('')
83 
84 ## Machine virtuelle URM
85 urm = urmCutland.UrmCutland()
86 
87 
88 
89 # #####################################
90 # Variables globales pour l'interface #
91 #######################################
92 ## Fenêtre principale
93 w = tk.Tk()
94 
95 ## Police de caractères à taille fixe pour les listes
96 monospace = tkFont.Font(w, size=10, family='courier')
97 
98 ## Si True alors n'affiche pas les instructions q) J(m,n,q+1) dans le champ programme
99 hide_qJmnq1 = tk.IntVar()
100 hide_qJmnq1.set(1)
101 
102 ## Si True alors n'affiche pas les instructions T(n,n) dans le champ programme
103 hide_Tnn = tk.IntVar()
104 hide_Tnn.set(1)
105 
106 ## Si True alors affiche les "nombres de Gödel" de chaque instruction
107 show_godel_numbers = tk.IntVar()
108 
109 ## Si True alors affiche godel_prog
110 show_godel_prog = tk.IntVar()
111 
112 ## Si True alors affiche godel_regs
113 show_godel_regs = tk.IntVar()
114 
115 ## Si True alors affiche les facteurs des registres
116 show_factors = tk.IntVar()
117 show_factors.set(1)
118 
119 
120 ## Si True alors marque une pause entre chaque instruction exécutée
121 sleep = tk.IntVar()
122 
123 ## Durée en ms de l'attente en deux exécutions
124 sleep_delay = 100
125 
126 
127 ## Si True alors interrompre l'exécution en cours
128 stop = False
129 
130 
131 
132 # ###########
133 # Fonctions #
134 #############
135 ## Compile le source
136 def compile():
137  """???"""
138  global nb_runned, num_inst, prog
139 
140  src = str(l_src.get('1.0', tk.END))
141  try:
142  prog = urmCutland.UrmCutlandProg(src)
143  except:
144  prog = urmCutland.UrmCutlandProg('')
145  num_inst = 1
146  nb_runned = 0
147 
148  update_num_inst()
149  update_nb_runned()
150  update_prog()
151 
152 
153 # Renvoie l'instruction numéro num sous forme de String
154 def inst_to_str(num):
155  """???"""
156  global hide_qJmnq1, hide_Tnn, num_inst, prog, show_godel_numbers
157 
158  c = ('*' if num == num_inst
159  else ' ')
160  if ((hide_Tnn.get() and (prog[num].inst() == urmCutland.T)
161  and (prog[num].a() == prog[num].b()))
162  or (hide_qJmnq1.get() and (prog[num].inst() == urmCutland.J)
163  and (prog[num].c() == num + 1))):
164  s = num_inst_to_str(num)
165  else:
166  s = '{0}{1}'.format(num_inst_to_str(num), prog[num])
167  if show_godel_numbers.get():
168  s += ' = {0}'.format(prog[num].godelnumber())
169  return s
170 
171 
172 ## Renvoie un numéro d'instruction sous forme de String
173 def num_inst_to_str(num):
174  """???"""
175  global num_inst, prog
176 
177  return ('{{0:{0}}}){{1}}'.format(len(str(len(prog))))).format(num,
178  '*' if num == num_inst
179  else ' ')
180 
181 
182 ## Exécute certaines instructions du programme dans l'URM
183 def run(nb):
184  """Exécute nb (ou toutes si nb == None) instructions du programme dans l'URM
185 
186  Pre: nb: naturel ou None"""
187  global nb_runned, num_inst, prog, stop
188 
189  b_run.config(relief=tk.SUNKEN, state=tk.DISABLED)
190  stop = False
191  while ((nb == None) or (nb > 0)) and (num_inst <= len(prog)) and (not stop):
192  update_num_inst()
193  update_nb_runned()
194  update_registers()
195  w.update()
196  if sleep.get():
197  time.sleep(sleep_delay/1000)
198 
199  num_inst = urm.run(prog, i=num_inst, nb=1)[0]
200  nb_runned += 1
201  if nb != None:
202  nb -= 1
203 
204  stop = False
205  update_num_inst()
206  update_nb_runned()
207  update_registers()
208  b_run.config(relief=tk.RAISED, state=tk.NORMAL)
209 
210 
211 
212 # ############################
213 # Fonctions pour l'interface #
214 ##############################
215 ## MessageBox About...
216 def cmd_about():
217  tkMessageBox.showinfo('About...',
218  """URM of Cutland Tk
219 
220 !!! Work in progress !!!
221 {0}
222 (c) Olivier Pirson --- DragonSoft
223 {1}
224 
225 
226 Infos:
227 {2}
228 Python {3}""".format(VERSION, DSPython.DS_web, DSPython.VERSION, sys.version))
229 
230 
231 ## Efface les registres
232 def cmd_clear_regs():
233  global urm
234 
235  urm = urmCutland.UrmCutland()
236  update_registers()
237 
238 
239 ## Efface le source (et donc le programme)
240 def cmd_clear_src():
241  global l_prog, l_src
242 
243  l_prog.delete(0, tk.END)
244  l_src.delete('1.0', tk.END)
245 
246 
247 ## Compile le source et actualise l'affichage
248 def cmd_compile():
249  compile()
250 
251 
252 ## cmd_compile() puis cmd_run()
253 def cmd_compile_run():
254  cmd_compile()
255  cmd_run()
256 
257 
258 ## Exécute le reste du programme à partir de l'instruction courante
259 def cmd_finish():
260  run(None)
261 
262 
263 ## Récupère et actualise le numéro d'instruction courante
264 def cmd_num_inst(event):
265  global num_inst
266 
267  try:
268  n = int(str(event.widget.get()))
269  num_inst = max(1, n)
270  except:
271  pass
272  update_num_inst()
273 
274 
275 ## Quitter ?
276 def cmd_quit():
277  if tkMessageBox.askyesno('Quit?', 'Quit URM of Cutland Tk?'):
278  cmd_stop()
279  w.quit()
280 
281 
282 ## Réinitialise sur la première instruction
283 def cmd_restart():
284  global num_inst, nb_runned
285 
286  num_inst = 1
287  nb_runned = 0
288  update_num_inst()
289  update_nb_runned()
290 
291 
292 ## Exécute tout le programme après réinitialisation
293 def cmd_run():
294  global num_inst, urm
295 
296  urm = urmCutland.UrmCutland()
297  num_inst = 1
298  run(None)
299 
300 
301 ## Sélection d'une instruction
302 def cmd_select_inst(event):
303  global l_prog, num_inst
304 
305  i = l_prog.curselection()
306  num_inst = (int(i[0]) + 1 if len(i) > 0
307  else 1)
308  update_num_inst()
309 
310 
311 ## Initialise sleep_delay avec la valeur saisie
312 def cmd_change_delay(event):
313  global e_delay, sleep_delay
314 
315  s = e_delay.get()
316  try:
317  sleep_delay = int(s)
318  except:
319  e_reg.delete(0, tk.END)
320 
321 
322 ## Initialise num_reg avec la valeur saisie
323 def cmd_change_reg(event):
324  global e_reg, num_reg, urm
325 
326  s = e_reg.get()
327  if (s != '') and (s[-1] == ':'): # numéro de registre
328  try:
329  num_reg = max(1, int(s[:-1]))
330  e_reg.delete(0, tk.END)
331  update_num_reg()
332  except:
333  e_reg.delete(0, tk.END)
334  e_reg.insert(tk.END, ':')
335  else: # valeur pour le registre
336  try:
337  n = int(s)
338  if n >= 0:
339  urm[num_reg] = n
340  update_registers()
341  else:
342  e_reg.delete(0, tk.END)
343  except:
344  e_reg.delete(0, tk.END)
345  update_registers()
346 
347 
348 ## Sélection d'un registre
349 def cmd_select_reg(event):
350  global l_regs, num_reg
351 
352  i = l_regs.curselection()
353  num_reg = (int(i[0]) + 1 if len(i) > 0
354  else 1)
355  update_num_reg()
356 
357 
358 ## Exécute l'instruction courante
359 def cmd_step():
360  run(1)
361 
362 
363 ## Active le stop
364 def cmd_stop():
365  global stop
366 
367  stop = True
368 
369 
370 ## Réactualise l'affichage de godel_prog
371 def update_godel_prog():
372  global godel_prog, l_godel_prog, prog
373 
374  if show_godel_prog.get():
375  godel_prog = prog.godelnumber()
376  l_godel_prog.config(text=('{0}' if godel_prog < 10**20
377  else '{0:e}').format(godel_prog))
378  else:
379  l_godel_prog.config(text='')
380 
381 
382 ## Réactualise l'affichage de godel_regs
383 def update_godel_regs():
384  global godel_regs, l_godel_regs, urm
385 
386  if show_godel_regs.get():
387  godel_regs = urm.godelnumber()
388  l_godel_regs.config(text=('{0}' if godel_regs < 10**20
389  else '{0:e}').format(godel_regs))
390  else:
391  l_godel_regs.config(text='')
392 
393 
394 ## Réactualise l'affichage de nb_runned
395 def update_nb_runned():
396  global l_nb_runned, nb_runned
397 
398  l_nb_runned.config(text='{0} runned'.format(nb_runned))
399 
400 
401 ## Réactualise l'affichage de num_inst
402 def update_num_inst():
403  global l_inst, num_inst, num_inst_old
404 
405  if num_inst_old == num_inst:
406  return
407  if (num_inst_old != None) and (num_inst_old <= l_prog.size()):
408  l_prog.delete(num_inst_old - 1)
409  l_prog.insert(num_inst_old - 1, inst_to_str(num_inst_old))
410  if num_inst <= l_prog.size():
411  l_prog.delete(num_inst - 1)
412  l_prog.insert(num_inst - 1, inst_to_str(num_inst))
413  num_inst_old = num_inst
414  l_inst.config(text=num_inst_to_str(num_inst))
415 
416 
417 ## Réactualise l'affichage de num_reg
418 def update_num_reg():
419  global l_reg, num_reg, urm
420 
421  l_reg.config(text=('{{0:{0}}}'.format(len(str(len(urm))))).format(num_reg))
422 
423 
424 ## Réactualise l'affichage de prog
425 def update_prog():
426  global l_prog, num_inst, num_inst_old, prog
427 
428  l_prog.delete(0, tk.END)
429  for i in range(1, len(prog) + 1):
430  l_prog.insert(tk.END, inst_to_str(i))
431  num_inst_old = num_inst
432 
433  update_num_inst()
434  update_nb_runned()
435  update_godel_prog()
436 
437 
438 ## Réactualise l'affichage des registres
439 def update_registers():
440  global l_regs, show_factors, urm
441 
442  len_r = 0
443  for r in urm:
444  len_r = max(len_r, r)
445  len_r = len(str(len_r))
446 
447  l_regs.delete(0, tk.END)
448  for i in range(1, len(urm) + 1):
449  if show_factors.get() and (urm[i] > 0):
450  p = factors.primaries(urm[i])
451  s = (('{{0:{0}}}: {{1:{1}}} = {{2}}'.format(len(str(len(urm))), len_r))
452  .format(i, urm[i], factors.primaries_str(p, times=' .')))
453  if len(s) > 30:
454  s = (('{{0:{0}}}: {{1:{1}}} = {{2}}'.format(len(str(len(urm))), len_r))
455  .format(i, urm[i], factors.primaries_str(p)))
456  else:
457  s = ('{{0:{0}}}: {{1:{1}}}'.format(len(str(len(urm))), len_r)).format(i, urm[i])
458  l_regs.insert(tk.END, s)
459 
460  update_num_reg()
461  update_godel_regs()
462 
463 
464 
465 # ######\cond MAIN
466 # Main #
467 ########
468 w.title('URM of Cutland Tk (!!! Work in progress !!!)')
469 w.resizable(0,0)
470 w.protocol('WM_DELETE_WINDOW', cmd_quit)
471 
472 
473 # ------
474 ## Pour les premiers boutons
475 f = tk.Frame(w)
476 
477 ## Bouton 'Compile & Run'
478 b_run = tk.Button(f, text='Compile & Run', command=cmd_compile_run)
479 b_run.grid(row=1, column=1)
480 tk.Frame(f, width=5).grid(row=1, column=2)
481 tk.Button(f, text='Restart', command=cmd_restart).grid(row=1, column=5)
482 tk.Frame(f, width=5).grid(row=1, column=6)
483 
484 tk.Button(f, text='Step', command=cmd_step).grid(row=1, column=7)
485 tk.Button(f, text='Next', state=tk.DISABLED).grid(row=1, column=8)
486 tk.Button(f, text='Continue', state=tk.DISABLED).grid(row=1, column=9)
487 tk.Button(f, text='Finish', command=cmd_finish).grid(row=1, column=10)
488 tk.Frame(f, width=5).grid(row=1, column=11)
489 tk.Button(f, text='Stop', command=cmd_stop).grid(row=1, column=12)
490 
491 tk.Frame(f, width=20).grid(row=1, column=13)
492 tk.Button(f, text='Help', state=tk.DISABLED).grid(row=1, column=14)
493 tk.Button(f, text='About', command=cmd_about).grid(row=1, column=15)
494 tk.Frame(f, width=5).grid(row=1, column=16)
495 tk.Button(f, text='Quit', command=cmd_quit).grid(row=1, column=17)
496 
497 f.grid(row=1, column=1, sticky=tk.W)
498 
499 tk.Frame(f, height=5).grid(row=2, column=1)
500 
501 
502 
503 # ------
504 ## Pour les registres et le programme
505 f = tk.Frame(w)
506 
507 tk.Button(f, text='Load', state=tk.DISABLED).grid(row=1, column=1, sticky=tk.W)
508 tk.Button(f, text='Save', state=tk.DISABLED).grid(row=1, column=2, sticky=tk.W)
509 tk.Button(f, text='Clear', command=cmd_clear_regs).grid(row=1, column=3, sticky=tk.W)
510 tk.Frame(f, height=5).grid(row=2, column=1)
511 
512 ## Liste des registres
513 l_reg = tk.Label(f, text='', font=monospace)
514 l_reg.grid(row=3, column=1, sticky=tk.W)
515 
516 ## Entry pour change la valeur d'un registre
517 e_reg = tk.Entry(f, width=5, font=monospace)
518 e_reg.bind('<Return>', cmd_change_reg)
519 #???e_reg.bind('<FocusOut>', cmd_change_reg)
520 e_reg.grid(row=3, column=2, sticky=tk.W)
521 
522 tk.Label(f, text='Registers |').grid(row=3, column=3, sticky=tk.E)
523 
524 ## Listbox pour la liste des regitres
525 l_regs = tk.Listbox(f, height=20, width=30, font=monospace)
526 l_regs.bind('<ButtonRelease-1>', cmd_select_reg)
527 l_regs.grid(row=4, column=1, columnspan=3, sticky=tk.N)
528 
529 tk.Checkbutton(f, text="Gödel's number:", variable=show_godel_regs,
530  command=update_godel_regs).grid(row=5, column=1, sticky=tk.W)
531 ## Label pour le nombre de Gödel de la liste des registres
532 l_godel_regs = tk.Label(f, text=godel_regs)
533 l_godel_regs.grid(row=5, column=2, columnspan=2, sticky=tk.W)
534 
535 tk.Checkbutton(f, text='Show factors', variable=show_factors,
536  command=update_registers).grid(row=6, column=1, columnspan=3, sticky=tk.W)
537 
538 
539 tk.Button(f, text='Load', state=tk.DISABLED).grid(row=1, column=4, sticky=tk.W)
540 tk.Button(f, text='Save', state=tk.DISABLED).grid(row=1, column=5, sticky=tk.W)
541 tk.Button(f, text='Run', command=cmd_run).grid(row=1, column=6, sticky=tk.W)
542 tk.Frame(f, height=5).grid(row=2, column=4)
543 
544 ## Programme (liste des instructions)
545 l_inst = tk.Label(f, text=num_inst_to_str(num_inst), font=monospace)
546 l_inst.grid(row=3, column=4, sticky=tk.W)
547 
548 ## Label pour le nombre d'instructions exécutées
549 l_nb_runned = tk.Label(f, text='{0} runned'.format(nb_runned))
550 l_nb_runned.grid(row=3, column=5, sticky=tk.W)
551 
552 tk.Label(f, text='Program |').grid(row=3, column=6, sticky=tk.E)
553 
554 ## Listbox pour le programme
555 l_prog = tk.Listbox(f, height=20, width=25, font=monospace)
556 l_prog.bind('<ButtonRelease-1>', cmd_select_inst)
557 l_prog.grid(row=4, column=4, columnspan=3, sticky=tk.N)
558 
559 tk.Checkbutton(f, text="Gödel's number:", variable=show_godel_prog,
560  command=update_godel_prog).grid(row=5, column=4, sticky=tk.W)
561 ## Label pour le nombre de Gödel du programme
562 l_godel_prog = tk.Label(f, text=godel_prog)
563 l_godel_prog.grid(row=5, column=5, columnspan=2, sticky=tk.W)
564 
565 tk.Checkbutton(f, text="Show Gödel's numbers", variable=show_godel_numbers,
566  command=update_prog).grid(row=6, column=4, columnspan=3, sticky=tk.W)
567 
568 tk.Checkbutton(f, text='Hide', variable=hide_Tnn,
569  command=update_prog).grid(row=7, column=4, columnspan=1, sticky=tk.W)
570 tk.Label(f, text='T(n,n)', font=monospace).grid(row=7, column=5, columnspan=2, sticky=tk.W)
571 
572 tk.Checkbutton(f, text='Hide', variable=hide_qJmnq1,
573  command=update_prog).grid(row=8, column=4, columnspan=3, sticky=tk.W)
574 tk.Label(f, text='q) J(m,n,q+1)', font=monospace).grid(row=8, column=5, columnspan=2, sticky=tk.W)
575 
576 tk.Checkbutton(f, text='Delay:', variable=sleep,
577  command=lambda : cmd_change_delay(None)).grid(row=9, column=4,
578  columnspan=3, sticky=tk.W)
579 ## Entry pour le délai
580 e_delay = tk.Entry(f, width=5)
581 e_delay.insert(tk.END, str(sleep_delay))
582 e_delay.bind('<Return>', cmd_change_delay)
583 #???e_delay.bind('<FocusOut>', cmd_change_delay)
584 e_delay.grid(row=9, column=5, sticky=tk.W)
585 tk.Label(f, text='ms').grid(row=9, column=6, sticky=tk.W)
586 
587 
588 tk.Button(f, text='Load', state=tk.DISABLED).grid(row=1, column=7, sticky=tk.W)
589 tk.Button(f, text='Save', state=tk.DISABLED).grid(row=1, column=8, sticky=tk.W)
590 tk.Button(f, text='Clear', command=cmd_clear_src).grid(row=1, column=9, sticky=tk.N)
591 tk.Button(f, text='Compile', command=cmd_compile).grid(row=1, column=10, sticky=tk.N)
592 tk.Frame(f, height=5).grid(row=7, column=1)
593 
594 ## Éditeur pour le source du programme
595 tk.Label(f, text='Source |').grid(row=3, column=7, columnspan=4, sticky=tk.E)
596 l_src = tk.Text(f, height=21, width=50, font=monospace)
597 l_src.grid(row=4, column=7, rowspan=2, columnspan=4, sticky=tk.N)
598 l_src.insert(tk.END, """3) i(ADD) # include ADD
599 Z(12)
600 10) J(3,4,11) # always next instruction
601 15) Z(7) # R7 <- 0
602 16) S(2) # R2 <- R2 + 1
603 17) S(2) # R2 <- R2 + 1""")#???
604 
605 f.grid(row=3, column=1)
606 
607 
608 
609 #
610 f = None
611 #???w.bind('<Button>', cmd_change_reg)
612 w.mainloop()
613 ##\endcond MAIN