home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / AIE8909.ZIP / TOOLBOX < prev   
Encoding:
Text File  |  1989-09-01  |  13.4 KB  |  511 lines

  1.  
  2.  
  3.                   Filling an Order using Pascal
  4.  
  5.  
  6. procedure ask( var item0 : item;
  7.                var amount : integer);
  8.      begin
  9.      write(" Item ? ");
  10.      read_item( item0 );
  11.      write(" Amount ? ");
  12.      readln( amount)
  13.      end;
  14.  
  15. function fill( var item0 : item ; amount : integer ) : integer;
  16.     begin
  17.      if item0.on_hand >= amount
  18.       then begin
  19.            item0.on_hand := item.on_hand - amount;
  20.            fill := amount
  21.            end
  22.       else fill := 0
  23.     end;
  24.  
  25.  
  26. procedure order;
  27.    var item0 : item;  amount , filled : integer;
  28.    begin
  29.      ask( item0, amount);  { get order info }
  30.      filled := fill( item, amount)  { fill order }
  31.    end;
  32.  
  33.                  Listing 1
  34.  
  35.  
  36.  
  37.     Filling an Order  -- rewritten for Dead End Debugging
  38.  
  39. CONST
  40.   trace_flag = true;
  41.  
  42. function ask( var item0 : item;
  43.                var amount : integer) : boolean;
  44.      begin
  45.      if trace_flag then
  46.          writeln("entering ask");
  47.      write(" Item ? ");
  48.      if read_item( item0 ) then
  49.          begin
  50.          write(" Amount ? ");
  51.          readln( amount)
  52.          ask := true
  53.          end
  54.       else
  55.          begin
  56.            ask := false;
  57.            writeln("ask fails")
  58.          end
  59.       end;
  60.  
  61. function fill( var item0 : item ;
  62.                amount : integer ) : boolean;
  63.     begin
  64.      if trace_flag then
  65.        begin
  66.          write("entering fill, item = ");
  67.          write_item( item0);
  68.          write( "amount = ");
  69.          writeln( amount)
  70.        end;
  71.      if item0.on_hand >= amount
  72.       then begin
  73.            item0.on_hand := item.on_hand - amount;
  74.            fill := true;
  75.            end
  76.       else begin
  77.            writeln("fill fails");
  78.            fill := false
  79.            end
  80.     end;
  81.  
  82.  
  83. boolean function order;
  84.    var item0 : item;  amount ; b1, b2 : boolean;
  85.    begin
  86.      if trace_flag then
  87.        begin
  88.          write("entering order, item = ");
  89.          write_item( item0);
  90.          write( "amount = ");
  91.          writeln( amount);
  92.        end;
  93.      b1 :=  ask( item0, amount);
  94.      if b1 then b2 :=  fill( item0, amount)
  95.         else b2 := false;
  96.      if b1 and b2 then then order := true
  97.                   else begin
  98.                        if trace_flag then writeln("order fails");
  99.                        order := false
  100.                        end
  101.       end;
  102.  
  103.  
  104.                  Listing 2
  105.  
  106. -------------------------------------------------------------------
  107.  
  108.               Order Filling in Prolog
  109.  
  110.  
  111. trace_flag.  % set trace flag to true
  112.  
  113.  
  114. order  :-
  115.       trace_message( trace_flag,
  116.                       $entering order$),
  117.       ask( Item, Amount),   % get order info
  118.       fill( Item, Amount),  % fill it
  119.       !.
  120. order  :-
  121.       fail_message( order ).
  122.  
  123. ask( Item, Amount ) :-
  124.       trace_message( trace_flag, $entering ask$),
  125.       write($item : $),
  126.       read_string( 100, S_item),
  127.       atom_string( Item_name, S_item),
  128.              % get an item from the database
  129.       call( item( Item_info  )),
  130.              % see if it's the one you want
  131.              % if not, backtrack
  132.       frame_slot_val( name, Item_info, Item_name),
  133.       Item = item( Item_info ),
  134.       write($Amount : $),
  135.       read_string( 100, S_amount),
  136.       int_text( Amount, S_amount),
  137.       !.
  138. ask( Item, Amount ) :-
  139.       fail_message( ask   ).
  140.  
  141. fill( Item, Amount) :-
  142.       trace_message( trace_flag, [$entering fill, Item = $,
  143.                                   Item,
  144.                                   $ Amount = $,
  145.                                   Amount]),
  146.      frame_slot_val( on_hand, Item, On_hand ),
  147.      Left_over is On_hand - Amount,
  148.      Left_over > 0,
  149.      update_frame_slot_val( on_hand, Left_over, Item, New_frame),
  150.      retract( Item),
  151.      assert( New_frame).
  152.  
  153. fill( Item, Amount) :-
  154.       fail_message( fill  ).
  155.  
  156. trace_message( Flag , _ ) :-
  157.      call( Flag),
  158.      !.
  159. trace_message( Flag , Message ) :-
  160.      trace_message(  Message ) .
  161.  
  162. trace_message(  Msg) :-
  163.      var( Msg),
  164.      !,
  165.      write( Msg).
  166. trace_message(  [] ) :-
  167.      !,
  168.      nl.
  169. trace_message(   [ H | T ] ) :-
  170.      write(H),
  171.      tab(1),
  172.      trace_message( T ).
  173. trace_message(  X ) :-
  174.     trace_message(  [ X ]) .
  175.  
  176. fail_message( Name ) :-
  177.       write(Name),
  178.       tab(1),
  179.       write( $fails.$),
  180.       nl,
  181.       fail.
  182.  
  183. % some sample items
  184.  
  185. item( [ name : diskettes,
  186.         on_hand : 1000]).
  187.  
  188. item( [ name : prolog_tools,
  189.         on_hand : 10]).
  190.  
  191.  
  192.  
  193.                  Listing 3
  194.  
  195. -------------------------------------------------------------------
  196.  
  197.           Testing for a list of Integers   -- with Bug
  198.  
  199.  
  200. integers( []) :-
  201.     !,
  202.     fail.
  203.  
  204. integers( [H|T]) :-
  205.     integer(H),
  206.     integers(T).
  207.  
  208.  
  209.  
  210.                      Listing 4
  211.  
  212. -------------------------------------------------------------------
  213.  
  214.                Generating Bug Paths
  215.  
  216. /*
  217. gen_bug_reports( In_bug_calls, Out_bug_calls)
  218.  
  219. INPUTS
  220.  
  221.      In_bug_call = list of bug call lists.
  222.  
  223. OUTPUTS
  224.  
  225.      Out_bug_call = list of complete bug call lists, each with innermost
  226.                     call first
  227. */
  228.  
  229.           %  No way to elaborate an empty bug path list.
  230. gen_bug_reports( [], [] ) :- !.
  231.  
  232.           % if the initial bug path is as detailed as our
  233.           % current heuristics permit, then elaborate the
  234.           % paths in the tail of the paths list
  235. gen_bug_reports( [H|T], [H|T1] )  :-
  236.       H = [Inside | _      ]  ,
  237.       complete_bug_report( Inside ), !,
  238.       gen_bug_reports(  T , T1  ).
  239.  
  240.       % otherwise elaborate the head bug report and then elaborate
  241.       % the other bug reports.
  242.       % Note that the head bug report may branch.
  243. gen_bug_reports( [ H | T ], Outputs  )  :-
  244.       H = [Inside | _      ]  ,
  245.       frame_slot_val( failing_subgoal, Inside , Goal ), !,
  246.       current_level_bug_report( Goal,
  247.                                 Current_level_report), !,
  248.       (    Current_level_report == [], !,
  249.            gen_bug_reports( T, Rest  ),
  250.            Outputs = [ H | Rest]
  251.         ;          % add the different current level reports
  252.                    % on the front of the head bug report.  Each
  253.                    % current level report represents one reason
  254.                    % at the next level down why a bug exists
  255.            make_head( Current_level_report, H, New_front_list),
  256.            append( New_front_list, T, New_inputs),
  257.            gen_bug_reports( New_inputs , Outputs   )).
  258.  
  259.  
  260. complete_bug_report( Bug_report ) :-
  261.       frame_slot_val( system_predicate, Bug_report, true),!.
  262.  
  263. complete_bug_report( Bug_report ) :-
  264.       not frame_slot_val( failing_subgoal, Bug_report, _ ),!.
  265.  
  266.  
  267.              Listing 5
  268.  
  269. -------------------------------------------------------------------
  270.  
  271.             A Bug Path List
  272.  
  273. [  % start of bug path list
  274.   [  % start of first bug path
  275.    goal_report([
  276.      system_predicate : true,
  277.      result : fail,
  278.      call : fail,
  279.      reason : $You called fail$]),
  280.  
  281.    goal_report([
  282.      call : integers([]),
  283.      clause_no : 1,
  284.      result : fail,
  285.      failing_subgoal_number : 2,
  286.      failing_subgoal : fail,
  287.      cuts_passed : 1 ]),
  288.  
  289.    goal_report([
  290.      call : integers([1]),
  291.      clause_no : 2,
  292.      result : fail,
  293.      failing_subgoal_number : 2,
  294.      failing_subgoal : integers([]) ]),
  295.  
  296.    goal_report([
  297.     failing_subgoal : integers([1])
  298.     source : user  ])
  299.   ]  % end of only bug path
  300. ]  % end of bug path list
  301.  
  302.                    Listing 6
  303.  
  304. -------------------------------------------------------------------
  305.  
  306.           Reporting a Bug Level
  307.  
  308. /* rule for system predicate failure .
  309.    Here is an example of such a frame:
  310.           Bug report :
  311.           FRAME goal_report
  312.           system_predicate : true
  313.           result : fail
  314.           call : integer(a)
  315.           END_FRAME  */
  316. report_on_bug_level( Bug_at_one_level ) :-
  317.        frame_slot_val(call   , Bug_at_one_level, Call ),
  318.        frame_slot_val(result , Bug_at_one_level, fail ),
  319.        frame_slot_val(system_predicate,
  320.                       Bug_at_one_level,
  321.                       true  ),
  322.        !,
  323.        write_message_with_tab(2,
  324.          [$The call $,
  325.          Call,
  326.          $ to a system predicate failed.$]),
  327.        nl.
  328.  
  329.  
  330. /* rule for when no heads match
  331.      FRAME goal_report
  332.      call : integers(a)
  333.      result : fail
  334.      reason : no_heads_match
  335.      END_FRAME                 */
  336. report_on_bug_level( Bug_at_one_level ) :-
  337.        frame_slot_val(call   , Bug_at_one_level, Call ),
  338.        frame_slot_val(reason , Bug_at_one_level, no_heads_match     ),
  339.        !,
  340.        write_message_with_tab(2,
  341.          [$The goal at this level is $,
  342.          Call,
  343.          $ which failed. $]),
  344.        functor( Call, Name, Arity),
  345.        write_message_with_tab(2,
  346.         [$This is because no heads of rules for $,
  347.          Name / Arity,
  348.          $ match the goal.$  ]),
  349.        nl.
  350.  
  351.               Listing 7
  352.  
  353. --------------------------------------------------------------------
  354.  
  355.               A Bug Report
  356.  
  357. HERE IS THE BUG ANALYSIS :
  358.  
  359. THE TOP LEVEL BUG...
  360.  
  361.      The user-supplied goal integers([1]) failed.
  362.  
  363.  
  364. GOING DOWN A LEVEL,
  365.  
  366.   The goal at this level is integers([1]) which failed.
  367.  
  368.   Clause 2 of integers / 1 failed.
  369.  
  370.   Here it is with the failing subgoal marked.
  371.  
  372.   integers([A|B]) :-
  373.         integer(A),
  374. FAILS==>integers(B).
  375.  
  376.   Instantiated, this subgoal is integers([]).
  377.  
  378.  
  379. GOING DOWN A LEVEL,
  380.  
  381.   The goal at this level is integers([]) which failed.
  382.  
  383.   Clause 1 of integers / 1 failed.
  384.  
  385.   Here it is with the failing subgoal marked.
  386.  
  387.   integers([]) :-
  388.         !,
  389. FAILS==>fail.
  390.  
  391.   Instantiated, this subgoal is fail.
  392.  
  393.  
  394. GOING DOWN A LEVEL,
  395.  
  396.   You called 'fail'.
  397.  
  398.  
  399.      -- ( end of this particular possible bug explanation ) --
  400.  
  401.                  Listing 8
  402.  
  403. --------------------------------------------------------------------
  404.  
  405.           Writing Clauses in User-Friendly Notation
  406.  
  407.      % createss an image of a clause with variables in user-friendly
  408.      %  notation when written with write.
  409.            % try to improve what's there
  410. create_image_to_write(  Clause, Image) :-
  411.    create_image_to_write_hlpr(  Clause, Image),
  412.    !.
  413.            % otherwise use it as is
  414. create_image_to_write(  Clause, Clause) :- !.
  415.  
  416. create_image_to_write_hlpr(  Clause, Image) :-
  417.            % distinguish real strings from variable names
  418.     rewrite_strings( Clause, Image1),         !,
  419.            % create table of variable names
  420.     create_variable_name_table( Clause, Table), !,
  421.            % substitute names for variables
  422.     put_in_var_names( Table, Image1, Image).
  423.  
  424.  
  425.      % This predicate substitutes names for variables in Term to
  426.      % produce Result
  427.               % image of a variable is its name
  428. put_in_var_names( Table, Term, Result   ) :-
  429.        var( Term) ,
  430.        !,
  431.       lookup_var_val( Term ,  Table    , Result).
  432.  
  433.               % image of atoms, numbers, etc. are themselves
  434. put_in_var_names( _    , Term, Term  ) :-
  435.        atomic( Term) ,
  436.        !.
  437.               % image of structures is the structure of the same
  438.               % form built from images of substructures
  439. put_in_var_names( Table, Term, Result) :-
  440.        Term =..List,
  441.        put_in_var_names_for_list(  Table, List, List1),
  442.        Result =.. List1.
  443.  
  444.               % image of a list is the list of images
  445. put_in_var_names_for_list(  _    , [], []) :- !.
  446. put_in_var_names_for_list(  Table, [H | T], [H1 | T1]) :-
  447.     put_in_var_names( Table,  H, H1 ),
  448.     put_in_var_names_for_list(  Table,  T ,  T1 ).
  449.  
  450.  
  451.           % This looks up a variable name in a table.  Arg. 1 is
  452.           % the variable, arg. 2 is the table, and arg. 3 is the
  453.           % name found.  Notice that we have used <I>==<R> for
  454.           % searching the table.  This lets us compare for
  455.           % equivalence without doing unification.  Two
  456.           % variables pass this test only if they are ALREADY
  457.           % unified.
  458. lookup_var_val( Var, []   , Var   ) :- !.
  459. lookup_var_val( Var, [Var1 : Result | _]   , Result) :-
  460.           Var == Var1,
  461.           !.
  462.  
  463. lookup_var_val( Var, [ _  | Rest]   , Result) :-
  464.     lookup_var_val( Var,  Rest    , Result).
  465.  
  466.  
  467.        %  creates table of variables in a clause
  468.        %  with string to represent each
  469. create_variable_name_table( Clause, Table) :-
  470.            % find variables in a clause
  471.        variables( Clause, Vars ),
  472.            % build a table of variable names
  473.        var_table( Vars, Table).
  474.  
  475.  
  476.        % Finds list of variables in a term in order they occur
  477. variables( Term, Variables) :-
  478.              % find variables with repeats
  479.       variables_hlpr( [Term],  Vars0), !,
  480.              % remove repeats of variables
  481.              % This is standard list processing, except that
  482.              % we have to use <I>==<R> instead of <I>=<R>
  483.              % for comparing list items.
  484.       remove_list_equivalents( Vars0, Variables).
  485.  
  486.          % empty list has no variables
  487. variables_hlpr( [], []   ) :- !.
  488.  
  489.          % add a variable to the found variables list
  490. variables_hlpr( [H | T],   [ H | Vars0] ) :-
  491.      var( H ),
  492.      !,
  493.      variables_hlpr( T,  Vars0).
  494.  
  495.          % ignore atoms, numbers, etc.
  496. variables_hlpr( [H | T],   Vars ) :-
  497.      atomic( H ),
  498.      !,
  499.      variables_hlpr( T,   Vars).
  500.  
  501.          % change structures to lists and process the list
  502. variables_hlpr( [H | T],   Vars ) :-
  503.      H =.. List,
  504.      variables_hlpr( List, Vars1),
  505.      variables_hlpr( T, Vars2),
  506.      append( Vars1, Vars2, Vars).
  507.  
  508.  
  509.                Listing 9
  510.  
  511. ables_hlpr(