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 |
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. *) |
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 |
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 |
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"}, |