[m-rev.] for review: use limited_deconstruct in sized_pretty.m

Mark Brown dougl at cs.mu.OZ.AU
Tue Jun 26 04:53:53 AEST 2001


This is for review by Zoltan.

Estimated hours taken: 4
Branches: main

Make mdb's term browser use limited_deconstruct/5 instead of deconstruct/4,
to avoid performance problems with large arrays.

browser/sized_pretty.m:
	Add a new function, maximum_functors, to the measure_with_params
	typeclass.  This calculates an upper bound for the number of
	functors that could be displayed within the given measurement.
	Implement this function for each of the typeclass instances.

	In the first pass, use this new function to calculate the limit for
	limited_deconstruct.  If this predicate fails, then the term is
	flagged as 'not_deconstructed'.  This means we won't attempt to
	deconstruct the term in the second pass, either.

	Replace deconstruct/4 with functor/3 in cases where the
	arguments are not required.

	Remove flag_with, which adds the same flag to each of a list of
	arguments.  Instead, pass the flag itself to
	annotate_args_with_size, which was the only predicate to use the
	arguments flagged in this way.

	Remove annotate_args_with_zero_size, since it is not used.

Index: browser/sized_pretty.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/sized_pretty.m,v
retrieving revision 1.1
diff -u -r1.1 sized_pretty.m
--- browser/sized_pretty.m	2001/02/23 04:14:41	1.1
+++ browser/sized_pretty.m	2001/06/25 18:19:07
@@ -218,6 +218,11 @@
 	func add_measures(T, T, MeasureParams) = T is det,
 	func subtract_measures(T, T, MeasureParams) = T is det,
 
+		% Given a measurement and the measure parameters,
+		% calculate an upper bound on the number of functors
+		% that could fit in that space.
+	func maximum_functors(T, MeasureParams) = int,
+
 		% given a term, it's arity, and a limit, this method decides
 		% the partial limit that each of the argument should be
 		% given. It's arguments in order are term, measure parameter(s),
@@ -246,7 +251,7 @@
 	% character_count(LineWidth - 3).
 univ_to_string_line(Univ, LineWidth, Lines, String) :-
 	Params = measure_params(LineWidth),
