[m-rev.] for review: fix readline problems
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Dec 11 15:50:23 AEDT 2001
The nightly tests have been failing on ceres, due to a problem
with readline 4.2 issuing unsuppressable runtime warnings.
This change should, I hope, fix that problem.
----------
Estimated hours taken: 4
Branches: main
Fix some problems with mdb and readline 4.2 that arose due to the use
of readline when input is redirected from an input file. Readline 4.2
issues a run-time warning, complaining that it can't get the terminal
characteristics.
One unfortunate consequence of this change is that none of the test
cases in our test suite actually test the use of readline anymore.
However, none of the line-editing features were being tested anyway,
and it's not really possible to test the use of readline properly
with our current test framework.
configure.in:
runtime/mercury_conf.h.in:
Check for the existence of isatty().
trace/mercury_trace_readline.c:
Only use readline() if the input is a terminal.
trace/mercury_trace_internal.c:
Delete the special handling of the `echo' command when readline
is enabled, because whether or not readline is enabled now has
no effect on echoing when the input is not a terminal.
Double-echoing when the input *is* a terminal and the "echo on"
command was used is probably appropriate anyway.
tests/debugger/Mmakefile:
tests/debugger/interactive.inp:
tests/debugger/interactive.exp:
Reenable the `interactive' test case, since the spurious
readline-related failures should not occur anymore.
This required updating the input file and expected output
file to reflect various earlier changes:
- readline is used for query input, so queries have to be all on one line;
- queries are now echoed properly when `echo on' is set;
- detailed stack traces include goal paths
- we fixed a bug with the display of caller line numbers
- we fixed a bug with the display of switch goal paths
Workspace: /home/ceres/fjh/mercury
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.284
diff -u -d -r1.284 configure.in
--- configure.in 3 Dec 2001 03:11:22 -0000 1.284
+++ configure.in 11 Dec 2001 04:40:32 -0000
@@ -436,7 +436,7 @@
ac_cv_func_mprotect=no ;;
esac
AC_HAVE_FUNCS(sysconf getpagesize memalign mprotect sigaction setitimer)
-AC_HAVE_FUNCS(strerror memmove dup fileno fdopen fstat stat)
+AC_HAVE_FUNCS(strerror memmove dup fileno fdopen fstat stat isatty)
AC_HAVE_FUNCS(snprintf vsnprintf _vsnprintf)
AC_HAVE_FUNCS(gethostname getpid)
#-----------------------------------------------------------------------------#
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.38
diff -u -d -r1.38 mercury_conf.h.in
--- runtime/mercury_conf.h.in 31 Oct 2001 17:53:37 -0000 1.38
+++ runtime/mercury_conf.h.in 11 Dec 2001 02:57:49 -0000
@@ -170,6 +170,7 @@
** Note that fileno() may be a macro
** rather than a function, so you should use
** #if defined(fileno) || defined(HAVE_FILENO)
+** HAVE_ISATTY we have the isatty() function.
*/
#undef HAVE_GETPID
#undef HAVE_GETHOSTNAME
@@ -192,6 +193,7 @@
#undef HAVE_FSTAT
#undef HAVE_FDOPEN
#undef HAVE_FILENO
+#undef HAVE_ISATTY
/*
** RETSIGTYPE: the return type of signal handlers.
Index: trace/mercury_trace_readline.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_readline.c,v
retrieving revision 1.5
diff -u -d -r1.5 mercury_trace_readline.c
--- trace/mercury_trace_readline.c 15 May 2000 16:37:46 -0000 1.5
+++ trace/mercury_trace_readline.c 11 Dec 2001 03:46:26 -0000
@@ -30,6 +30,9 @@
#ifdef HAVE_READLINE_HISTORY
#include "readline/history.h"
#endif
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h> /* for isatty() */
+ #endif
#endif
#include <stdio.h>
@@ -48,43 +51,45 @@
char *
MR_trace_readline(const char *prompt, FILE *in, FILE *out)
{
- char *line;
-
-#ifdef MR_NO_USE_READLINE
-
- fprintf(out, "%s", prompt);
- fflush(out);
- line = MR_trace_readline_raw(in);
-
-#else /* use readline */
+#if (defined(isatty) || defined(HAVE_ISATTY)) \
+ && (defined(fileno) || defined(HAVE_FILENO)) \
+ && !defined(MR_NO_USE_READLINE)
+ /* use readline, if the input file is a terminal */
+ if (isatty(fileno(in))) {
+ char *line;
- rl_instream = in;
- rl_outstream = out;
+ rl_instream = in;
+ rl_outstream = out;
- line = readline((char *) prompt);
+ line = readline((char *) prompt);
- /*
- ** readline() allocates with malloc(), and we want
- ** to return something allocated with MR_malloc(),
- ** but that's OK, because MR_malloc() and malloc()
- ** are interchangable.
- */
+ /*
+ ** readline() allocates with malloc(), and we want
+ ** to return something allocated with MR_malloc(),
+ ** but that's OK, because MR_malloc() and malloc()
+ ** are interchangable.
+ */
#if 0
- {
- char *tmp = line;
+ {
+ char *tmp = line;
- line = MR_copy_string(line);
- free(tmp);
- }
+ line = MR_copy_string(line);
+ free(tmp);
+ }
#endif
- if (line != NULL && line[0] != '\0') {
- add_history(line);
- }
+ if (line != NULL && line[0] != '\0') {
+ add_history(line);
+ }
-#endif
+ return line;
+ }
+#endif /* have isatty && have fileno && !MR_NO_USE_READLINE */
- return line;
+ /* otherwise, don't use readline */
+ fprintf(out, "%s", prompt);
+ fflush(out);
+ return MR_trace_readline_raw(in);
}
/*
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.109
diff -u -d -r1.109 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 4 Dec 2001 00:44:39 -0000 1.109
+++ trace/mercury_trace_internal.c 11 Dec 2001 03:38:36 -0000
@@ -91,14 +91,10 @@
static int MR_scroll_next = 0;
/*
-** We echo each command just as it is executed iff this variable is TRUE,
-** unless we're using GNU readline. If we're using readline, then readline
-** echos things anyway, so in that case we ignore this variable.
+** We echo each command just as it is executed iff this variable is TRUE.
*/
-#ifdef MR_NO_USE_READLINE
static bool MR_echo_commands = FALSE;
-#endif
/*
** The details of the source server, if any.
@@ -1815,31 +1811,21 @@
} else if (streq(words[0], "echo")) {
if (word_count == 2) {
if (streq(words[1], "off")) {
-#ifdef MR_NO_USE_READLINE
MR_echo_commands = FALSE;
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out,
"Command echo disabled.\n");
}
-#else
- /* with readline, echoing is always enabled */
- fprintf(MR_mdb_err, "Sorry, cannot disable "
- "echoing when using GNU readline.\n");
-
-#endif
} else if (streq(words[1], "on")) {
-#ifdef MR_NO_USE_READLINE
if (!MR_echo_commands) {
/*
** echo the `echo on' command
- ** This is needed for testing, so that
- ** we get the same output both with
- ** and without readline.
+ ** This is needed for historical reasons
+ ** (compatibly with out existing test suite).
*/
fprintf(MR_mdb_out, "echo on\n");
MR_echo_commands = TRUE;
}
-#endif
if (MR_trace_internal_interacting) {
fprintf(MR_mdb_out,
"Command echo enabled.\n");
@@ -1849,17 +1835,11 @@
}
} else if (word_count == 1) {
fprintf(MR_mdb_out, "Command echo is ");
-#ifdef MR_NO_USE_READLINE
if (MR_echo_commands) {
fprintf(MR_mdb_out, "on.\n");
} else {
fprintf(MR_mdb_out, "off.\n");
}
-#else
- /* with readline, echoing is always enabled */
- fprintf(MR_mdb_out, "on.\n");
-#endif
-
} else {
MR_trace_usage("parameter", "echo");
}
@@ -3427,13 +3407,10 @@
line = MR_trace_readline(prompt, mdb_in, mdb_out);
- /* if we're using readline, then readline does the echoing */
-#ifdef MR_NO_USE_READLINE
if (MR_echo_commands && line != NULL) {
fputs(line, mdb_out);
putc('\n', mdb_out);
}
-#endif
return line;
}
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.57
diff -u -d -r1.57 Mmakefile
--- tests/debugger/Mmakefile 10 Dec 2001 06:50:14 -0000 1.57
+++ tests/debugger/Mmakefile 11 Dec 2001 03:40:40 -0000
@@ -34,6 +34,7 @@
field_names \
implied_instance \
interpreter \
+ interactive \
loopcheck \
lval_desc_array \
multi_parameter \
@@ -43,17 +44,13 @@
resume_typeinfos \
shallow
-# The following tests are disabled, since currently they get some spurious
-# failures if readline support is enabled:
-# interactive
-# Note that some of the make rules for interactive are disabled too.
-
MCFLAGS-shallow = --trace shallow
MCFLAGS-tabled_read = --trace-table-io
# By default, we reclaim heap on failure in non-Boehm-gc grades.
# The extra stack slots required for this reclamation cause spurious
# differences from the expected output on the nondet_stack test case.
MCFLAGS-nondet_stack = --no-reclaim-heap-on-failure
+
MCFLAGS = --trace deep
MLFLAGS = --trace
C2INITFLAGS = --trace
@@ -255,11 +252,8 @@
# interactive.inp contains interactive queries that require interactive.ints
# to have been built.
-# This rule is commented out while the interactive test case is disabled,
-# because otherwise we get an undefined variable warning from make.
-
-# interactive.out.orig: interactive interactive.inp $(interactive.ints)
-# $(MDB) ./interactive < interactive.inp > interactive.out.orig 2>&1
+interactive.out.orig: interactive interactive.inp $(interactive.ints)
+ $(MDB) ./interactive < interactive.inp > interactive.out.orig 2>&1
# We pipe the output through sed to remove some spurious warnings that
# `ld' issues.
Index: tests/debugger/interactive.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/interactive.exp,v
retrieving revision 1.2
diff -u -d -r1.2 interactive.exp
--- tests/debugger/interactive.exp 20 Nov 1999 12:50:03 -0000 1.2
+++ tests/debugger/interactive.exp 11 Dec 2001 04:31:40 -0000
@@ -20,7 +20,7 @@
mdb> print *
HeadVar__1 [1, 2, 3, 4, 5]
mdb>
- 6: 4 3 SWTC pred interactive:qperm/2-0 (nondet) s1; interactive.m:47
+ 6: 4 3 SWTC pred interactive:qperm/2-0 (nondet) s2; interactive.m:47
mdb> print *
HeadVar__1 [1, 2, 3, 4, 5]
mdb>
@@ -56,7 +56,7 @@
mdb> print *
HeadVar__1 [2, 3, 4, 5]
mdb>
- 11: 6 4 SWTC pred interactive:qperm/2-0 (nondet) s1; interactive.m:47
+ 11: 6 4 SWTC pred interactive:qperm/2-0 (nondet) s2; interactive.m:47
mdb> print *
HeadVar__1 [2, 3, 4, 5]
mdb>
@@ -76,7 +76,7 @@
mdb>
15: 8 5 CALL pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:50)
mdb> goto -a 20
- 16: 8 5 SWTC pred interactive:qperm/2-0 (nondet) s1; interactive.m:47
+ 16: 8 5 SWTC pred interactive:qperm/2-0 (nondet) s2; interactive.m:47
17: 9 6 CALL pred interactive:qdelete/3-0 (nondet) interactive.m:52 (interactive.m:48)
18: 9 6 DISJ pred interactive:qdelete/3-0 (nondet) c2;d1; interactive.m:52
19: 9 6 EXIT pred interactive:qdelete/3-0 (nondet) interactive.m:52 (interactive.m:48)
@@ -86,12 +86,12 @@
4 pred interactive:queen/2-0 (nondet) (interactive.m:43)
5 pred interactive:main/2-0 (cc_multi) (interactive.m:19)
mdb> stack -d
- 0 20 10 6 pred interactive:qperm/2-0 (nondet) (interactive.m:46)
- 1 15 8 5 pred interactive:qperm/2-0 (nondet) (interactive.m:50)
- 2 10 6 4 pred interactive:qperm/2-0 (nondet) (interactive.m:50)
- 3 5 4 3 pred interactive:qperm/2-0 (nondet) (interactive.m:50)
- 4 4 3 2 pred interactive:queen/2-0 (nondet) (interactive.m:43)
- 5 1 1 1 pred interactive:main/2-0 (cc_multi) (interactive.m:19)
+ 0 20 10 6 pred interactive:qperm/2-0 (nondet) (interactive.m:46) (empty)
+ 1 15 8 5 pred interactive:qperm/2-0 (nondet) (interactive.m:50) s2;c2;
+ 2 10 6 4 pred interactive:qperm/2-0 (nondet) (interactive.m:50) s2;c2;
+ 3 5 4 3 pred interactive:qperm/2-0 (nondet) (interactive.m:50) s2;c2;
+ 4 4 3 2 pred interactive:queen/2-0 (nondet) (interactive.m:43) c2;
+ 5 1 1 1 pred interactive:main/2-0 (cc_multi) (interactive.m:19) ?;c2;q!;
mdb> print *
HeadVar__1 [4, 5]
mdb> #
@@ -105,6 +105,7 @@
mdb> query interactive list
?- <stdin>:026: Inferred :- pred query((list:list(character)), (list:list(character))).
<stdin>:026: Inferred :- mode query(out, out) is multi.
+append(X, Y, ['a', 'b', 'c']).
X = [], Y = ['a', 'b', 'c'], true ;
X = ['a'], Y = ['b', 'c'], true ;
X = ['a', 'b'], Y = ['c'], true ;
@@ -113,6 +114,7 @@
No (more) solutions.
?- <stdin>:026: Inferred :- pred query((list:list(int))).
<stdin>:026: Inferred :- mode query(out) is nondet.
+qperm([1,2,3], List).
List = [1, 2, 3], true ;
List = [1, 3, 2], true ;
List = [2, 1, 3], true ;
@@ -135,6 +137,7 @@
<stdin>:001: warning: variable `_2' occurs more than once in this scope.
<stdin>:026: Inferred :- pred query((list:list(int)), (list:list(int))).
<stdin>:026: Inferred :- mode query(out, out) is nondet.
+qperm([1,2,3], List), List = [2 | _].
List = [2, 1, 3], _2 = [1, 3], true ;
List = [2, 3, 1], _2 = [3, 1], true ;
fail.
@@ -153,34 +156,45 @@
<stdin>:001: warning: variable `_2' occurs more than once in this scope.
<stdin>:026: Inferred :- pred query((list:list(int)), (list:list(int))).
<stdin>:026: Inferred :- mode query(out, out) is nondet.
+qperm([1,2,3], List), List = [4 | _].
fail.
No (more) solutions.
?- <stdin>:001: In clause for predicate `query:query/1':
<stdin>:001: in argument 1 of call to predicate `qperm/2':
-<stdin>:001: in argument 2 of functor `./2':
-<stdin>:001: in argument 2 of functor `./2':
-<stdin>:001: in argument 1 of functor `./2':
+<stdin>:001: in argument 2 of functor `[|]/2':
+<stdin>:001: in argument 2 of functor `[|]/2':
+<stdin>:001: in argument 1 of functor `[|]/2':
<stdin>:001: type error in unification of argument
<stdin>:001: and constant `"foo"'.
<stdin>:001: argument has type `int',
<stdin>:001: constant `"foo"' has type `string'.
For more information, try recompiling with `-E'.
+qperm([1,2,"foo"], List).
Compilation error(s) occurred.
?- <stdin>:026: Inferred :- pred query((list:list(int))).
-<stdin>:001: In clause for `query(out(not_reached))':
-<stdin>:001: in argument 1 of call to predicate `interactive:qperm/2':
-<stdin>:001: mode error: variable `List' has instantiatedness `free',
-<stdin>:001: expected instantiatedness was `ground'.
-<stdin>:026: Inferred :- mode query(out(free)).
+<stdin>:014: In clause for `run(di, uo)':
+<stdin>:014: in call to predicate `query:query/1':
+<stdin>:014: mode error: arguments `List'
+<stdin>:014: have insts `free',
+<stdin>:014: which does not match any of the valid modes for
+<stdin>:014: the callee, because of the following error.
+<stdin>:026: In clause for `query(out(not_reached))':
+<stdin>:026: in argument 1 of call to predicate `interactive:qperm/2':
+<stdin>:026: mode error: variable `HeadVar__2' has instantiatedness `free',
+<stdin>:026: expected instantiatedness was `ground'.
For more information, try recompiling with `-E'.
+qperm(List, [1]).
Compilation error(s) occurred.
-?-
-mdb> cc_query interactive list
+?- quit.
+
+mdb> cc_query interactive list
?- <stdin>:017: Inferred :- pred query((list:list(character)), (list:list(character))).
<stdin>:017: Inferred :- mode query(out, out) is multi.
+append(X, Y, ['a', 'b', 'c']).
X = [], Y = ['a', 'b', 'c'], true.
?- <stdin>:017: Inferred :- pred query((list:list(int))).
<stdin>:017: Inferred :- mode query(out) is nondet.
+qperm([1,2,3], List).
List = [1, 2, 3], true.
?- <stdin>:011: In clause for predicate `query:run/2':
<stdin>:011: warning: variable `_2' occurs more than once in this scope.
@@ -192,6 +206,7 @@
<stdin>:001: warning: variable `_2' occurs more than once in this scope.
<stdin>:017: Inferred :- pred query((list:list(int)), (list:list(int))).
<stdin>:017: Inferred :- mode query(out, out) is nondet.
+qperm([1,2,3], List), List = [2 | _].
List = [2, 1, 3], _2 = [1, 3], true.
?- <stdin>:011: In clause for predicate `query:run/2':
<stdin>:011: warning: variable `_2' occurs more than once in this scope.
@@ -203,35 +218,39 @@
<stdin>:001: warning: variable `_2' occurs more than once in this scope.
<stdin>:017: Inferred :- pred query((list:list(int)), (list:list(int))).
<stdin>:017: Inferred :- mode query(out, out) is nondet.
+qperm([1,2,3], List), List = [4 | _].
No solution.
-?-
-mdb> io_query interactive list
-run <-- [1, 3, 5, 2, 4]
-run <-- X = [], Y = ['a', 'b', 'c']
-run <-- [1, 2, 3]
-run <-- [2, 1, 3]
-run <-- No solution, as expected.
-run <--
-mdb>
- 21: 10 6 SWTC pred interactive:qperm/2-0 (nondet) s1;
+?- quit.
+
+mdb> io_query interactive list
+run <-- main.
+[1, 3, 5, 2, 4]
+run <-- if { append(X, Y, ['a', 'b', 'c']) } then print("X = "), print(X), print(", Y = "), print(Y), nl else print("No solution\n").
+X = [], Y = ['a', 'b', 'c']
+run <-- if { qperm([1,2,3], List) } then print(List), nl else [].
+[1, 2, 3]
+run <-- if { qperm([1,2,3], List), List = [2 | _] } then print(List), nl else { true }.
+[2, 1, 3]
+run <-- if { qperm([1,2,3], List), List = [4 | _] } then print(List), nl else print("No solution, as expected."), io__nl.
+No solution, as expected.
+run <-- quit.
+
mdb> retry
- 34: 10 6 EXIT pred interactive:qperm/2-0 (nondet)
-retry
- 20: 10 6 CALL pred interactive:qperm/2-0 (nondet)
+This command is a no-op from this port.
mdb> print *
HeadVar__1 [4, 5]
mdb> finish -a
- 21: 10 6 SWTC pred interactive:qperm/2-0 (nondet) s1; interactive.m:47
+ 21: 10 6 SWTC pred interactive:qperm/2-0 (nondet) s2; interactive.m:47
22: 11 7 CALL pred interactive:qdelete/3-0 (nondet) interactive.m:52 (interactive.m:48)
23: 11 7 DISJ pred interactive:qdelete/3-0 (nondet) c2;d1; interactive.m:52
24: 11 7 EXIT pred interactive:qdelete/3-0 (nondet) interactive.m:52 (interactive.m:48)
25: 12 7 CALL pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:50)
- 26: 12 7 SWTC pred interactive:qperm/2-0 (nondet) s1; interactive.m:47
+ 26: 12 7 SWTC pred interactive:qperm/2-0 (nondet) s2; interactive.m:47
27: 13 8 CALL pred interactive:qdelete/3-0 (nondet) interactive.m:52 (interactive.m:48)
28: 13 8 DISJ pred interactive:qdelete/3-0 (nondet) c2;d1; interactive.m:52
29: 13 8 EXIT pred interactive:qdelete/3-0 (nondet) interactive.m:52 (interactive.m:48)
30: 14 8 CALL pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:50)
- 31: 14 8 SWTC pred interactive:qperm/2-0 (nondet) s2; interactive.m:46
+ 31: 14 8 SWTC pred interactive:qperm/2-0 (nondet) s1; interactive.m:46
32: 14 8 EXIT pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:50)
33: 12 7 EXIT pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:50)
34: 10 6 EXIT pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:50)
@@ -245,10 +264,10 @@
36: 6 4 EXIT pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:50)
37: 4 3 EXIT pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:43)
38: 15 3 CALL pred interactive:safe/1-0 (semidet) interactive.m:56 (interactive.m:44)
- 39: 15 3 SWTC pred interactive:safe/1-0 (semidet) s1; interactive.m:57
+ 39: 15 3 SWTC pred interactive:safe/1-0 (semidet) s2; interactive.m:57
40: 16 4 CALL pred interactive:nodiag/3-0 (semidet) interactive.m:61 (interactive.m:58)
- 41: 16 4 SWTC pred interactive:nodiag/3-0 (semidet) s1; interactive.m:62
- 42: 16 4 THEN pred interactive:nodiag/3-0 (semidet) s1;c4;t; interactive.m:66
+ 41: 16 4 SWTC pred interactive:nodiag/3-0 (semidet) s2; interactive.m:62
+ 42: 16 4 THEN pred interactive:nodiag/3-0 (semidet) s2;c4;t; interactive.m:66
43: 16 4 FAIL pred interactive:nodiag/3-0 (semidet) interactive.m:61 (interactive.m:58)
44: 15 3 FAIL pred interactive:safe/1-0 (semidet) interactive.m:56 (interactive.m:44)
45: 4 3 REDO pred interactive:qperm/2-0 (nondet) interactive.m:46 (interactive.m:43)
@@ -268,6 +287,6 @@
mdb> disable 1
1: - stop interface pred interactive:qdelete/3-0 (nondet)
mdb> continue -n
- 675: 141 2 CALL pred interactive:print_list/3-0 (det) interactive.m:83 (interactive.m:22)
+ 675: 141 2 CALL pred interactive:print_list/3-0 (det) interactive.m:83 (interactive.m:20)
mdb> continue -n -S
[1, 3, 5, 2, 4]
Index: tests/debugger/interactive.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/interactive.inp,v
retrieving revision 1.2
diff -u -d -r1.2 interactive.inp
--- tests/debugger/interactive.inp 20 Nov 1999 12:50:04 -0000 1.2
+++ tests/debugger/interactive.inp 11 Dec 2001 04:29:02 -0000
@@ -50,22 +50,19 @@
qperm([1,2,3], List), List = [4 | _].
qperm([1,2,"foo"], List).
qperm(List, [1]).
-quit. cc_query interactive list
+quit.
+cc_query interactive list
append(X, Y, ['a', 'b', 'c']).
qperm([1,2,3], List).
qperm([1,2,3], List), List = [2 | _].
qperm([1,2,3], List), List = [4 | _].
-quit. io_query interactive list
+quit.
+io_query interactive list
main.
-if { append(X, Y, ['a', 'b', 'c']) } then
- print("X = "), print(X),
- print(", Y = "), print(Y), nl
-else
- print("No solution\n").
+if { append(X, Y, ['a', 'b', 'c']) } then print("X = "), print(X), print(", Y = "), print(Y), nl else print("No solution\n").
if { qperm([1,2,3], List) } then print(List), nl else [].
if { qperm([1,2,3], List), List = [2 | _] } then print(List), nl else { true }.
-if { qperm([1,2,3], List), List = [4 | _] } then print(List), nl
-else print("No solution, as expected."), io__nl.
+if { qperm([1,2,3], List), List = [4 | _] } then print(List), nl else print("No solution, as expected."), io__nl.
quit.
retry
print *
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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