home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lifeos2.zip / LIFE-1.02 / DEMO / X_MATHWI.LF < prev    next >
Text File  |  1996-06-04  |  10KB  |  435 lines

  1. module("x_mathwiz")?
  2. public(mathwiz)?
  3.  
  4. import("xtools_utils")?
  5.  
  6. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  7. % Borrow sorting routine:
  8.  
  9. import("lists")?
  10.  
  11. sort(L) -> gen_quicksort(L,order=> >).
  12.  
  13. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  14.  
  15. persistent(target, seed, best) ?
  16. persistent(stop_point, first_sol) ?
  17. persistent(start_time) ?
  18.  
  19. dynamic(solvable, unsolvable) ?
  20.  
  21. find(Ls, Show, Time) :-
  22.     Nums = copy_term(feature_values(seed)),
  23.     cond(Show ,
  24.          resolve1(Nums, copy_term(target), Ls.moves),
  25.          resolve2(6, Nums, [], Ls)).
  26.  
  27. resolve1(L, Target, Moves) :-
  28.     choose(A, L, L1),
  29.     choose1(B, L1),
  30.     findop(A, B, Op, C),
  31.     Moves = [A, Op, B, C | R],
  32.     cond( abs(Target - C) =:= 0,
  33.           R = [],
  34.           resolve1([C|L], Target, R)).
  35.  
  36. resolve2(2, [A, B], Moves, Ls) :-
  37.     !,
  38.     New_moves = append(Moves, [A, Op, B, C]),
  39.     findop(A, B, Op, C),
  40.     Diff = abs(target - C),
  41.     cond( Diff < best,
  42.           ( best <<- copy_term(Diff),
  43.         cond(cpu_time - start_time > 10,
  44.              time_display(New_moves, Ls),
  45.              display(New_moves, Ls)))
  46.         ),
  47.     cond( Diff =:= 0, time_display(New_moves, Ls), fail ).
  48.  
  49. resolve2(N, L) :-
  50.     N > 3,
  51.     unsolvable(L),
  52.     !,
  53.     fail.
  54.  
  55. resolve2(N, L, Moves, Ls) :-
  56.     New_moves = append(Moves, [A, Op, B, C]),
  57.     choose(A, L, L1),
  58.     choose1(B, L1),
  59.     findop(A, B, Op, C),
  60.     Diff = abs(target - C),
  61.     cond( Diff < best,
  62.           ( best <<- copy_term(Diff),
  63.         cond(cpu_time - start_time > 10,
  64.              time_display(New_moves, Ls),
  65.              display(New_moves, Ls)))
  66.         ),
  67.     cond( Diff =:= 0,
  68.           time_display(New_moves, Ls),
  69.           res2(N-1, [C|L], New_moves, Ls)
  70.         ).
  71.  
  72. res2(N, NL, Moves, Ls) :-
  73.     resolve2(N, NL, Moves, Ls),
  74.     asserta(solvable(NL)).
  75. res2(N, NL) :-
  76.     N > 3,
  77.     \+solvable(NL),
  78.     asserta(unsolvable(NL)),
  79.     fail.
  80.  
  81. findop(A, B, (+), A+B).
  82. findop(A, B, (-), C) :-
  83.     A > B, A =\= B*2, C = A - B
  84.     ;
  85.     A < B, B =\= A*2, C = B - A
  86.     ;
  87.     B =:= 1, !, fail
  88.     ;
  89.     A =:= 1, !, fail.
  90.  
  91. findop(A, B, (*), A*B).
  92. findop(A, B, (/), C) :- A mod B =:= 0, !, A =\= B*B, C = A/B.
  93. findop(A, B, (/), C) :- B mod A =:= 0, B =\= A*A, C = B/A.
  94.  
  95. choose(X, L:[X|T], T) :- L <- T.
  96. choose(X, [H|T], R) :- choose(X, T, R).
  97.  
  98. choose1(X, L:[X|T]) :- L <- T.
  99. choose1(X, [@|T]) :- choose1(X, T).
  100.  
  101. insert(C, L:[H | T]) -> cond(C >= H, [C|L], [H|insert(C,T)]).
  102. insert(C, []) -> [C].
  103.  
  104. %%%%%%%%%%%%%%%%%%%%%%%%%%%
  105. % THE GRAPHICAL INTERFACE %
  106. %%%%%%%%%%%%%%%%%%%%%%%%%%%
  107.  
  108. import("xtools") ?
  109. import("xtools_utils")?
  110.  
  111. % The necessary widgets:
  112.  
  113. s_box <| frame.
  114. s_box <| field.
  115. s_box <| text_box.
  116.  
  117. :: s_box(frame_state => true,
  118.      text => " ").
  119.  
  120. slot_box := s_box(font_id => z_font,
  121.           offset => d_border).
  122.  
  123. time_box := s_box(font_id => z_font,
  124.           text_color_id => z_color).
  125.  
  126. l_box := text_box(offset => -d_border,
  127.           font_id => title_font).
  128.  
  129. p_button := push_button(font_id => z_font).
  130.  
  131. n_box := text_field_button(number => N:int,
  132.                text => T:"     ",
  133.                action => set_number(N,T),
  134.                offset => 0,
  135.                font_id => title_font,
  136.                text_color_id => z_color).
  137.  
  138. % Colors and fonts
  139.  
  140. color('Blue') -> blue.
  141. color('Green') -> green.
  142. color('Ivory') -> wheat.
  143. color('Red') -> red.
  144. color('Yellow') -> yellow.
  145.  
  146. def_color(main_colors, r, red)?
  147. def_color(main_colors, i, wheat)?
  148. def_color(main_colors, g, green)?
  149. def_color(main_colors, b, blue)?
  150. def_color(main_colors, y, yellow)?
  151. def_color(main_colors, z_color, 'blue violet')?
  152.  
  153. def_font(z_font,
  154.      new_font(cond(life_demo#using_demo_fonts,
  155.                "terminal_bold_narrow18",
  156.                "-adobe-helvetica-bold-r-narrow--17-120-100-100-p-72-*")))?
  157.  
  158. def_font(title_font,
  159.      new_font(cond(life_demo#using_demo_fonts,
  160.                "terminal_bold_narrow28",
  161.                "-adobe-helvetica-bold-r-narrow--25-180-100-100-p-116-*")))?
  162.  
  163. % The control and display panel:
  164.  
  165. mathwiz :-
  166.     (
  167.         C = get_choice,
  168.         Q = p_button(text => "QUIT",
  169.              action => (set_choice(C),fail)),
  170.  
  171.         G = p_button(text => "SOLVE",
  172.              action => (solve(Ls),
  173.                     reset_state(M,false))),
  174.  
  175.         M = p_button(text => "MORE",
  176.              action => more(TB, SB, Ss)),
  177.  
  178.         A = p_button(text => "ANIMATE",
  179.              action => (animate(Ls),
  180.                     reset_state(R,false),
  181.                     reset_state(M,false))),
  182.  
  183.         P = p_button(text => "RANDOM",
  184.              action => random_pick([B0|Bs])),
  185.  
  186.         S = p_button(text => "STOP",
  187.              action => stop),
  188.  
  189.         R = p_button(text => "RESET",
  190.              action => reset_all([TB, SB|Ss])),
  191.  
  192.         same_size([Q,G,M,A,P,S,R]),
  193.  
  194.         B0 = n_box(number=>0, width => 2*W, height => H),
  195.         B1 = n_box(number=>1, width => W,   height => H),
  196.         B2 = n_box(number=>2),
  197.         B3 = n_box(number=>3),
  198.         B4 = n_box(number=>4),
  199.         B5 = n_box(number=>5),
  200.         B6 = n_box(number=>6),
  201.  
  202.         same_size(Bs:[B1,B2,B3,B4,B5,B6]),
  203.  
  204.         Num_boxes = frame_box(vc_list [B0,
  205.                        v_box(10),
  206.                        ht_list [B1,h_box(10),
  207.                             B2,h_box(10),
  208.                             B3],
  209.                        v_box(10),
  210.                        ht_list [B4,h_box(10),
  211.                             B5,h_box(10),
  212.                             B6]
  213.                       ],
  214.                   padding => 10),
  215.  
  216.         S1 = slot_box(width => 200,height => 20),
  217.         S2 = slot_box,
  218.         S3 = slot_box,
  219.         S4 = slot_box,
  220.         S5 = slot_box,
  221.  
  222.         same_size(Ss:[S1,S2,S3,S4,S5]),
  223.  
  224.         Sol_boxes = frame_box(padding => 10,
  225.                   vl_list Ss),
  226.  
  227.         TitleBox = fancy_text_box(text => "Math Wizard",
  228.                       font => title_font,
  229.                       colors => [r,i,g,b,y]),
  230.         
  231.         TimeBox = padded_box
  232.           (padding => 10,
  233.            hc_list [text_box(text => "Total Time",
  234.                  font_id => z_font),
  235.             frame_box(TB:time_box(width => 120,
  236.                           height => 50,
  237.                           text => " "),
  238.                   padding => 3)
  239.                ]
  240.          ),
  241.  
  242.         StatusBox = padded_box
  243.           (padding => 10,
  244.            hc_list [text_box(text => "Status",
  245.                  font_id => z_font),
  246.             frame_box(SB:time_box(width => 120,
  247.                           height => 50,
  248.                           text => " "),
  249.                   padding => 3)
  250.                ]
  251.          ),
  252.  
  253.         Panel = panel(title => "Le compte est bon!...")
  254.           containing
  255.           padded_box(padding => 20,
  256.              ht_list [vl_list [Q, v_box(10),
  257.                        P, v_box(10),
  258.                        G, v_box(10),
  259.                        M, v_box(10),
  260.                        A, v_box(10),
  261.                        S, v_box(10),
  262.                        R
  263.                       ],
  264.                   vr_list [TitleBox,
  265.                        v_box(30),
  266.                        ht_list
  267.                          [h_box(10),
  268.                           Num_boxes,
  269.                           h_box(10),Sol_boxes],
  270.                        v_box(20),
  271.                        ht_list
  272.                          [TimeBox, h_box(30),
  273.                           StatusBox]
  274.                       ]
  275.                  ]),
  276.  
  277.         create_box(Panel),
  278.  
  279.         Ls = @(timebox => TB, morebox=>M, stopbox=>S, statusbox => SB)
  280.           & map(boxify, Ss)
  281.     ;
  282.         succeed
  283.     ).
  284.     
  285. boxify(X) -> @(box => X).
  286.  
  287. % Actions for the control panel buttons:
  288.  
  289. random_pick(Bs) :- choose_random, random_pick2(Bs).
  290.  
  291. random_pick2([B|Bs]) :- !, random_set(B), random_pick2(Bs).
  292. random_pick2([]).
  293.  
  294. choose_random :- !,
  295.     L = [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,25,50,75,100],
  296.     seed.1 <<- remove_nth(L, random(24)),
  297.     seed.2 <<- remove_nth(L, random(23)),
  298.     seed.3 <<- remove_nth(L, random(22)),
  299.     seed.4 <<- remove_nth(L, random(21)),
  300.     seed.5 <<- remove_nth(L, random(20)),
  301.     seed.6 <<- remove_nth(L, random(19)),
  302.     target <<- 100 + random(900).
  303.  
  304. remove_nth(L:[H|T], 0) -> H | L <- T.
  305. remove_nth([@|T], N) -> remove_nth(T, N-1).
  306.  
  307. random_set(B:@(number => 0)) :-
  308.     !, reset_text(B,psi2str(target)).
  309. random_set(B:@(number => N:int))
  310.     :- !, reset_text(B,psi2str(seed.N)).
  311.  
  312. set_number(0,T:string) :- !, target <<- parse(T).
  313. set_number(N,T:string) :- !, seed.N <<- parse(T).
  314.  
  315. persistent(is_reset)?
  316. is_reset <<- true?
  317.  
  318. solve(Ls) :-
  319.     cond(is_reset,
  320.          succeed,
  321.          reset_all(Ls)),
  322.     is_reset <<- false,
  323.     first_sol <<- true,
  324.     best <<- 1000,
  325.     Ls.moves <- @,
  326.     reset_text(Ls.statusbox,"Solving..."),
  327.     (
  328.         stop_point <<- get_choice,
  329.         solution(Ls, false)
  330.     ;
  331.         reset_state(Ls.stopbox, false),   % reached by STOP only
  332.         reset_boxes([Ls.statusbox, Ls.timebox]) 
  333.     ).
  334.  
  335. animate(Ls) :-
  336.     cond(is_reset, succeed, reset_all(Ls)),
  337.     is_reset <<- false,
  338.     first_sol <<- true,
  339.     best <<- 1000,
  340.     Ls.moves <- @,
  341.     reset_text(Ls.statusbox,"Animating..."),
  342.     (
  343.         stop_point <<- get_choice,
  344.         display_moves(Ls),
  345.         solution(Ls, true)
  346.     ;
  347.         reset_state(Ls.stopbox, false),   % reached by STOP only
  348.         reset_boxes([Ls.timebox, Ls.statusbox])
  349.     ).
  350.  
  351. more(TB, SB, Ss) :-
  352.     reset_text(SB, "Retrying..."),
  353.     reset_text(TB, " "),
  354.     reset_boxes(Ss),
  355.     first_sol <<- false,
  356.     try_more,
  357.     beep,
  358.     reset_text(SB, "NO MORE!").
  359.  
  360. stop :-
  361.     cond(is_value(stop_point),
  362.          (set_choice(stop_point), fail),
  363.          succeed).
  364.  
  365. reset_all(L) :- cond(is_reset, succeed,
  366.              (
  367.              clean_cache,
  368.              reset_text(L.timebox, " "),
  369.              reset_boxes(L)
  370.              )).
  371.  
  372. reset_boxes([H|T]) :- !, reset_text(H," "), reset_boxes(T).
  373. reset_boxes([]).
  374.  
  375. clean_cache :- retract(unsolvable(@)), fail.
  376. clean_cache :- retract(solvable(@)), fail.
  377. clean_cache.
  378.  
  379. display_moves(L) :- display(L.moves, L).
  380.  
  381. time_display(Moves, Ls) :-
  382.     reset_text(Ls.timebox,
  383.            strcon(psi2str(cpu_time-start_time), " ms")),
  384.     display(Moves, Ls).
  385.  
  386. display([A,O,B,C|T], [@(box=>Box)|Boxes]) -> true | 
  387.     reset_text(Box,textify(A,O,B,C)),
  388.     display(T, Boxes).
  389. display([], Boxes) -> true |
  390.     clear_boxes(Boxes).
  391.  
  392. clear_boxes([@(box => Box) | Boxes]) :-
  393.     !,
  394.     reset_text(Box, " "),
  395.     clear_boxes(Boxes).
  396. clear_boxes([]).
  397.  
  398. textify(A, (-), B, C) ->
  399.     cond( A < B, 
  400.           strcat(psi2str(B), " - ", psi2str(A), " = ", psi2str(C)),
  401.           strcat(psi2str(A), " - ", psi2str(B), " = ", psi2str(C))).
  402.           
  403. textify(A, (/), B, C) ->
  404.     cond( A < B, 
  405.           strcat(psi2str(B), " / ", psi2str(A), " = ", psi2str(C)),
  406.           strcat(psi2str(A), " / ", psi2str(B), " = ", psi2str(C))).
  407.           
  408.            
  409. textify(A, Op, B, C) ->
  410.     strcat(psi2str(A), " ", psi2str(Op), " ", psi2str(B),
  411.            " = ", psi2str(C)).
  412.  
  413. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  414. % PUTTING TOGETHER THE SOLVER AND THE GRAPHICAL INTERFACE
  415. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  416.  
  417. persistent(try_more)?
  418. try_more <<- succeed?
  419.  
  420. solution(Ls, Show) :-
  421.     try_more <<- fail,
  422.     start_time <<- cpu_time,
  423.     find(Ls, Show, copy_term(start_time)),
  424.     Time = cpu_time-start_time,
  425.     reset_text(Ls.statusbox, "Solved!"),
  426.     reset_text(Ls.timebox, strcon(psi2str(Time)," ms")).
  427.  
  428. solution(list(statusbox => SB, timebox => TB)) :-
  429.     reset_text(SB, (cond(first_sol, "Impossible", "No more!"))),
  430.     reset_text(TB, strcon(psi2str(cpu_time-start_time)," ms")),
  431.     is_reset <<- false,
  432.     beep, beep,
  433.     try_more <<- succeed.
  434.  
  435.