-	deconstruct(univ_value(Univ), _, Arity, _),
+	functor(univ_value(Univ), _, Arity),
 	( 	Arity \= 0,
 		Lines \= 0,
 		(Lines - 1) // Arity = 0 
@@ -282,35 +287,41 @@
 	<= measure_with_params(T, MeasureParams).
 
 first_pass(Univ, Params, Limit, Size) :-
-	deconstruct(univ_value(Univ), Functor, Arity, Args),	
-	measured_split(Univ, Params, Limit, Arity, yes, FunctorSize, 
-					Flag, NewLimit, NewParams),
-	flag_with(Args, Flag, FlaggedUnivArgs),
-	( (Arity \= 0, Flag = no) ->
-		Exact0 = no
-	;
-		Exact0 = yes
-	),
-        annotate_args_with_size(FlaggedUnivArgs, NewParams, NewLimit, 
-		FunctorSize, SoFar, Exact0, Exact, MaybeArgSizes),
+	MaxFunctors = maximum_functors(Limit, Params),
 	(
-		Exact = no,
-	        Size = at_least(Univ, SoFar,
-	                        deconstructed(Functor, Arity, MaybeArgSizes))
+		limited_deconstruct(univ_value(Univ), MaxFunctors,
+				Functor, Arity, UnivArgs)
+	->
+		measured_split(Univ, Params, Limit, Arity, yes, FunctorSize, 
+						Flag, NewLimit, NewParams),
+		( (Arity \= 0, Flag = no) ->
+			Exact0 = no
+		;
+			Exact0 = yes
+		),
+		annotate_args_with_size(UnivArgs, Flag, NewParams, NewLimit, 
+			FunctorSize, SoFar, Exact0, Exact, MaybeArgSizes),
+		(
+			Exact = no,
+			Size = at_least(Univ, SoFar,
+				deconstructed(Functor, Arity, MaybeArgSizes))
+		;
+			Exact = yes,
+			Size = exact(Univ, SoFar, Functor, Arity, MaybeArgSizes)
+		)
 	;
-	        Exact = yes,
-	        Size = exact(Univ, SoFar, Functor, Arity, MaybeArgSizes)
+		Size = at_least(Univ, zero_measure, not_deconstructed)
 	).
 
 %------------------------------------------------------------------------------%
 	% annotating the arguments.
-:- pred annotate_args_with_size(assoc_list(maybe(T), univ)::in,
+:- pred annotate_args_with_size(list(univ)::in, maybe(T)::in,
 	MeasureParams::in, T::in, T::in, T::out, bool::in, bool::out, 
 	size_annotated_args(T)::out) is det <= measure_with_params(T, 
 	MeasureParams).
 
-annotate_args_with_size([], _, _, SoFar, SoFar, Exact, Exact, []).
-annotate_args_with_size([Flag - Arg | FlaggedArgs], Params, Limit,
+annotate_args_with_size([], _, _, _, SoFar, SoFar, Exact, Exact, []).
+annotate_args_with_size([Arg | Args], Flag, Params, Limit,
 		SoFar0, SoFar, Exact0, Exact,
 		[MaybeFlaggedSize | MaybeFlaggedSizes]) :-
 	(
@@ -343,28 +354,10 @@
 	;
 		Exact2 = Exact1
 	),
-	annotate_args_with_size(FlaggedArgs, Params, Limit, SoFar1, SoFar, 
+	annotate_args_with_size(Args, Flag, Params, Limit, SoFar1, SoFar, 
 		Exact2, Exact, MaybeFlaggedSizes).
 
 %------------------------------------------------------------------------------%
-	% Annotates the arguments with zero limit.
-:- pred annotate_args_with_zero_size(assoc_list(maybe(T), univ)::in, T::in,
-	size_annotated_args(T)::out) is det <= measure(T).
-
-annotate_args_with_zero_size([], _, []).
-annotate_args_with_zero_size([Flag - Univ | FlaggedArgs], ZeroMeasure,
-		[FlaggedSize | FlaggedSizes]) :-
-	(
-		Flag = yes(ArgLimit),
-		FlaggedSize = yes(ArgLimit -
-			at_least(Univ, ZeroMeasure, not_deconstructed))
-	;
-		Flag = no,
-		FlaggedSize = no
-	),
-	annotate_args_with_zero_size(FlaggedArgs, ZeroMeasure, FlaggedSizes).
-
-%------------------------------------------------------------------------------%
 
 :- func extract_size_from_annotation(size_annotated_term(T)) = T.
 
@@ -527,7 +520,7 @@
 :- func to_doc_sized(size_annotated_term(T)) = doc.
 
 to_doc_sized(at_least(Univ, _, not_deconstructed)) = Doc :-
-	deconstruct(univ_value(Univ), Functor, Arity, _Args),
+	functor(univ_value(Univ), Functor, Arity),
 	Doc = text(Functor) `<>` text("/") `<>` poly(i(Arity)).
 
 to_doc_sized(at_least(_, _, deconstructed(Functor, Arity, MaybeArgs))) = Doc :-
@@ -561,15 +554,6 @@
 handle_arg(no) = nil.
 
 %------------------------------------------------------------------------------%
-	% A predicate that creates an associated list of Univ and their
-	% individual Limit
-:- pred flag_with(list(univ)::in, maybe(T)::in, assoc_list(maybe(T), univ)::out)
-	is det.
-flag_with([], _, []).
-flag_with([Arg | Args], Flag, [Flag - Arg | FlaggedArgs]) :-
-	flag_with(Args, Flag, FlaggedArgs).
-
-%------------------------------------------------------------------------------%
 	% functor_count is a representation where the size of a term
 	% is measured by the number of function symbols.
 
@@ -587,6 +571,10 @@
 subtract_functor_count(functor_count(A), functor_count(B), _) =
 	functor_count(A - B).
 
+:- func maximum_functor_count(functor_count, no_measure_params) = int.
+
+maximum_functor_count(functor_count(N), _) = N.
+
 :- func compare_functor_count(functor_count, functor_count) = comparison_result.
 
 compare_functor_count(functor_count(A), functor_count(B)) = R :-
@@ -627,6 +615,7 @@
 :- instance measure_with_params(functor_count, no_measure_params) where [
 	func(add_measures/3) is add_functor_count,
 	func(subtract_measures/3) is subtract_functor_count,
+	func(maximum_functors/2) is maximum_functor_count,
 	pred(measured_split/9) is functor_count_split
 ].
 
@@ -648,6 +637,12 @@
 subtract_char_count(char_count(A), char_count(B), _) =
 	char_count(A - B).
 
+:- func maximum_char_count(char_count, no_measure_params) = int.
+
+maximum_char_count(char_count(N), _) = Max :-
+	% Each functor except the first takes a minimum of three chars.
+	Max = (N + 2) div 3.
+
 :- func compare_char_count(char_count, char_count) = comparison_result.
 
 compare_char_count(char_count(A), char_count(B)) = R :-
@@ -695,6 +690,7 @@
 :- instance measure_with_params(char_count, no_measure_params) where [
         func(add_measures/3) is add_char_count,
         func(subtract_measures/3) is subtract_char_count,
+	func(maximum_functors/2) is maximum_char_count,
         pred(measured_split/9) is char_count_split
 ].
 
@@ -781,6 +777,19 @@
 		Result = line_count(0)
 	).
 
+:- func maximum_size_count(size_count, measure_params) = int.
+
+maximum_size_count(character_count(N), _) = Max :-
+	% Each functor except the first takes a minimum of three chars.
+	Max = (N + 2) div 3.
+
+maximum_size_count(line_count(N), measure_params(LineWidth)) = Max :-
+	% We can't assume any particular layout, so we go by how many
+	% functors will fit in the area covered by N lines.  Each functor
+	% except the first takes a minimum of three chars.
+	Area = N * LineWidth,
+	Max = (Area + 2) div 3.
+
 :- func compare_size_count(size_count, size_count) = comparison_result.
 
 compare_size_count(character_count(C1), character_count(C2)) = R :-
@@ -890,6 +899,7 @@
 :- instance measure_with_params(size_count, measure_params) where [
 	func(add_measures/3) is add_size_count,
 	func(subtract_measures/3) is subtract_size_count,
+	func(maximum_functors/2) is maximum_size_count,
 	pred(measured_split/9) is size_count_split
 ].
 
@@ -901,7 +911,7 @@
 
 get_arg_length([], 0, 0).
 get_arg_length([HeadUniv | Rest], TotalLength, MaxLength) :-
-	deconstruct(univ_value(HeadUniv), Functor, Arity, _),
+	functor(univ_value(HeadUniv), Functor, Arity),
 	( Rest = [] ->
 		Correction = 2
 	;
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list