src/Tools/Metis/metis.ML
changeset 32740 9dd0a2f83429
parent 30161 c26e515f1c29
child 33004 715566791eb0
equal deleted inserted replaced
32739:31e75ad9ae17 32740:9dd0a2f83429
   393     fun ++ i n = (i + 1) mod n
   393     fun ++ i n = (i + 1) mod n
   394     fun -- i n = (i - 1) mod n
   394     fun -- i n = (i - 1) mod n
   395 in
   395 in
   396 
   396 
   397 abstype 'a queue = QUEUE of {elems: 'a array, (* the contents *)
   397 abstype 'a queue = QUEUE of {elems: 'a array, (* the contents *)
   398                              front: int ref,
   398                              front: int Unsynchronized.ref,
   399                              back: int ref,
   399                              back: int Unsynchronized.ref,
   400                              size: int}  (* fixed size of element array *)
   400                              size: int}  (* fixed size of element array *)
   401 with
   401 with
   402 
   402 
   403   fun is_empty (QUEUE{front=ref ~1, back=ref ~1,...}) = true
   403   fun is_empty (QUEUE{front=Unsynchronized.ref ~1, back=Unsynchronized.ref ~1,...}) = true
   404     | is_empty _ = false
   404     | is_empty _ = false
   405 
   405 
   406   fun mk_queue n init_val =
   406   fun mk_queue n init_val =
   407       if (n < 2)
   407       if (n < 2)
   408       then raise REQUESTED_QUEUE_SIZE_TOO_SMALL
   408       then raise REQUESTED_QUEUE_SIZE_TOO_SMALL
   409       else QUEUE{elems=array(n, init_val), front=ref ~1, back=ref ~1, size=n}
   409       else QUEUE{elems=array(n, init_val), front=Unsynchronized.ref ~1, back=Unsynchronized.ref ~1, size=n}
   410 
   410 
   411   fun clear_queue (QUEUE{front,back,...}) = (front := ~1; back := ~1)
   411   fun clear_queue (QUEUE{front,back,...}) = (front := ~1; back := ~1)
   412 
   412 
   413   fun queue_at Qfront (QUEUE{elems,front,...}) = elems sub !front
   413   fun queue_at Qfront (QUEUE{elems,front,...}) = elems sub !front
   414     | queue_at Qback (QUEUE{elems,back,...}) = elems sub !back
   414     | queue_at Qback (QUEUE{elems,back,...}) = elems sub !back
   457   | ONE_PER_LINE of int
   457   | ONE_PER_LINE of int
   458 
   458 
   459 (* Some global values *)
   459 (* Some global values *)
   460 val INFINITY = 999999
   460 val INFINITY = 999999
   461 
   461 
   462 abstype indent_stack = Istack of break_info list ref
   462 abstype indent_stack = Istack of break_info list Unsynchronized.ref
   463 with
   463 with
   464   fun mk_indent_stack() = Istack (ref([]:break_info list))
   464   fun mk_indent_stack() = Istack (Unsynchronized.ref([]:break_info list))
   465   fun clear_indent_stack (Istack stk) = (stk := ([]:break_info list))
   465   fun clear_indent_stack (Istack stk) = (stk := ([]:break_info list))
   466   fun top (Istack stk) =
   466   fun top (Istack stk) =
   467       case !stk
   467       case !stk
   468         of nil => raise Fail "PP-error: top: badly formed block"
   468         of nil => raise Fail "PP-error: top: badly formed block"
   469 	 | x::_ => x
   469 	 | x::_ => x
   499   fun bottom_delim_stack (Dstack d) = queue_at Qback d
   499   fun bottom_delim_stack (Dstack d) = queue_at Qback d
   500   fun delim_stack_is_empty (Dstack d) = is_empty d
   500   fun delim_stack_is_empty (Dstack d) = is_empty d
   501 end
   501 end
   502 
   502 
   503 
   503 
   504 type block_info = { Block_size : int ref,
   504 type block_info = { Block_size : int Unsynchronized.ref,
   505                     Block_offset : int,
   505                     Block_offset : int,
   506                     How_to_indent : break_style }
   506                     How_to_indent : break_style }
   507 
   507 
   508 
   508 
   509 (* Distance_to_next_break includes Number_of_blanks. Break_offset is
   509 (* Distance_to_next_break includes Number_of_blanks. Break_offset is
   510    a local offset for the break. BB represents a sequence of contiguous
   510    a local offset for the break. BB represents a sequence of contiguous
   511    Begins. E represents a sequence of contiguous Ends.
   511    Begins. E represents a sequence of contiguous Ends.
   512 *)
   512 *)
   513 datatype pp_token
   513 datatype pp_token
   514   = S of  {String : string, Length : int}
   514   = S of  {String : string, Length : int}
   515   | BB of {Pblocks : block_info list ref,   (* Processed   *)
   515   | BB of {Pblocks : block_info list Unsynchronized.ref,   (* Processed   *)
   516            Ublocks : block_info list ref}  (* Unprocessed *)
   516            Ublocks : block_info list Unsynchronized.ref}  (* Unprocessed *)
   517   | E of  {Pend : int ref, Uend : int ref}
   517   | E of  {Pend : int Unsynchronized.ref, Uend : int Unsynchronized.ref}
   518   | BR of {Distance_to_next_break : int ref,
   518   | BR of {Distance_to_next_break : int Unsynchronized.ref,
   519            Number_of_blanks : int,
   519            Number_of_blanks : int,
   520            Break_offset : int}
   520            Break_offset : int}
   521 
   521 
   522 
   522 
   523 (* The initial values in the token buffer *)
   523 (* The initial values in the token buffer *)
   530       linewidth : int,
   530       linewidth : int,
   531       flush : unit -> unit,
   531       flush : unit -> unit,
   532       the_token_buffer : pp_token array,
   532       the_token_buffer : pp_token array,
   533       the_delim_stack : delim_stack,
   533       the_delim_stack : delim_stack,
   534       the_indent_stack : indent_stack,
   534       the_indent_stack : indent_stack,
   535       ++ : int ref -> unit,    (* increment circular buffer index *)
   535       ++ : int Unsynchronized.ref -> unit,    (* increment circular buffer index *)
   536       space_left : int ref,    (* remaining columns on page *)
   536       space_left : int Unsynchronized.ref,    (* remaining columns on page *)
   537       left_index : int ref,    (* insertion index *)
   537       left_index : int Unsynchronized.ref,    (* insertion index *)
   538       right_index : int ref,   (* output index *)
   538       right_index : int Unsynchronized.ref,   (* output index *)
   539       left_sum : int ref,      (* size of strings and spaces inserted *)
   539       left_sum : int Unsynchronized.ref,      (* size of strings and spaces inserted *)
   540       right_sum : int ref}     (* size of strings and spaces printed *)
   540       right_sum : int Unsynchronized.ref}     (* size of strings and spaces printed *)
   541 
   541 
   542 type ppstream = ppstream_
   542 type ppstream = ppstream_
   543 
   543 
   544 type ppconsumer = {consumer : string -> unit,
   544 type ppconsumer = {consumer : string -> unit,
   545 		   linewidth : int,
   545 		   linewidth : int,
   555 		 flush = flush,
   555 		 flush = flush,
   556 		 the_token_buffer = array(buf_size, initial_token_value),
   556 		 the_token_buffer = array(buf_size, initial_token_value),
   557 		 the_delim_stack = new_delim_stack buf_size,
   557 		 the_delim_stack = new_delim_stack buf_size,
   558 		 the_indent_stack = mk_indent_stack (),
   558 		 the_indent_stack = mk_indent_stack (),
   559 		 ++ = fn i => i := ((!i + 1) mod buf_size),
   559 		 ++ = fn i => i := ((!i + 1) mod buf_size),
   560 		 space_left = ref linewidth,
   560 		 space_left = Unsynchronized.ref linewidth,
   561 		 left_index = ref 0, right_index = ref 0,
   561 		 left_index = Unsynchronized.ref 0, right_index = Unsynchronized.ref 0,
   562 		 left_sum = ref 0, right_sum = ref 0}
   562 		 left_sum = Unsynchronized.ref 0, right_sum = Unsynchronized.ref 0}
   563                  ) : ppstream
   563                  ) : ppstream
   564 	 end
   564 	 end
   565 
   565 
   566 fun dest_ppstream(pps : ppstream) =
   566 fun dest_ppstream(pps : ppstream) =
   567   let val PPS{consumer,linewidth,flush, ...} = magic pps
   567   let val PPS{consumer,linewidth,flush, ...} = magic pps
   593    This works because the unprocessed list is treated as a stack, the
   593    This works because the unprocessed list is treated as a stack, the
   594    processed list as a FIFO queue. How can an item on the unprocessed list
   594    processed list as a FIFO queue. How can an item on the unprocessed list
   595    be printable? Because of what goes on in add_string. See there for details.
   595    be printable? Because of what goes on in add_string. See there for details.
   596 *)
   596 *)
   597 
   597 
   598 fun print_BB (_,{Pblocks = ref [], Ublocks = ref []}) =
   598 fun print_BB (_,{Pblocks = Unsynchronized.ref [], Ublocks = Unsynchronized.ref []}) =
   599              raise Fail "PP-error: print_BB"
   599              raise Fail "PP-error: print_BB"
   600   | print_BB (PPS{the_indent_stack,linewidth,space_left=ref sp_left,...},
   600   | print_BB (PPS{the_indent_stack,linewidth,space_left=Unsynchronized.ref sp_left,...},
   601              {Pblocks as ref({How_to_indent=CONSISTENT,Block_size,
   601              {Pblocks as Unsynchronized.ref({How_to_indent=CONSISTENT,Block_size,
   602                               Block_offset}::rst),
   602                               Block_offset}::rst),
   603               Ublocks=ref[]}) =
   603               Ublocks=Unsynchronized.ref[]}) =
   604        (push ((if (!Block_size > sp_left)
   604        (push ((if (!Block_size > sp_left)
   605                then ONE_PER_LINE (linewidth - (sp_left - Block_offset))
   605                then ONE_PER_LINE (linewidth - (sp_left - Block_offset))
   606                else FITS),
   606                else FITS),
   607 	      the_indent_stack);
   607 	      the_indent_stack);
   608         Pblocks := rst)
   608         Pblocks := rst)
   609   | print_BB(PPS{the_indent_stack,linewidth,space_left=ref sp_left,...},
   609   | print_BB(PPS{the_indent_stack,linewidth,space_left=Unsynchronized.ref sp_left,...},
   610              {Pblocks as ref({Block_size,Block_offset,...}::rst),Ublocks=ref[]}) =
   610              {Pblocks as Unsynchronized.ref({Block_size,Block_offset,...}::rst),Ublocks=Unsynchronized.ref[]}) =
   611        (push ((if (!Block_size > sp_left)
   611        (push ((if (!Block_size > sp_left)
   612                then PACK_ONTO_LINE (linewidth - (sp_left - Block_offset))
   612                then PACK_ONTO_LINE (linewidth - (sp_left - Block_offset))
   613                else FITS),
   613                else FITS),
   614 	      the_indent_stack);
   614 	      the_indent_stack);
   615         Pblocks := rst)
   615         Pblocks := rst)
   616   | print_BB (PPS{the_indent_stack, linewidth, space_left=ref sp_left,...},
   616   | print_BB (PPS{the_indent_stack, linewidth, space_left=Unsynchronized.ref sp_left,...},
   617               {Ublocks,...}) =
   617               {Ublocks,...}) =
   618       let fun pr_end_Ublock [{How_to_indent=CONSISTENT,Block_size,Block_offset}] l =
   618       let fun pr_end_Ublock [{How_to_indent=CONSISTENT,Block_size,Block_offset}] l =
   619 		(push ((if (!Block_size > sp_left)
   619 		(push ((if (!Block_size > sp_left)
   620 			then ONE_PER_LINE (linewidth - (sp_left - Block_offset))
   620 			then ONE_PER_LINE (linewidth - (sp_left - Block_offset))
   621 			else FITS),
   621 			else FITS),
   633        in Ublocks := pr_end_Ublock(!Ublocks) []
   633        in Ublocks := pr_end_Ublock(!Ublocks) []
   634       end
   634       end
   635 
   635 
   636 
   636 
   637 (* Uend should always be 0 when print_E is called. *)
   637 (* Uend should always be 0 when print_E is called. *)
   638 fun print_E (_,{Pend = ref 0, Uend = ref 0}) =
   638 fun print_E (_,{Pend = Unsynchronized.ref 0, Uend = Unsynchronized.ref 0}) =
   639       raise Fail "PP-error: print_E"
   639       raise Fail "PP-error: print_E"
   640   | print_E (istack,{Pend, ...}) =
   640   | print_E (istack,{Pend, ...}) =
   641       let fun pop_n_times 0 = ()
   641       let fun pop_n_times 0 = ()
   642 	    | pop_n_times n = (pop istack; pop_n_times(n-1))
   642 	    | pop_n_times n = (pop istack; pop_n_times(n-1))
   643        in pop_n_times(!Pend); Pend := 0
   643        in pop_n_times(!Pend); Pend := 0
   708 
   708 
   709 
   709 
   710 fun pointers_coincide(PPS{left_index,right_index,the_token_buffer,...}) =
   710 fun pointers_coincide(PPS{left_index,right_index,the_token_buffer,...}) =
   711     (!left_index = !right_index) andalso
   711     (!left_index = !right_index) andalso
   712     (case (the_token_buffer sub (!left_index))
   712     (case (the_token_buffer sub (!left_index))
   713        of (BB {Pblocks = ref [], Ublocks = ref []}) => true
   713        of (BB {Pblocks = Unsynchronized.ref [], Ublocks = Unsynchronized.ref []}) => true
   714 	| (BB _) => false
   714 	| (BB _) => false
   715 	| (E {Pend = ref 0, Uend = ref 0}) => true
   715 	| (E {Pend = Unsynchronized.ref 0, Uend = Unsynchronized.ref 0}) => true
   716 	| (E _) => false
   716 	| (E _) => false
   717 	| _ => true)
   717 	| _ => true)
   718 
   718 
   719 fun advance_left (ppstrm as PPS{consumer,left_index,left_sum,
   719 fun advance_left (ppstrm as PPS{consumer,left_index,left_sum,
   720                                 the_token_buffer,++,...},
   720                                 the_token_buffer,++,...},
   730 	  | last_size (_::rst) = last_size rst
   730 	  | last_size (_::rst) = last_size rst
   731           | last_size _ = raise Fail "PP-error: last_size: internal error"
   731           | last_size _ = raise Fail "PP-error: last_size: internal error"
   732 	fun token_size (S{Length, ...}) = Length
   732 	fun token_size (S{Length, ...}) = Length
   733 	  | token_size (BB b) =
   733 	  | token_size (BB b) =
   734 	     (case b
   734 	     (case b
   735                 of {Pblocks = ref [], Ublocks = ref []} =>
   735                 of {Pblocks = Unsynchronized.ref [], Ublocks = Unsynchronized.ref []} =>
   736                      raise Fail "PP-error: BB_size"
   736                      raise Fail "PP-error: BB_size"
   737 	         | {Pblocks as ref(_::_),Ublocks=ref[]} => POS
   737 	         | {Pblocks as Unsynchronized.ref(_::_),Ublocks=Unsynchronized.ref[]} => POS
   738 		 | {Ublocks, ...} => last_size (!Ublocks))
   738 		 | {Ublocks, ...} => last_size (!Ublocks))
   739 	  | token_size (E{Pend = ref 0, Uend = ref 0}) =
   739 	  | token_size (E{Pend = Unsynchronized.ref 0, Uend = Unsynchronized.ref 0}) =
   740               raise Fail "PP-error: token_size.E"
   740               raise Fail "PP-error: token_size.E"
   741 	  | token_size (E{Pend = ref 0, ...}) = NEG
   741 	  | token_size (E{Pend = Unsynchronized.ref 0, ...}) = NEG
   742 	  | token_size (E _) = POS
   742 	  | token_size (E _) = POS
   743 	  | token_size (BR {Distance_to_next_break, ...}) = !Distance_to_next_break
   743 	  | token_size (BR {Distance_to_next_break, ...}) = !Distance_to_next_break
   744 	fun loop (instr) =
   744 	fun loop (instr) =
   745 	    if (token_size instr < 0)  (* synchronization point; cannot advance *)
   745 	    if (token_size instr < 0)  (* synchronization point; cannot advance *)
   746 	    then ()
   746 	    then ()
   759        (We might find ourselves adding a BB to an "old" BB, with the result
   759        (We might find ourselves adding a BB to an "old" BB, with the result
   760        that the index is not pushed onto the delim_stack. This can lead to
   760        that the index is not pushed onto the delim_stack. This can lead to
   761        mangled output.)
   761        mangled output.)
   762     *)
   762     *)
   763 		       (case (the_token_buffer sub (!left_index))
   763 		       (case (the_token_buffer sub (!left_index))
   764 			  of (BB {Pblocks = ref [], Ublocks = ref []}) =>
   764 			  of (BB {Pblocks = Unsynchronized.ref [], Ublocks = Unsynchronized.ref []}) =>
   765 			       (update(the_token_buffer,!left_index,
   765 			       (update(the_token_buffer,!left_index,
   766 				       initial_token_value);
   766 				       initial_token_value);
   767 				++left_index)
   767 				++left_index)
   768 			   | (BB _) => ()
   768 			   | (BB _) => ()
   769 			   | (E {Pend = ref 0, Uend = ref 0}) =>
   769 			   | (E {Pend = Unsynchronized.ref 0, Uend = Unsynchronized.ref 0}) =>
   770 			       (update(the_token_buffer,!left_index,
   770 			       (update(the_token_buffer,!left_index,
   771 				       initial_token_value);
   771 				       initial_token_value);
   772 				++left_index)
   772 				++left_index)
   773 			   | (E _) => ()
   773 			   | (E _) => ()
   774 			   | _ => ++left_index;
   774 			   | _ => ++left_index;
   789 	  right_index := 0;
   789 	  right_index := 0;
   790 	  right_sum := 1)
   790 	  right_sum := 1)
   791     else BB_inc_right_index ppstrm;
   791     else BB_inc_right_index ppstrm;
   792     case (the_token_buffer sub (!right_index))
   792     case (the_token_buffer sub (!right_index))
   793       of (BB {Ublocks, ...}) =>
   793       of (BB {Ublocks, ...}) =>
   794 	   Ublocks := {Block_size = ref (~(!right_sum)),
   794 	   Ublocks := {Block_size = Unsynchronized.ref (~(!right_sum)),
   795 		       Block_offset = offset,
   795 		       Block_offset = offset,
   796 		       How_to_indent = style}::(!Ublocks)
   796 		       How_to_indent = style}::(!Ublocks)
   797        | _ => (update(the_token_buffer, !right_index,
   797        | _ => (update(the_token_buffer, !right_index,
   798 		      BB{Pblocks = ref [],
   798 		      BB{Pblocks = Unsynchronized.ref [],
   799 			 Ublocks = ref [{Block_size = ref (~(!right_sum)),
   799 			 Ublocks = Unsynchronized.ref [{Block_size = Unsynchronized.ref (~(!right_sum)),
   800 					 Block_offset = offset,
   800 					 Block_offset = offset,
   801 					 How_to_indent = style}]});
   801 					 How_to_indent = style}]});
   802 	       push_delim_stack (!right_index, the_delim_stack)))
   802 	       push_delim_stack (!right_index, the_delim_stack)))
   803   end
   803   end
   804 
   804 
   806   let val ppstrm = magic pps : ppstream_
   806   let val ppstrm = magic pps : ppstream_
   807       val PPS{the_token_buffer,the_delim_stack,right_index,...}
   807       val PPS{the_token_buffer,the_delim_stack,right_index,...}
   808             = ppstrm
   808             = ppstrm
   809   in
   809   in
   810     if (delim_stack_is_empty the_delim_stack)
   810     if (delim_stack_is_empty the_delim_stack)
   811     then print_token(ppstrm,(E{Pend = ref 1, Uend = ref 0}))
   811     then print_token(ppstrm,(E{Pend = Unsynchronized.ref 1, Uend = Unsynchronized.ref 0}))
   812     else (E_inc_right_index ppstrm;
   812     else (E_inc_right_index ppstrm;
   813 	  case (the_token_buffer sub (!right_index))
   813 	  case (the_token_buffer sub (!right_index))
   814             of (E{Uend, ...}) => Uend := !Uend + 1
   814             of (E{Uend, ...}) => Uend := !Uend + 1
   815 	     | _ => (update(the_token_buffer,!right_index,
   815 	     | _ => (update(the_token_buffer,!right_index,
   816 			    E{Uend = ref 1, Pend = ref 0});
   816 			    E{Uend = Unsynchronized.ref 1, Pend = Unsynchronized.ref 0});
   817 		     push_delim_stack (!right_index, the_delim_stack)))
   817 		     push_delim_stack (!right_index, the_delim_stack)))
   818   end
   818   end
   819 
   819 
   820 local
   820 local
   821   fun check_delim_stack(PPS{the_token_buffer,the_delim_stack,right_sum,...}) =
   821   fun check_delim_stack(PPS{the_token_buffer,the_delim_stack,right_sum,...}) =
   822       let fun check k =
   822       let fun check k =
   823 	      if (delim_stack_is_empty the_delim_stack)
   823 	      if (delim_stack_is_empty the_delim_stack)
   824 	      then ()
   824 	      then ()
   825 	      else case(the_token_buffer sub (top_delim_stack the_delim_stack))
   825 	      else case(the_token_buffer sub (top_delim_stack the_delim_stack))
   826 		     of (BB{Ublocks as ref ((b as {Block_size, ...})::rst),
   826 		     of (BB{Ublocks as Unsynchronized.ref ((b as {Block_size, ...})::rst),
   827 			    Pblocks}) =>
   827 			    Pblocks}) =>
   828 			   if (k>0)
   828 			   if (k>0)
   829 			   then (Block_size := !right_sum + !Block_size;
   829 			   then (Block_size := !right_sum + !Block_size;
   830 				 Pblocks := b :: (!Pblocks);
   830 				 Pblocks := b :: (!Pblocks);
   831 				 Ublocks := rst;
   831 				 Ublocks := rst;
   860       (if (delim_stack_is_empty the_delim_stack)
   860       (if (delim_stack_is_empty the_delim_stack)
   861        then (left_index := 0; right_index := 0;
   861        then (left_index := 0; right_index := 0;
   862 	     left_sum := 1;   right_sum := 1)
   862 	     left_sum := 1;   right_sum := 1)
   863        else ++right_index;
   863        else ++right_index;
   864        update(the_token_buffer, !right_index,
   864        update(the_token_buffer, !right_index,
   865 	      BR{Distance_to_next_break = ref (~(!right_sum)),
   865 	      BR{Distance_to_next_break = Unsynchronized.ref (~(!right_sum)),
   866 		 Number_of_blanks = n,
   866 		 Number_of_blanks = n,
   867 		 Break_offset = break_offset});
   867 		 Break_offset = break_offset});
   868        check_delim_stack ppstrm;
   868        check_delim_stack ppstrm;
   869        right_sum := (!right_sum) + n;
   869        right_sum := (!right_sum) + n;
   870        push_delim_stack (!right_index,the_delim_stack))
   870        push_delim_stack (!right_index,the_delim_stack))
   897               = ppstrm
   897               = ppstrm
   898         fun fnl [{Block_size, ...}:block_info] = Block_size := INFINITY
   898         fun fnl [{Block_size, ...}:block_info] = Block_size := INFINITY
   899 	  | fnl (_::rst) = fnl rst
   899 	  | fnl (_::rst) = fnl rst
   900           | fnl _ = raise Fail "PP-error: fnl: internal error"
   900           | fnl _ = raise Fail "PP-error: fnl: internal error"
   901 
   901 
   902 	fun set(dstack,BB{Ublocks as ref[{Block_size,...}:block_info],...}) =
   902 	fun set(dstack,BB{Ublocks as Unsynchronized.ref[{Block_size,...}:block_info],...}) =
   903 	      (pop_bottom_delim_stack dstack;
   903 	      (pop_bottom_delim_stack dstack;
   904 	       Block_size := INFINITY)
   904 	       Block_size := INFINITY)
   905 	  | set (_,BB {Ublocks = ref(_::rst), ...}) = fnl rst
   905 	  | set (_,BB {Ublocks = Unsynchronized.ref(_::rst), ...}) = fnl rst
   906 	  | set (dstack, E{Pend,Uend}) =
   906 	  | set (dstack, E{Pend,Uend}) =
   907 	      (Pend := (!Pend) + (!Uend);
   907 	      (Pend := (!Pend) + (!Uend);
   908 	       Uend := 0;
   908 	       Uend := 0;
   909 	       pop_bottom_delim_stack dstack)
   909 	       pop_bottom_delim_stack dstack)
   910 	  | set (dstack,BR{Distance_to_next_break,...}) =
   910 	  | set (dstack,BR{Distance_to_next_break,...}) =
   956    end
   956    end
   957    handle Fail msg =>
   957    handle Fail msg =>
   958      (TextIO.print (">>>> Pretty-printer failure: " ^ msg ^ "\n"))
   958      (TextIO.print (">>>> Pretty-printer failure: " ^ msg ^ "\n"))
   959 
   959 
   960 fun pp_to_string linewidth ppfn ob =
   960 fun pp_to_string linewidth ppfn ob =
   961     let val l = ref ([]:string list)
   961     let val l = Unsynchronized.ref ([]:string list)
   962 	fun attach s = l := (s::(!l))
   962 	fun attach s = l := (s::(!l))
   963      in with_pp {consumer = attach, linewidth=linewidth, flush = fn()=>()}
   963      in with_pp {consumer = attach, linewidth=linewidth, flush = fn()=>()}
   964 		(fn ppstrm =>  ppfn ppstrm ob);
   964 		(fn ppstrm =>  ppfn ppstrm ob);
   965 	String.concat(List.rev(!l))
   965 	String.concat(List.rev(!l))
   966     end
   966     end
   993 
   993 
   994 (* ------------------------------------------------------------------------- *)
   994 (* ------------------------------------------------------------------------- *)
   995 (* Tracing.                                                                  *)
   995 (* Tracing.                                                                  *)
   996 (* ------------------------------------------------------------------------- *)
   996 (* ------------------------------------------------------------------------- *)
   997 
   997 
   998 val tracePrint : (string -> unit) ref
   998 val tracePrint : (string -> unit) Unsynchronized.ref
   999 
   999 
  1000 val trace : string -> unit
  1000 val trace : string -> unit
  1001 
  1001 
  1002 (* ------------------------------------------------------------------------- *)
  1002 (* ------------------------------------------------------------------------- *)
  1003 (* Combinators.                                                              *)
  1003 (* Combinators.                                                              *)
  1226 
  1226 
  1227 val newInt : unit -> int
  1227 val newInt : unit -> int
  1228 
  1228 
  1229 val newInts : int -> int list
  1229 val newInts : int -> int list
  1230 
  1230 
  1231 val withRef : 'r ref * 'r -> ('a -> 'b) -> 'a -> 'b
  1231 val withRef : 'r Unsynchronized.ref * 'r -> ('a -> 'b) -> 'a -> 'b
  1232 
  1232 
  1233 val cloneArray : 'a Metis.Array.array -> 'a Metis.Array.array
  1233 val cloneArray : 'a Metis.Array.array -> 'a Metis.Array.array
  1234 
  1234 
  1235 (* ------------------------------------------------------------------------- *)
  1235 (* ------------------------------------------------------------------------- *)
  1236 (* The environment.                                                          *)
  1236 (* The environment.                                                          *)
  1303 
  1303 
  1304 (* ------------------------------------------------------------------------- *)
  1304 (* ------------------------------------------------------------------------- *)
  1305 (* Tracing                                                                   *)
  1305 (* Tracing                                                                   *)
  1306 (* ------------------------------------------------------------------------- *)
  1306 (* ------------------------------------------------------------------------- *)
  1307 
  1307 
  1308 val tracePrint = ref print;
  1308 val tracePrint = Unsynchronized.ref print;
  1309 
  1309 
  1310 fun trace message = !tracePrint message;
  1310 fun trace message = !tracePrint message;
  1311 
  1311 
  1312 (* ------------------------------------------------------------------------- *)
  1312 (* ------------------------------------------------------------------------- *)
  1313 (* Combinators                                                               *)
  1313 (* Combinators                                                               *)
  1627         looking res' (n - 1) f' (p + 1)
  1627         looking res' (n - 1) f' (p + 1)
  1628       end;
  1628       end;
  1629 
  1629 
  1630   fun calcPrimes n = looking [] n (K true) 2
  1630   fun calcPrimes n = looking [] n (K true) 2
  1631 
  1631 
  1632   val primesList = ref (calcPrimes 10);
  1632   val primesList = Unsynchronized.ref (calcPrimes 10);
  1633 in
  1633 in
  1634   fun primes n = CRITICAL (fn () =>
  1634   fun primes n = CRITICAL (fn () =>
  1635       if length (!primesList) <= n then List.take (!primesList,n)
  1635       if length (!primesList) <= n then List.take (!primesList,n)
  1636       else
  1636       else
  1637         let
  1637         let
  1826 (* ------------------------------------------------------------------------- *)
  1826 (* ------------------------------------------------------------------------- *)
  1827 (* Useful impure features.                                                   *)
  1827 (* Useful impure features.                                                   *)
  1828 (* ------------------------------------------------------------------------- *)
  1828 (* ------------------------------------------------------------------------- *)
  1829 
  1829 
  1830 local
  1830 local
  1831   val generator = ref 0
  1831   val generator = Unsynchronized.ref 0
  1832 in
  1832 in
  1833   fun newInt () = CRITICAL (fn () =>
  1833   fun newInt () = CRITICAL (fn () =>
  1834       let
  1834       let
  1835         val n = !generator
  1835         val n = !generator
  1836         val () = generator := n + 1
  1836         val () = generator := n + 1
  1984 
  1984 
  1985 datatype 'a thunk =
  1985 datatype 'a thunk =
  1986     Value of 'a
  1986     Value of 'a
  1987   | Thunk of unit -> 'a;
  1987   | Thunk of unit -> 'a;
  1988 
  1988 
  1989 datatype 'a lazy = Lazy of 'a thunk ref;
  1989 datatype 'a lazy = Lazy of 'a thunk Unsynchronized.ref;
  1990 
  1990 
  1991 fun delay f = Lazy (ref (Thunk f));
  1991 fun delay f = Lazy (Unsynchronized.ref (Thunk f));
  1992 
  1992 
  1993 fun force (Lazy (ref (Value v))) = v
  1993 fun force (Lazy (Unsynchronized.ref (Value v))) = v
  1994   | force (Lazy (s as ref (Thunk f))) =
  1994   | force (Lazy (s as Unsynchronized.ref (Thunk f))) =
  1995     let
  1995     let
  1996       val v = f ()
  1996       val v = f ()
  1997       val () = s := Value v
  1997       val () = s := Value v
  1998     in
  1998     in
  1999       v
  1999       v
  4139 (* Function caching.                                                         *)
  4139 (* Function caching.                                                         *)
  4140 (* ------------------------------------------------------------------------- *)
  4140 (* ------------------------------------------------------------------------- *)
  4141 
  4141 
  4142 fun cache cmp f =
  4142 fun cache cmp f =
  4143     let
  4143     let
  4144       val cache = ref (Map.new cmp)
  4144       val cache = Unsynchronized.ref (Map.new cmp)
  4145     in
  4145     in
  4146       fn a =>
  4146       fn a =>
  4147          case Map.peek (!cache) a of
  4147          case Map.peek (!cache) a of
  4148            SOME b => b
  4148            SOME b => b
  4149          | NONE =>
  4149          | NONE =>
  4618 
  4618 
  4619 datatype breakStyle = Consistent | Inconsistent
  4619 datatype breakStyle = Consistent | Inconsistent
  4620 
  4620 
  4621 type 'a pp = ppstream -> 'a -> unit
  4621 type 'a pp = ppstream -> 'a -> unit
  4622 
  4622 
  4623 val lineLength : int ref
  4623 val lineLength : int Unsynchronized.ref
  4624 
  4624 
  4625 val beginBlock : ppstream -> breakStyle -> int -> unit
  4625 val beginBlock : ppstream -> breakStyle -> int -> unit
  4626 
  4626 
  4627 val endBlock : ppstream -> unit
  4627 val endBlock : ppstream -> unit
  4628 
  4628 
  4795 
  4795 
  4796 datatype breakStyle = Consistent | Inconsistent
  4796 datatype breakStyle = Consistent | Inconsistent
  4797 
  4797 
  4798 type 'a pp = PP.ppstream -> 'a -> unit;
  4798 type 'a pp = PP.ppstream -> 'a -> unit;
  4799 
  4799 
  4800 val lineLength = ref 75;
  4800 val lineLength = Unsynchronized.ref 75;
  4801 
  4801 
  4802 fun beginBlock pp Consistent = PP.begin_block pp PP.CONSISTENT
  4802 fun beginBlock pp Consistent = PP.begin_block pp PP.CONSISTENT
  4803   | beginBlock pp Inconsistent = PP.begin_block pp PP.INCONSISTENT;
  4803   | beginBlock pp Inconsistent = PP.begin_block pp PP.INCONSISTENT;
  4804 
  4804 
  4805 val endBlock = PP.end_block
  4805 val endBlock = PP.end_block
  5764 (* Parsing and pretty printing.                                              *)
  5764 (* Parsing and pretty printing.                                              *)
  5765 (* ------------------------------------------------------------------------- *)
  5765 (* ------------------------------------------------------------------------- *)
  5766 
  5766 
  5767 (* Infix symbols *)
  5767 (* Infix symbols *)
  5768 
  5768 
  5769 val infixes : Metis.Parser.infixities ref
  5769 val infixes : Metis.Parser.infixities Unsynchronized.ref
  5770 
  5770 
  5771 (* The negation symbol *)
  5771 (* The negation symbol *)
  5772 
  5772 
  5773 val negation : Metis.Name.name ref
  5773 val negation : Metis.Name.name Unsynchronized.ref
  5774 
  5774 
  5775 (* Binder symbols *)
  5775 (* Binder symbols *)
  5776 
  5776 
  5777 val binders : Metis.Name.name list ref
  5777 val binders : Metis.Name.name list Unsynchronized.ref
  5778 
  5778 
  5779 (* Bracket symbols *)
  5779 (* Bracket symbols *)
  5780 
  5780 
  5781 val brackets : (Metis.Name.name * Metis.Name.name) list ref
  5781 val brackets : (Metis.Name.name * Metis.Name.name) list Unsynchronized.ref
  5782 
  5782 
  5783 (* Pretty printing *)
  5783 (* Pretty printing *)
  5784 
  5784 
  5785 val pp : term Metis.Parser.pp
  5785 val pp : term Metis.Parser.pp
  5786 
  5786 
  6135 (* Parsing and pretty printing.                                              *)
  6135 (* Parsing and pretty printing.                                              *)
  6136 (* ------------------------------------------------------------------------- *)
  6136 (* ------------------------------------------------------------------------- *)
  6137 
  6137 
  6138 (* Operators parsed and printed infix *)
  6138 (* Operators parsed and printed infix *)
  6139 
  6139 
  6140 val infixes : Parser.infixities ref = ref
  6140 val infixes : Parser.infixities Unsynchronized.ref = Unsynchronized.ref
  6141   [(* ML symbols *)
  6141   [(* ML symbols *)
  6142    {token = " / ", precedence = 7, leftAssoc = true},
  6142    {token = " / ", precedence = 7, leftAssoc = true},
  6143    {token = " div ", precedence = 7, leftAssoc = true},
  6143    {token = " div ", precedence = 7, leftAssoc = true},
  6144    {token = " mod ", precedence = 7, leftAssoc = true},
  6144    {token = " mod ", precedence = 7, leftAssoc = true},
  6145    {token = " * ", precedence = 7, leftAssoc = true},
  6145    {token = " * ", precedence = 7, leftAssoc = true},
  6172    {token = " -- ", precedence = 6, leftAssoc = true},
  6172    {token = " -- ", precedence = 6, leftAssoc = true},
  6173    {token = " == ", precedence = 4, leftAssoc = true}];
  6173    {token = " == ", precedence = 4, leftAssoc = true}];
  6174 
  6174 
  6175 (* The negation symbol *)
  6175 (* The negation symbol *)
  6176 
  6176 
  6177 val negation : Name.name ref = ref "~";
  6177 val negation : Name.name Unsynchronized.ref = Unsynchronized.ref "~";
  6178 
  6178 
  6179 (* Binder symbols *)
  6179 (* Binder symbols *)
  6180 
  6180 
  6181 val binders : Name.name list ref = ref ["\\","!","?","?!"];
  6181 val binders : Name.name list Unsynchronized.ref = Unsynchronized.ref ["\\","!","?","?!"];
  6182 
  6182 
  6183 (* Bracket symbols *)
  6183 (* Bracket symbols *)
  6184 
  6184 
  6185 val brackets : (Name.name * Name.name) list ref = ref [("[","]"),("{","}")];
  6185 val brackets : (Name.name * Name.name) list Unsynchronized.ref = Unsynchronized.ref [("[","]"),("{","}")];
  6186 
  6186 
  6187 (* Pretty printing *)
  6187 (* Pretty printing *)
  6188 
  6188 
  6189 local
  6189 local
  6190   open Parser;
  6190   open Parser;
 11049 (* Basic conjunctive normal form.                                            *)
 11049 (* Basic conjunctive normal form.                                            *)
 11050 (* ------------------------------------------------------------------------- *)
 11050 (* ------------------------------------------------------------------------- *)
 11051 
 11051 
 11052 val newSkolemFunction =
 11052 val newSkolemFunction =
 11053     let
 11053     let
 11054       val counter : int NameMap.map ref = ref (NameMap.new ())
 11054       val counter : int NameMap.map Unsynchronized.ref = Unsynchronized.ref (NameMap.new ())
 11055     in
 11055     in
 11056       fn n => CRITICAL (fn () =>
 11056       fn n => CRITICAL (fn () =>
 11057       let
 11057       let
 11058         val ref m = counter
 11058         val Unsynchronized.ref m = counter
 11059         val i = Option.getOpt (NameMap.peek m n, 0)
 11059         val i = Option.getOpt (NameMap.peek m n, 0)
 11060         val () = counter := NameMap.insert m (n, i + 1)
 11060         val () = counter := NameMap.insert m (n, i + 1)
 11061       in
 11061       in
 11062         "skolem_" ^ n ^ (if i = 0 then "" else "_" ^ Int.toString i)
 11062         "skolem_" ^ n ^ (if i = 0 then "" else "_" ^ Int.toString i)
 11063       end)
 11063       end)
 11247 (* Conjunctive normal form.                                                  *)
 11247 (* Conjunctive normal form.                                                  *)
 11248 (* ------------------------------------------------------------------------- *)
 11248 (* ------------------------------------------------------------------------- *)
 11249 
 11249 
 11250 val newDefinitionRelation =
 11250 val newDefinitionRelation =
 11251     let
 11251     let
 11252       val counter : int ref = ref 0
 11252       val counter : int Unsynchronized.ref = Unsynchronized.ref 0
 11253     in
 11253     in
 11254       fn () => CRITICAL (fn () =>
 11254       fn () => CRITICAL (fn () =>
 11255       let
 11255       let
 11256         val ref i = counter
 11256         val Unsynchronized.ref i = counter
 11257         val () = counter := i + 1
 11257         val () = counter := i + 1
 11258       in
 11258       in
 11259         "defCNF_" ^ Int.toString i
 11259         "defCNF_" ^ Int.toString i
 11260       end)
 11260       end)
 11261     end;
 11261     end;
 11818 
 11818 
 11819 datatype model =
 11819 datatype model =
 11820     Model of
 11820     Model of
 11821       {size : int,
 11821       {size : int,
 11822        fixed : fixedModel,
 11822        fixed : fixedModel,
 11823        functions : (Term.functionName * int list, int) Map.map ref,
 11823        functions : (Term.functionName * int list, int) Map.map Unsynchronized.ref,
 11824        relations : (Atom.relationName * int list, bool) Map.map ref};
 11824        relations : (Atom.relationName * int list, bool) Map.map Unsynchronized.ref};
 11825 
 11825 
 11826 local
 11826 local
 11827   fun cmp ((n1,l1),(n2,l2)) =
 11827   fun cmp ((n1,l1),(n2,l2)) =
 11828       case String.compare (n1,n2) of
 11828       case String.compare (n1,n2) of
 11829         LESS => LESS
 11829         LESS => LESS
 11832 in
 11832 in
 11833   fun new {size = N, fixed} =
 11833   fun new {size = N, fixed} =
 11834       Model
 11834       Model
 11835         {size = N,
 11835         {size = N,
 11836          fixed = fixed {size = N},
 11836          fixed = fixed {size = N},
 11837          functions = ref (Map.new cmp),
 11837          functions = Unsynchronized.ref (Map.new cmp),
 11838          relations = ref (Map.new cmp)};
 11838          relations = Unsynchronized.ref (Map.new cmp)};
 11839 end;
 11839 end;
 11840 
 11840 
 11841 fun size (Model {size = s, ...}) = s;
 11841 fun size (Model {size = s, ...}) = s;
 11842 
 11842 
 11843 (* ------------------------------------------------------------------------- *)
 11843 (* ------------------------------------------------------------------------- *)
 11903                   (_,[]) => f_tms
 11903                   (_,[]) => f_tms
 11904                 | (v as Term.Var _, tms) => (".", v :: tms)
 11904                 | (v as Term.Var _, tms) => (".", v :: tms)
 11905                 | (Term.Fn (f,tms), tms') => (f, tms @ tms')
 11905                 | (Term.Fn (f,tms), tms') => (f, tms @ tms')
 11906             val elts = map interpret tms
 11906             val elts = map interpret tms
 11907             val f_elts = (f,elts)
 11907             val f_elts = (f,elts)
 11908             val ref funcs = functions
 11908             val Unsynchronized.ref funcs = functions
 11909           in
 11909           in
 11910             case Map.peek funcs f_elts of
 11910             case Map.peek funcs f_elts of
 11911               SOME k => k
 11911               SOME k => k
 11912             | NONE =>
 11912             | NONE =>
 11913               let
 11913               let
 11930       val Model {fixed,relations,...} = M
 11930       val Model {fixed,relations,...} = M
 11931       val {relations = fixed_relations, ...} = fixed
 11931       val {relations = fixed_relations, ...} = fixed
 11932 
 11932 
 11933       val elts = map (interpretTerm M V) tms
 11933       val elts = map (interpretTerm M V) tms
 11934       val r_elts = (r,elts)
 11934       val r_elts = (r,elts)
 11935       val ref rels = relations
 11935       val Unsynchronized.ref rels = relations
 11936     in
 11936     in
 11937       case Map.peek rels r_elts of
 11937       case Map.peek rels r_elts of
 11938         SOME b => b
 11938         SOME b => b
 11939       | NONE =>
 11939       | NONE =>
 11940         let
 11940         let
 14715 
 14715 
 14716 (* ------------------------------------------------------------------------- *)
 14716 (* ------------------------------------------------------------------------- *)
 14717 (* Pretty printing.                                                          *)
 14717 (* Pretty printing.                                                          *)
 14718 (* ------------------------------------------------------------------------- *)
 14718 (* ------------------------------------------------------------------------- *)
 14719 
 14719 
 14720 val showId : bool ref
 14720 val showId : bool Unsynchronized.ref
 14721 
 14721 
 14722 val pp : clause Metis.Parser.pp
 14722 val pp : clause Metis.Parser.pp
 14723 
 14723 
 14724 end
 14724 end
 14725 
 14725 
 14745 (* Helper functions.                                                         *)
 14745 (* Helper functions.                                                         *)
 14746 (* ------------------------------------------------------------------------- *)
 14746 (* ------------------------------------------------------------------------- *)
 14747 
 14747 
 14748 val newId =
 14748 val newId =
 14749     let
 14749     let
 14750       val r = ref 0
 14750       val r = Unsynchronized.ref 0
 14751     in
 14751     in
 14752       fn () => CRITICAL (fn () =>
 14752       fn () => CRITICAL (fn () =>
 14753         case r of ref n => let val () = r := n + 1 in n end)
 14753         case r of Unsynchronized.ref n => let val () = r := n + 1 in n end)
 14754     end;
 14754     end;
 14755 
 14755 
 14756 (* ------------------------------------------------------------------------- *)
 14756 (* ------------------------------------------------------------------------- *)
 14757 (* A type of clause.                                                         *)
 14757 (* A type of clause.                                                         *)
 14758 (* ------------------------------------------------------------------------- *)
 14758 (* ------------------------------------------------------------------------- *)
 14775 
 14775 
 14776 (* ------------------------------------------------------------------------- *)
 14776 (* ------------------------------------------------------------------------- *)
 14777 (* Pretty printing.                                                          *)
 14777 (* Pretty printing.                                                          *)
 14778 (* ------------------------------------------------------------------------- *)
 14778 (* ------------------------------------------------------------------------- *)
 14779 
 14779 
 14780 val showId = ref false;
 14780 val showId = Unsynchronized.ref false;
 14781 
 14781 
 14782 local
 14782 local
 14783   val ppIdThm = Parser.ppPair Parser.ppInt Thm.pp;
 14783   val ppIdThm = Parser.ppPair Parser.ppInt Thm.pp;
 14784 in
 14784 in
 14785   fun pp p (Clause {id,thm,...}) =
 14785   fun pp p (Clause {id,thm,...}) =
 16370 
 16370 
 16371 (* ------------------------------------------------------------------------- *)
 16371 (* ------------------------------------------------------------------------- *)
 16372 (* Mapping TPTP functions and relations to different names.                  *)
 16372 (* Mapping TPTP functions and relations to different names.                  *)
 16373 (* ------------------------------------------------------------------------- *)
 16373 (* ------------------------------------------------------------------------- *)
 16374 
 16374 
 16375 val functionMapping : {name : string, arity : int, tptp : string} list ref
 16375 val functionMapping : {name : string, arity : int, tptp : string} list Unsynchronized.ref
 16376 
 16376 
 16377 val relationMapping : {name : string, arity : int, tptp : string} list ref
 16377 val relationMapping : {name : string, arity : int, tptp : string} list Unsynchronized.ref
 16378 
 16378 
 16379 (* ------------------------------------------------------------------------- *)
 16379 (* ------------------------------------------------------------------------- *)
 16380 (* TPTP literals.                                                            *)
 16380 (* TPTP literals.                                                            *)
 16381 (* ------------------------------------------------------------------------- *)
 16381 (* ------------------------------------------------------------------------- *)
 16382 
 16382 
 16489 
 16489 
 16490 (* ------------------------------------------------------------------------- *)
 16490 (* ------------------------------------------------------------------------- *)
 16491 (* Mapping TPTP functions and relations to different names.                  *)
 16491 (* Mapping TPTP functions and relations to different names.                  *)
 16492 (* ------------------------------------------------------------------------- *)
 16492 (* ------------------------------------------------------------------------- *)
 16493 
 16493 
 16494 val functionMapping = ref
 16494 val functionMapping = Unsynchronized.ref
 16495     [(* Mapping TPTP functions to infix symbols *)
 16495     [(* Mapping TPTP functions to infix symbols *)
 16496      {name = "*", arity = 2, tptp = "multiply"},
 16496      {name = "*", arity = 2, tptp = "multiply"},
 16497      {name = "/", arity = 2, tptp = "divide"},
 16497      {name = "/", arity = 2, tptp = "divide"},
 16498      {name = "+", arity = 2, tptp = "add"},
 16498      {name = "+", arity = 2, tptp = "add"},
 16499      {name = "-", arity = 2, tptp = "subtract"},
 16499      {name = "-", arity = 2, tptp = "subtract"},
 16502      (* Expanding HOL symbols to TPTP alphanumerics *)
 16502      (* Expanding HOL symbols to TPTP alphanumerics *)
 16503      {name = ":", arity = 2, tptp = "has_type"},
 16503      {name = ":", arity = 2, tptp = "has_type"},
 16504      {name = ".", arity = 2, tptp = "apply"},
 16504      {name = ".", arity = 2, tptp = "apply"},
 16505      {name = "<=", arity = 0, tptp = "less_equal"}];
 16505      {name = "<=", arity = 0, tptp = "less_equal"}];
 16506 
 16506 
 16507 val relationMapping = ref
 16507 val relationMapping = Unsynchronized.ref
 16508     [(* Mapping TPTP relations to infix symbols *)
 16508     [(* Mapping TPTP relations to infix symbols *)
 16509      {name = "=", arity = 2, tptp = "="},
 16509      {name = "=", arity = 2, tptp = "="},
 16510      {name = "==", arity = 2, tptp = "equalish"},
 16510      {name = "==", arity = 2, tptp = "equalish"},
 16511      {name = "<=", arity = 2, tptp = "less_equal"},
 16511      {name = "<=", arity = 2, tptp = "less_equal"},
 16512      {name = "<", arity = 2, tptp = "less_than"},
 16512      {name = "<", arity = 2, tptp = "less_than"},