diff: extras/trailed_update/var.m changes
Fergus Henderson
fjh at hydra.cs.mu.oz.au
Fri Nov 14 04:14:16 AEDT 1997
Hi,
You have seen part of this before. But I decided to add a test case
before committing, and then the test case discovered a couple of bugs,
so there are now a few more changes...
extras/trailed_update/var.m:
Add new predicate var__is_ground/2.
Also fix a bug: it was not handling unifications between
already-aliased variables correctly.
extras/trailed_update/samples/tests.m:
Add some more test cases.
cvs diff: Diffing .
Index: var.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/extras/trailed_update/var.m,v
retrieving revision 1.7
diff -u -u -r1.7 var.m
--- var.m 1997/11/11 10:25:54 1.7
+++ var.m 1997/11/13 16:08:15
@@ -97,6 +97,25 @@
% dump_var prints out a representation of a variable.
:- pred dump_var(var(T)::in(any), io__state::di, io__state::uo) is cc_multi.
+ % var__is_ground/2 can be used to test if a variable is ground.
+ %
+ % Declaratively, is_ground(Var, Result) is true iff
+ % either Result = no or Var = var(Value) and Result = yes(Value);
+ % that is, it is equivalent to the following clauses:
+ %
+ % is_ground(var(Value), yes(Value)).
+ % is_ground(_, no).
+ %
+ % Operationally, is_ground(Var, Result) returns Result = no
+ % if Var is non-ground, and Result = yes(Value) if Var is ground;
+ % that is, execution will select the first clause if the variable
+ % is ground, and the second clause if the variable is non-ground.
+ %
+ % Beware that is_ground is, and must be, `cc_multi';
+ % making it `det' would not be safe.
+
+:- pred is_ground(var(T)::in(any), maybe(T)::out) is cc_multi.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
@@ -322,6 +341,32 @@
wakeup_delayed_goals(DelayedGoals, Value)
).
+:- pragma c_code( is_ground(Var::in(any), Result::out) /* cc_multi */,
+ may_call_mercury,
+"
+ ML_var_is_ground(TypeInfo_for_T, Var, &Result);
+").
+
+:- pred var__rep_is_ground(var_rep(T), maybe(T)).
+:- mode var__rep_is_ground(in(ptr(var_rep_any)), out) is det.
+:- pragma export(var__rep_is_ground(in(ptr(var_rep_any)), out),
+ "ML_var_is_ground").
+var__rep_is_ground(VarPtr, Result) :-
+ VarPtr = alias(Var),
+ (
+ Var = alias(_),
+ var__rep_is_ground(Var, Result)
+ ;
+ Var = ground(Value),
+ Result = yes(Value)
+ ;
+ Var = free,
+ Result = no
+ ;
+ Var = free(_DelayedGoals),
+ Result = no
+ ).
+
%-----------------------------------------------------------------------------%
%
@@ -739,8 +784,11 @@
var__rep_unify(X, YPtr)
;
X = free,
- % would it be better to deref YPtr here?
- destructively_update_binding(XPtr, YPtr)
+ ( var__identical(XPtr, YPtr) ->
+ true
+ ;
+ destructively_update_binding(XPtr, YPtr)
+ )
;
X = ground(_),
var__rep_unify_gr(X, YPtr)
@@ -792,10 +840,26 @@
;
Y = free(YGoals),
X = free(XGoals),
- XY = free((XGoals, YGoals)),
- destructively_update_binding(XPtr, XY),
- destructively_update_binding(YPtr, XY)
+ ( identical(XPtr, YPtr) ->
+ true
+ ;
+ XY = free((XGoals, YGoals)),
+ destructively_update_binding(XPtr, XY),
+ destructively_update_binding(YPtr, XY)
+ )
).
+
+%-----------------------------------------------------------------------------%
+
+/* impure */
+:- pred identical(var_rep(T), var_rep(T)).
+:- mode identical(in(ptr(var_rep_any)), in(ptr(var_rep_any))) is semidet.
+
+:- pragma c_code(identical(X::in(ptr(var_rep_any)), Y::in(ptr(var_rep_any))),
+ will_not_call_mercury,
+"{
+ SUCCESS_INDICATOR = (X == Y);
+}").
%-----------------------------------------------------------------------------%
cvs diff: Diffing samples
Index: samples/tests.exp
===================================================================
RCS file: /home/staff/zs/imp/mercury/extras/trailed_update/samples/tests.exp,v
retrieving revision 1.2
diff -u -u -r1.2 tests.exp
--- tests.exp 1997/10/07 11:48:04 1.2
+++ tests.exp 1997/11/13 16:54:08
@@ -2,14 +2,23 @@
test_delaying_2: yes
var.m: warning: goal floundered.
1 outstanding delayed goal.
-X = alias(free(<delayed goal>))
-Y = alias(free)
+X = alias(free(<delayed goal>)) [ground: no]
+Y = alias(free) [ground: no]
test_delaying_1: no
test_delaying_2: yes
test_delaying_3: var.m: warning: goal floundered.
1 outstanding delayed goal.
-yes: X = alias(free(<delayed goal>)), Y = alias(free)
+yes: X = alias(free(<delayed goal>)) [ground: no], Y = alias(free) [ground: no]
test_delaying_4: var.m: warning: goal floundered.
1 outstanding delayed goal.
-yes: X = alias(free(<delayed goal>))
+yes: X = alias(free(<delayed goal>)) [ground: no]
+test_ground:
+Z = alias(ground(42)) [ground: yes(42)]
+Z2 = alias(alias(alias(ground(42)))) [ground: yes(42)]
+test_alias_twice:
+A = alias(free) [ground: no]
+B = alias(free) [ground: no]
+test_dup_call_bug:
+A1 = alias(ground(42)) [ground: yes(42)]
+A2 = alias(free) [ground: no]
Done.
Index: samples/tests.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/extras/trailed_update/samples/tests.m,v
retrieving revision 1.1
diff -u -u -r1.1 tests.m
--- tests.m 1997/10/06 18:46:58 1.1
+++ tests.m 1997/11/13 17:10:46
@@ -36,8 +36,8 @@
),
( { create_solvable_delayed_goal(X, Y) } ->
- print("X = "), dump_var(X), nl,
- print("Y = "), dump_var(Y), nl
+ print("X = "), output_var(X), nl,
+ print("Y = "), output_var(Y), nl
;
print("Oops.\n")
),
@@ -57,19 +57,47 @@
print("test_delaying_3: "),
( { create_solvable_delayed_goal(X3, Y3) } ->
- print("yes: X = "), dump_var(X3),
- print(", Y = "), dump_var(Y3), nl
+ print("yes: X = "), output_var(X3),
+ print(", Y = "), output_var(Y3), nl
;
print("no"), nl
),
print("test_delaying_4: "),
( { create_unsolvable_delayed_goal(X4) } ->
- print("yes: X = "), dump_var(X4), nl
+ print("yes: X = "), output_var(X4), nl
;
print("no"), nl
),
+ print("test_ground:"), nl,
+ { Z = var(42) },
+ print("Z = "), output_var(Z), nl,
+ ( { var__init(Z2), var__init(Z3), Z2 = Z3, Z3 = Z } ->
+ print("Z2 = "), output_var(Z2), nl
+ ;
+ print("oops"), nl
+ ),
+ print("test_alias_twice:"), nl,
+ ( { A == B, A = B } ->
+ print("A = "), output_var(A), nl,
+ print("B = "), output_var(B), nl
+ ;
+ print("oops"), nl
+ ),
+ print("test_dup_call_bug:"), nl,
+ ( { var__init(A1), var__init(A2), A1 = var(42) } ->
+ print("A1 = "), output_var(A1), nl,
+ print("A2 = "), output_var(A2), nl
+ ;
+ print("oops"), nl
+ ),
print("Done.\n").
+:- mode output_var(in(any), di, uo) is cc_multi.
+output_var(Var) -->
+ dump_var(Var),
+ { var__is_ground(Var, MaybeVal) },
+ print(" [ground: "), write(MaybeVal), print("]").
+
test_delaying_1 :-
create_solvable_delayed_goal(X, Y),
wake_and_fail(X, Y).
@@ -86,7 +114,7 @@
wake_and_succeed(var(0), var(1)). % 1 = 0 + 1 succeeds
% unsafe_perform_io(print("Y = ")),
-% unsafe_perform_io(dump_var(Y)),
+% unsafe_perform_io(output_var(Y)),
% unsafe_perform_io(nl).
wake_and_fail(var(0), var(42)). % 42 = 0 + 1 fails.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list