for review: new tests/tabling directory
Zoltan Somogyi
zs at cs.mu.OZ.AU
Fri Aug 14 08:25:03 AEST 1998
Tyson, please review this. DJ, this has the code of boyer.m, the test case
we discussed.
tests/Mmakefile:
Add the new tabling directory to the list of directories.
tests/tabling/Mmakefile:
tests/tabling/runtests:
The intrastructure of the new tests directory.
tests/tabling/fib.{m,exp}:
A test of the memoing of a det procedure.
tests/tabling/tc_loop.{m,exp}:
A test of loop checking for a nondet procedure.
tests/tabling/tc_minimal.{m,exp}:
A test of minimal model tabling for a nondet procedure.
(Doesn't work yet).
tests/tabling/boyer.{m,exp}:
A benchmark program, translated to Mercury by Bart Demoen
from an original in Prolog.
(Doesn't work yet).
Zoltan.
cvs diff: Diffing .
Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/Mmakefile,v
retrieving revision 1.2
diff -u -u -r1.2 Mmakefile
--- Mmakefile 1997/12/22 09:57:39 1.2
+++ Mmakefile 1998/08/13 02:23:29
@@ -1,4 +1,4 @@
-SUBDIRS = benchmarks general hard_coded invalid misc_tests term valid warnings
+SUBDIRS = benchmarks general hard_coded invalid misc_tests tabling term valid warnings
NUPROLOG_SUBDIRS = benchmarks general
main_target: check
cvs diff: Diffing benchmarks
cvs diff: Diffing debugger
cvs diff: Diffing general
cvs diff: Diffing hard_coded
cvs diff: Diffing hard_coded/typeclasses
cvs diff: Diffing invalid
cvs diff: Diffing misc_tests
cvs diff: Diffing tabling
Index: tabling/Mmakefile
===================================================================
RCS file: Mmakefile
diff -N Mmakefile
--- /dev/null Wed May 28 10:49:58 1997
+++ Mmakefile Thu Aug 13 15:43:13 1998
@@ -0,0 +1,50 @@
+#-----------------------------------------------------------------------------#
+
+main_target: check
+
+include ../Mmake.common
+
+#-----------------------------------------------------------------------------#
+
+PROGS= \
+ fib \
+ tc_loop
+
+# We don't yet pass the following tests:
+# boyer \
+# tc_minimal
+
+#-----------------------------------------------------------------------------#
+
+# at the moment tabling only works with conservative gc
+GRADEFLAGS = --gc conservative
+
+# tc_loop is expected to fail, so we need to ignore the exit status
+# (hence the leading `-')
+tc_loop.out: tc_loop
+ -./tc_loop > tc_loop.out 2>&1;
+
+#-----------------------------------------------------------------------------#
+
+DEPS= $(PROGS:%=%.dep)
+DEPENDS=$(PROGS:%=%.depend)
+OUTS= $(PROGS:%=%.out)
+RESS= $(PROGS:%=%.res)
+
+#-----------------------------------------------------------------------------#
+
+MMAKEFLAGS =
+
+dep: $(DEPS)
+
+depend: $(DEPENDS)
+
+check: $(OUTS) $(RESS)
+
+all: $(PROGS)
+
+clean:
+
+realclean:
+
+#-----------------------------------------------------------------------------#
Index: tabling/boyer.exp
===================================================================
RCS file: boyer.exp
diff -N boyer.exp
--- /dev/null Wed May 28 10:49:58 1997
+++ boyer.exp Thu Aug 13 15:45:04 1998
@@ -0,0 +1 @@
+rewriting...proving...done...
Index: tabling/boyer.m
===================================================================
RCS file: boyer.m
diff -N boyer.m
--- /dev/null Wed May 28 10:49:58 1997
+++ boyer.m Thu Aug 13 16:47:01 1998
@@ -0,0 +1,325 @@
+% generated: 20 November 1989
+% option(s):
+%
+% boyer
+%
+% Evan Tick (from Lisp version by R. P. Gabriel)
+%
+% November 1985
+%
+% prove arithmetic theorem
+
+% in Mercury by Bart Demoen - started 17 Jan 1997
+
+:- module boyer .
+
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module int, list.
+
+main --> boyer.
+
+:- pred boyer(io__state::di, io__state::uo) is det .
+
+boyer -->
+ {wff(Wff)} ,
+ io__write_string("rewriting...") ,
+ { rewrite(Wff,NewWff) } ,
+ io__write_string("proving...") ,
+ ({tautology(NewWff,[],[])} -> io__write_string("done...\n")
+ ; io__write_string("not done ...")
+ ) .
+
+:- type type_wff --->
+ (implies(type_wff,type_wff) ;
+ and(type_wff,type_wff) ;
+ f(type_wff) ;
+ plus(type_wff,type_wff) ;
+ equal(type_wff,type_wff) ;
+ append(type_wff,type_wff) ;
+ lessp(type_wff,type_wff) ;
+ times(type_wff,type_wff) ;
+ reverse(type_wff) ;
+ difference(type_wff,type_wff) ;
+ remainder(type_wff,type_wff) ;
+ member(type_wff,type_wff) ;
+ length(type_wff) ;
+ if(type_wff,type_wff,type_wff) ;
+ a1 ; b1 ; c1 ; d1 ; t1 ; f1 ; x1 ; y1 ; zero ; []
+ ) .
+
+:- pred wff(type_wff) .
+:- mode wff(out) is det .
+
+wff(implies(and(implies(X,Y),
+ and(implies(Y,Z),
+ and(implies(Z,U),
+ implies(U,W)))),
+ implies(X,W))) :-
+ X = f(plus(plus(a1,b1),plus(c1,zero))),
+ Y = f(times(times(a1,b1),plus(c1,d1))),
+ Z = f(reverse(append(append(a1,b1),[]))),
+ U = equal(plus(a1,b1),difference(x1,y1)),
+ W = lessp(remainder(a1,b1),member(a1,length(b1))).
+
+:- pred tautology(type_wff,list(type_wff),list(type_wff)) .
+:- mode tautology(in,in,in) is semidet .
+
+tautology(Wff,Tlist,Flist) :-
+ (truep(Wff,Tlist) -> true
+ ;falsep(Wff,Flist) -> fail
+ ;Wff = if(If,Then,Else) ->
+ (truep(If,Tlist) -> tautology(Then,Tlist,Flist)
+ ;falsep(If,Flist) -> tautology(Else,Tlist,Flist)
+ ;tautology(Then,[If|Tlist],Flist), tautology(Else,Tlist,[If|Flist])
+ )
+ ; fail
+ ).
+
+:- pragma memo(rewrite/2).
+
+:- pred rewrite(type_wff,type_wff) .
+:- mode rewrite(in,out) is det .
+
+rewrite(a1,a1) .
+rewrite(b1,b1) .
+rewrite(c1,c1) .
+rewrite(d1,d1) .
+rewrite(f1,f1) .
+rewrite(t1,t1) .
+rewrite(x1,x1) .
+rewrite(y1,y1) .
+rewrite(zero,zero) .
+rewrite([],[]) .
+
+rewrite(lessp(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = lessp(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(member(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = member(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(remainder(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = remainder(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(plus(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = plus(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(and(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = and(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(equal(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = equal(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(difference(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = difference(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(append(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = append(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(times(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = times(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(implies(X1,X2),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) ,
+ Mid = implies(Y1,Y2) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(length(X1),New) :-
+ rewrite(X1,Y1) ,
+ Mid = length(Y1) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(f(X1),New) :-
+ rewrite(X1,Y1) ,
+ Mid = f(Y1) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(reverse(X1),New) :-
+ rewrite(X1,Y1) ,
+ Mid = reverse(Y1) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+rewrite(if(X1,X2,X3),New) :-
+ rewrite(X1,Y1) , rewrite(X2,Y2) , rewrite(X3,Y3) ,
+ Mid = if(Y1,Y2,Y3) ,
+ (equal(Mid,Next) -> rewrite(Next,New)
+ ;
+ New = Mid
+ ) .
+
+:- pred rewrite_args(list(type_wff),list(type_wff)) .
+:- mode rewrite_args(in,out) is det .
+
+rewrite_args([],[]) .
+rewrite_args([A|RA],[B|RB]) :-
+ rewrite(A,B),
+ rewrite_args(RA,RB).
+
+:- pred truep(type_wff,list(type_wff)) .
+:- mode truep(in,in) is semidet .
+
+truep(Wff,List) :- Wff = t1 -> true ; member_chk(Wff,List) .
+
+:- pred falsep(type_wff,list(type_wff)) .
+:- mode falsep(in,in) is semidet .
+
+falsep(Wff,List) :- Wff = f1 -> true ; member_chk(Wff,List) .
+
+:- pred member_chk(type_wff,list(type_wff)) .
+:- mode member_chk(in,in) is semidet .
+
+member_chk(X,[Y|T]) :- X = Y -> true ; member_chk(X,T).
+
+:- pred equal(type_wff,type_wff) .
+:- mode equal(in,out) is semidet .
+
+equal( and(P,Q),
+ if(P,if(Q,t1,f1),f1)
+ ).
+equal( append(append(X,Y),Z),
+ append(X,append(Y,Z))
+ ).
+equal( difference(A,B),
+ C
+ ) :- difference(A,B,C).
+equal( equal(A,B),
+ C
+ ) :- eq(A,B,C).
+equal( if(if(A,B,C),D,E),
+ if(A,if(B,D,E),if(C,D,E))
+ ).
+equal( implies(P,Q),
+ if(P,if(Q,t1,f1),t1)
+ ).
+equal( length(A),
+ B
+ ) :- mylength(A,B).
+equal( lessp(A,B),
+ C
+ ) :- lessp(A,B,C).
+equal( plus(A,B),
+ C
+ ) :- plus(A,B,C).
+equal( remainder(A,B),
+ C
+ ) :- remainder(A,B,C).
+equal( reverse(append(A,B)),
+ append(reverse(B),reverse(A))
+ ).
+
+:- pred difference(type_wff,type_wff,type_wff) .
+:- mode difference(in,in,out) is semidet .
+
+difference(X,Y,Z) :-
+ (X = Y -> Z = zero
+ ;
+ (X = plus(A,B), Y = plus(A,C) -> Z = difference(B,C)
+ ;
+ X = plus(B,plus(Y,C)) -> Z = plus(B,C) ; fail
+ )
+ ) .
+
+:- pred eq(type_wff,type_wff,type_wff) .
+:- mode eq(in,in,out) is semidet .
+
+eq(append(A,B), append(A,C), equal(B,C)) .
+eq(lessp(X,Y), Z, if(lessp(X,Y),
+ equal(t1,Z),
+ equal(f1,Z))).
+
+:- pred mylength(type_wff,type_wff) .
+:- mode mylength(in,out) is semidet .
+
+mylength(reverse(X),length(X)).
+
+:- pred lessp(type_wff,type_wff,type_wff) .
+:- mode lessp(in,in,out) is semidet .
+
+lessp(plus(X,Y), plus(X,Z), lessp(Y,Z)) :- !.
+
+:- pred plus(type_wff,type_wff,type_wff) .
+:- mode plus(in,in,out) is semidet .
+
+plus(plus(X,Y),Z,
+ plus(X,plus(Y,Z))).
+
+:- pred remainder(type_wff,type_wff,type_wff) .
+:- mode remainder(in,in,out) is semidet .
+
+remainder(U,V,zero) :-
+ (U = V -> true ;
+ U = times(A,B) , (B = V -> true ; A = V)
+ ) .
+
+:- pred times(type_wff,type_wff,type_wff) .
+:- mode times(in,in,out) is semidet .
+
+times(A,B,C) :-
+ (B = plus(Y,Z) -> C = plus(times(A,Y),times(A,Z))
+ ;
+ A = times(X,Y) -> C = times(X,times(Y,B))
+ ;
+ B = difference(CC,W) , C = difference(times(CC,A),times(W,A))
+ ) .
Index: tabling/fib.exp
===================================================================
RCS file: fib.exp
diff -N fib.exp
--- /dev/null Wed May 28 10:49:58 1997
+++ fib.exp Thu Aug 13 16:44:02 1998
@@ -0,0 +1 @@
+tabling works
Index: tabling/fib.m
===================================================================
RCS file: fib.m
diff -N fib.m
--- /dev/null Wed May 28 10:49:58 1997
+++ fib.m Thu Aug 13 16:42:12 1998
@@ -0,0 +1,72 @@
+:- module fib.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is cc_multi.
+
+:- implementation.
+
+:- import_module benchmarking, require, int.
+
+main -->
+ perform_trials(10).
+
+:- pred perform_trials(int::in, io__state::di, io__state::uo) is cc_multi.
+
+perform_trials(N) -->
+ { trial(N, Time, MTime) },
+ % io__write_int(Time),
+ % io__write_string(" "),
+ % io__write_int(MTime),
+ % io__write_string(" \n"),
+ (
+ {
+ Time > 10 * MTime,
+ MTime > 0 % untabled takes ten times as long
+ ;
+ Time > 100, % untabled takes at least 100 ms
+ MTime < 1 % while untabled takes at most 1 ms
+ }
+ ->
+ io__write_string("tabling works\n")
+ ;
+ { Time > 10000 } % Untabled takes at least 10 seconds
+ ->
+ io__write_string("tabling does not appear to work\n")
+ ;
+ % We couldn't get a measurable result with N,
+ % and it looks like we can afford a bigger trial
+ perform_trials(N+3)
+ ).
+
+:- pred trial(int::in, int::out, int::out) is cc_multi.
+
+trial(N, Time, MTime) :-
+ benchmark_det(fib, N, Res, 1, Time),
+ benchmark_det(mfib, N, MRes, 1, MTime),
+ require(unify(Res, MRes), "tabling produces wrong answer").
+
+:- pred fib(int::in, int::out) is det.
+
+fib(N, F) :-
+ ( N < 2 ->
+ F = 1
+ ;
+ fib(N - 1, F1),
+ fib(N - 2, F2),
+ F is F1 + F2
+ ).
+
+:- pred mfib(int::in, int::out) is det.
+:- pragma memo(mfib/2).
+
+mfib(N, F) :-
+ ( N < 2 ->
+ F = 1
+ ;
+ mfib(N - 1, F1),
+ mfib(N - 2, F2),
+ F is F1 + F2
+ ).
Index: tabling/runtests
===================================================================
RCS file: runtests
diff -N runtests
--- /dev/null Wed May 28 10:49:58 1997
+++ runtests Thu Aug 13 15:04:41 1998
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Test whether the code generated by the Mercury compiler
+# is producing the expected output.
+# Return a status of 0 (true) if everything is all right, and 1 otherwise.
+
+. ../handle_options
+. ../startup
+
+mmake $jfactor depend || exit 1
+eval mmake -k $jfactor $gradeopt $flagsopt $cflagsopt check
+checkstatus=$?
+
+cat *.res > .allres
+if test ! -s .allres -a "$checkstatus" = 0
+then
+ echo "the tests in the hard_coded directory succeeded"
+ echo "gradeopt=$gradeopt, flagsopt=$flagsopt, cflagsopt=$cflagsopt"
+ rm -f .allres
+ . ../shutdown
+ exit 0
+else
+ echo "the tests in the hard_coded directory failed"
+ echo "gradeopt=$gradeopt, flagsopt=$flagsopt, cflagsopt=$cflagsopt"
+ echo "the differences are:"
+ cat .allres
+ exit 1
+fi
Index: tabling/tc_loop.exp
===================================================================
RCS file: tc_loop.exp
diff -N tc_loop.exp
--- /dev/null Wed May 28 10:49:58 1997
+++ tc_loop.exp Fri Aug 14 10:21:19 1998
@@ -0,0 +1,2 @@
+Software error: detected infinite recursion in pred tc_loop:tc/2
+Stack dump not available in this grade.
Index: tabling/tc_loop.m
===================================================================
RCS file: tc_loop.m
diff -N tc_loop.m
--- /dev/null Wed May 28 10:49:58 1997
+++ tc_loop.m Thu Aug 13 15:18:24 1998
@@ -0,0 +1,37 @@
+:- module tc_loop.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module std_util, list.
+
+main -->
+ { solutions(tc(1), Solns) },
+ ( { Solns = [] } ->
+ io__write_string("loopcheck failed, tc has no solutions\n")
+ ;
+ io__write_string("loopcheck failed, tc has solutions\n")
+ ).
+
+:- pred tc(int::in, int::out) is nondet.
+:- pragma loop_check(tc/2).
+
+tc(A, B) :-
+ (
+ edge(A, B)
+ ;
+ edge(A, C),
+ tc(C, B)
+ ).
+
+:- pred edge(int::in, int::out) is nondet.
+
+edge(1, 2).
+edge(1, 3).
+edge(2, 1).
+edge(3, 4).
Index: tabling/tc_minimal.exp
===================================================================
RCS file: tc_minimal.exp
diff -N tc_minimal.exp
--- /dev/null Wed May 28 10:49:58 1997
+++ tc_minimal.exp Thu Aug 13 15:43:33 1998
@@ -0,0 +1 @@
+[1, 2, 3, 4]
Index: tabling/tc_minimal.m
===================================================================
RCS file: tc_minimal.m
diff -N tc_minimal.m
--- /dev/null Wed May 28 10:49:58 1997
+++ tc_minimal.m Thu Aug 13 15:38:38 1998
@@ -0,0 +1,34 @@
+:- module tc_minimal.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module std_util, list.
+
+main -->
+ { solutions(tc(1), Solns) },
+ io__write(Solns),
+ io__write_string("\n").
+
+:- pred tc(int::in, int::out) is nondet.
+:- pragma minimal_model(tc/2).
+
+tc(A, B) :-
+ edge(A, C),
+ (
+ B = C
+ ;
+ tc(C, B)
+ ).
+
+:- pred edge(int::in, int::out) is nondet.
+
+edge(1, 2).
+edge(1, 3).
+edge(2, 1).
+edge(3, 4).
cvs diff: Diffing term
cvs diff: Diffing valid
cvs diff: Diffing warnings
More information about the developers
mailing list