[m-dev.] for review: Aditi updates [3]
Simon Taylor
stayl at cs.mu.OZ.AU
Wed Apr 12 18:26:06 AEST 2000
Index: extras/aditi/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/aditi/Mmakefile,v
retrieving revision 1.2
diff -u -u -r1.2 Mmakefile
--- extras/aditi/Mmakefile 1999/09/16 04:46:22 1.2
+++ extras/aditi/Mmakefile 2000/04/12 02:53:37
@@ -1,36 +1,63 @@
#-----------------------------------------------------------------------------#
-# Copyright (C) 1998-1999 The University of Melbourne.
+# Copyright (C) 1998-2000 The University of Melbourne.
# This file may only be copied under the terms of the GNU Library General
# Public License - see the file COPYING.LIB in the Mercury distribution.
#-----------------------------------------------------------------------------#
-
-MAIN_TARGET = all
-
-MCFLAGS = --no-infer-all
+# Mmakefile for the Mercury->Aditi interface.
+#
+# Environment variables (must be set externally):
+# MADITI_INSTALL_PREFIX - directory where the interface should be installed.
+# MAKEFILE_ADITI - makefile containing variables used when compiling
+# a program for Aditi.
+#
+#-----------------------------------------------------------------------------#
+#
+# Defines ADITI_API_EXTRA_CFLAGS, ADITI_API_EXTRA_LIBS and
+# ADITI_API_EXTRA_LDFLAGS
+include $(MAKEFILE_ADITI)
+
+INSTALL_PREFIX = $(MADITI_INSTALL_PREFIX)
+
+# The Aditi interface only works with conservative garbage collection.
+# This is equivalent to
+# LIBGRADES-aditi = $(filter %.gc%,$(LIBGRADES))
+# but gmake patterns can't include multiple wildcards.
+LIBGRADES-aditi = $(shell echo $(LIBGRADES) | tr ' ' '\n' | grep '.gc')
-ADITI_API_DIR = /aditi4/stayl/aditi2/src/api
+#----------------------------------------------------------------------------#
# The --Wno-strict-prototypes is to shut up warnings about prototypes
# without argument types in a header file generated by rpcgen.
-MGNUCFLAGS=-I$(ADITI_API_DIR) -Wno-strict-prototypes
+CFLAGS = $(ADITI_API_EXTRA_CFLAGS) -Wno-strict-prototypes
-# Link in the Aditi API library.
-MLFLAGS += -R$(ADITI_API_DIR) -L$(ADITI_API_DIR) $(EXTRA_MLFLAGS) -lapi
-C2INITFLAGS = --aditi aditi.init
+MLFLAGS = --use-thread-libs $(ADITI_API_EXTRA_LDFLAGS) $(EXTRA_MLFLAGS)
+MLLIBS = $(ADITI_API_EXTRA_LIBS)
-#-----------------------------------------------------------------------------#
+MCFLAGS = --no-infer-all --aditi
-DEPENDS = aditi.depend
+C2INITFLAGS = --aditi
-#-----------------------------------------------------------------------------#
+#-----------------------------------------------------------------------------%
+
+MAIN_TARGET = libaditi
.PHONY: depend
-depend: $(DEPENDS)
+depend: aditi.depend
+ cd tests && mmake $(MMAKEFLAGS) depend
-.PHONY: all
-all: aditi.o
+.PHONY: clean
+clean:
+ cd tests && mmake $(MMAKEFLAGS) clean
+
+.PHONY: realclean
+realclean:
+ cd tests && mmake $(MMAKEFLAGS) realclean
+
+.PHONY: tests
+tests:
+ cd tests && mmake $(MMAKEFLAGS)
-clean_local:
- rm -f *.out *.res
+.PHONY: install
+install: libaditi.install
#-----------------------------------------------------------------------------#
Index: extras/aditi/aditi.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/aditi/aditi.m,v
retrieving revision 1.5
diff -u -u -r1.5 aditi.m
--- extras/aditi/aditi.m 2000/02/08 02:07:58 1.5
+++ extras/aditi/aditi.m 2000/04/12 07:58:54
@@ -14,6 +14,25 @@
% (XXX this section in the manual is commented out, since Aditi is not yet
% publicly available.)
%
+%
+% Compilation grade notes (see the section "Compilation model options"
+% in the Mercury User's Guide for more information):
+%
+% This module requires a compilation grade with conservative garbage
+% collection. Any grade containing `.gc' in its name, such as
+% `asm_fast.gc' or `asm_fast.gc.tr', will do.
+%
+% When trailing is not being used (the compilation grade does not
+% contain `.tr'), resources will sometimes not be cleaned up until
+% the end of a transaction.
+% If there is a commit across a nondet database call, or an exception
+% is thrown, or a database call is retried in the debugger, the output
+% relation from the call and its cursor will not be cleaned up until the
+% transaction ends.
+% It is up to the programmer to decide whether imposing the overhead
+% of trailing on the rest of the program is worthwhile.
+%
+%
% The transaction interface used here is described in
% Kemp, Conway, Harris, Henderson, Ramamohanarao and Somogyi,
% "Database transactions in a purely declarative
@@ -84,16 +103,35 @@
io__state, io__state).
:- mode aditi__disconnect(in, out, di, uo) is det.
+:- type aditi__transaction(T) == pred(T, aditi__state, aditi__state).
+:- inst aditi__transaction = (pred(out, aditi_di, aditi_uo) is det).
+
+ % aditi__transaction(Connection, Transaction, Result).
+ %
+ % Start a transaction with the Aditi database referred to by
+ % Connection, call Transaction, returning ok(Result) if the
+ % transaction is not aborted, or error(Error, Msg) if
+ % the transaction fails.
+ %
+ % If Transaction throws an exception, the transaction will
+ % be aborted and the exception will be rethrown to the caller.
+ %
+ % Predicates with `:- pragma aditi' or `:- pragma base_relation'
+ % markers can only be called from within a transaction -- there
+ % is no other way to get an `aditi__state' to pass to them.
+:- pred aditi__transaction(aditi__connection, aditi__transaction(T),
+ aditi__result(T), io__state, io__state).
+:- mode aditi__transaction(in, in(aditi__transaction), out, di, uo) is det.
+
% aditi__aggregate_compute_initial(Closure, UpdateAcc,
% ComputeInitial, Results)
%
% When called, the query Closure returns the relation to be
% aggregated over. This relation must have two attributes,
- % the first being the attribute to group by. The relation is
- % sorted and duplicates are removed before the aggregate is applied.
- % The closure ComputeInitial computes an initial accumulator
- % for each group given the first tuple in the group.
- % The closure UpdateAcc is called for each tuple in each group to
+ % the first being the attribute to group by. The closure
+ % ComputeInitial computes an initial accumulator for each
+ % group given the first tuple in the group. The closure
+ % UpdateAcc is called for each tuple in each group to
% update the accumulator. The outputs are the group-by element
% and final accumulator for each group.
%
@@ -136,18 +174,11 @@
in, out, out) is nondet.
*/
-:- type aditi__transaction(T) == pred(T, aditi__state, aditi__state).
-:- inst aditi__transaction = (pred(out, aditi_di, aditi_uo) is det).
-
-:- pred aditi__transaction(aditi__connection, aditi__transaction(T),
- aditi__result(T), io__state, io__state).
-:- mode aditi__transaction(in, in(aditi__transaction), out, di, uo) is det.
-
%---------------------------------------------------------------------------%
:- implementation.
-:- import_module bool, char, list, require, std_util, string, std_util.
+:- import_module bool, char, exception, list, require, std_util, string.
:- type aditi__connection == int.
:- type aditi__state == unit.
@@ -159,10 +190,32 @@
:- pragma c_header_code("
#include ""mercury_wrapper.h""
+#include ""mercury_ho_call.h""
+
+/* aditi_api_config.h must be included before aditi_clnt.h */
+#include ""aditi_api_config.h""
#include ""aditi_clnt.h""
+#define MADITI_check(status) MADITI_do_check(status, __LINE__);
#define MADITI_throw MR_longjmp(&MADITI_jmp_buf);
+typedef enum { MADITI_INSERT_TUPLE, MADITI_DELETE_TUPLE } MADITI_insert_delete;
+typedef enum { MADITI_INSERT, MADITI_DELETE, MADITI_MODIFY } MADITI_bulk_op;
+
+#ifdef MR_USE_TRAIL
+
+/*
+** Information used to clean up a call result if there is a commit
+** or an exception across a database call.
+*/
+typedef struct {
+ ticket *output_rel;
+ ticket *output_cursor;
+ bool cleaned_up;
+} MADITI_trail_cleanup_data;
+
+#endif /* MR_USE_TRAIL */
+
static ticket MADITI_ticket; /* Current connection ticket. */
static MR_jmp_buf MADITI_jmp_buf; /* jmp_buf to longjmp() to when
** aborting the transaction.
@@ -171,10 +224,26 @@
** Aditi API call.
*/
-static void MADITI_do_call(void);
-static void MADITI_check(int);
+static void MADITI_do_nondet_call(void);
+static ticket * MADITI_run_procedure(String proc_name,
+ String input_schema, String input_tuple);
+static void MADITI_do_insert_delete_tuple(MADITI_insert_delete);
+static void MADITI_do_bulk_operation(MADITI_bulk_op operation);
+static void MADITI_do_bulk_insert_or_delete(MADITI_bulk_op operation,
+ String rel_name, ticket *call_result_ticket);
static bool MADITI_get_output_tuple(int);
-static void MADITI_cleanup(void);
+static void MADITI_post_call_cleanup(void);
+static void MADITI_cleanup_call_output(ticket *output_rel, ticket *cursor);
+
+#ifdef MR_USE_TRAIL
+static void MADITI_trail_cleanup_call_output(void *cleanup_data,
+ MR_untrail_reason reason);
+#endif
+
+static String MADITI_construct_tuple(int num_input_args,
+ Word *input_typeinfos, Word *input_args);
+static void MADITI_do_check(int, int);
+static void MADITI_list_rel(ticket* rel);
").
%-----------------------------------------------------------------------------%
@@ -208,11 +277,7 @@
*/
if ((Stat = ADITI_NAME(login)(User, Passwd)) == ADITI_OK) {
- DEBUG(struct param_value pvalue);
- DEBUG(pvalue.type = int_type);
- DEBUG(pvalue.param_value_u.int_val = 1);
- DEBUG(ADITI_NAME(setparam)(""debug"", &pvalue));
- DEBUG(ADITI_NAME(disable_ping)());
+ DEBUG(ADITI_NAME(set_debug)());
DEBUG(printf(""logged in\\n""));
if ((Stat = MR_load_aditi_rl_code())
@@ -259,23 +324,29 @@
aditi__transaction(_Connection, Transaction, TransResult, IO0, IO) :-
aditi__do_transaction(Transaction, Results,
- Status, IO0, IO),
- ( Status = 0 ->
- TransResult = ok(Results)
+ Status, GotException, Exception, IO0, IO),
+ ( GotException = 0 ->
+ ( Status = 0 ->
+ TransResult = ok(Results)
+ ;
+ aditi__error_code(Status, Error, String),
+ TransResult = error(Error, String)
+ )
;
- aditi__error_code(Status, Error, String),
- TransResult = error(Error, String)
+ rethrow(exception(Exception))
).
%-----------------------------------------------------------------------------%
:- pred aditi__do_transaction(aditi__transaction(T),
- T, int, io__state, io__state).
-:- mode aditi__do_transaction(in(aditi__transaction), out, out, di, uo) is det.
-:- pragma no_inline(aditi__do_transaction/5). % contains labels
+ T, int, int, univ, io__state, io__state).
+:- mode aditi__do_transaction(in(aditi__transaction),
+ out, out, out, out, di, uo) is det.
+:- pragma no_inline(aditi__do_transaction/7). % contains labels
:- pragma c_code(aditi__do_transaction(Transaction::in(aditi__transaction),
- Results::out, Stat::out, IO0::di, IO::uo),
+ Results::out, Stat::out, GotException::out, Exception::out,
+ IO0::di, IO::uo),
may_call_mercury,
"
{
@@ -293,11 +364,18 @@
MR_setjmp(&MADITI_jmp_buf, transaction_error);
MADITI__call_transaction(TypeInfo_for_T,
- Transaction, &Results, 0, &DB);
+ Transaction, &Results, &GotException,
+ &Exception, (Word)0, &DB);
- DEBUG(printf(""committing transaction...""));
- Stat = ADITI_NAME(trans_commit)(&MADITI_ticket);
- DEBUG(printf(""done\\n""));
+ if (GotException == 0) {
+ DEBUG(printf(""committing transaction...""));
+ Stat = ADITI_NAME(trans_commit)(&MADITI_ticket);
+ DEBUG(printf(""done\\n""));
+ } else {
+ DEBUG(printf(""got exception - aborting transaction...""));
+ Stat = ADITI_NAME(trans_abort)(&MADITI_ticket);
+ DEBUG(printf(""done\\n""));
+ }
goto transaction_done;
@@ -306,38 +384,60 @@
DEBUG(printf(""aborting transaction...""));
ADITI_NAME(trans_abort)(&MADITI_ticket);
DEBUG(printf(""done\\n""));
+ GotException = 0;
Stat = MADITI_status;
transaction_done:
}
").
-:- pred aditi__call_transaction(aditi__transaction(T), T,
+:- pred aditi__call_transaction(aditi__transaction(T), T, int, univ,
aditi__state, aditi__state).
-:- mode aditi__call_transaction(in(aditi__transaction), out,
- aditi_di, aditi_uo) is det.
+:- mode aditi__call_transaction(in(aditi__transaction), out, out, out,
+ aditi_di, aditi_uo) is cc_multi.
:- pragma export(
aditi__call_transaction(in(aditi__transaction), out,
- aditi_di, aditi_uo),
+ out, out, aditi_di, aditi_uo),
"MADITI__call_transaction"
).
-aditi__call_transaction(Trans, Results) -->
- call(Trans, Results).
+aditi__call_transaction(Trans, Results, GotException, Exception,
+ State0, State) :-
+ TryTransaction =
+ (pred(Result - AditiState::out) is det :-
+ Trans(Result, State0, AditiState)
+ ),
+ try(TryTransaction, ExceptionResult),
+ (
+ ExceptionResult = succeeded(Results - State),
+ GotException = 0,
+ make_dummy_value(Exception)
+ ;
+ ExceptionResult = exception(Exception),
+ State = State0,
+ GotException = 1,
+ make_dummy_value(Results)
+ ).
+
+ % Pretend to bind a variable. The result must never be looked at.
+:- pred make_dummy_value(T::out) is det.
+:- pragma c_code(make_dummy_value(T::out),
+ [will_not_call_mercury, thread_safe],
+ "T = 0;").
%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
:- pragma c_code("
/*
- ** We might allocate memory from may_call_mercury C code. XXX?
+ ** We might allocate memory from may_call_mercury C code.
*/
#ifndef CONSERVATIVE_GC
#error The Aditi interface requires conservative garbage collection. \\
Use a compilation grade containing .gc.
#endif /* ! CONSERVATIVE_GC */
+
").
% Hand coded C to call an Aditi procedure. This is needed
@@ -378,8 +478,8 @@
#define MADITI_input_schema r3
#define MADITI_num_output_args r4
- /* Register containing the first input argument */
-#define MADITI_FIRST_INPUT 5
+ /* Register containing the typeinfo for the first input argument */
+#define MADITI_CALL_FIRST_INPUT 5
/*
** Output arguments from do_call_aditi are the same as for
@@ -410,17 +510,37 @@
Declare_label(do_nondet_aditi_call_i1);
Define_extern_entry(do_semidet_aditi_call);
Define_extern_entry(do_det_aditi_call);
+Define_extern_entry(do_aditi_insert);
+Define_extern_entry(do_aditi_delete);
+Define_extern_entry(do_aditi_bulk_insert);
+Define_extern_entry(do_aditi_bulk_delete);
+Define_extern_entry(do_aditi_bulk_modify);
MR_MAKE_PROC_LAYOUT(do_nondet_aditi_call, MR_DETISM_NON,
- MR_ENTRY_NO_SLOT_COUNT, MR_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
- ""private_builtin"", ""do_nondet_aditi_call"", 0, 0);
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_nondet_aditi_call"", 0, 0);
MR_MAKE_INTERNAL_LAYOUT(do_nondet_aditi_call, 1);
MR_MAKE_PROC_LAYOUT(do_semidet_aditi_call, MR_DETISM_NON,
- MR_ENTRY_NO_SLOT_COUNT, MR_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
- ""private_builtin"", ""do_semidet_aditi_call"", 0, 0);
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_semidet_aditi_call"", 0, 0);
MR_MAKE_PROC_LAYOUT(do_det_aditi_call, MR_DETISM_NON,
- MR_ENTRY_NO_SLOT_COUNT, MR_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
- ""private_builtin"", ""do_semidet_aditi_call"", 0, 0);
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_det_aditi_call"", 0, 0);
+MR_MAKE_PROC_LAYOUT(do_aditi_insert, MR_DETISM_DET,
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_aditi_insert"", 0, 0);
+MR_MAKE_PROC_LAYOUT(do_aditi_delete, MR_DETISM_DET,
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_aditi_delete"", 0, 0);
+MR_MAKE_PROC_LAYOUT(do_aditi_bulk_insert, MR_DETISM_DET,
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_aditi_bulk_insert"", 0, 0);
+MR_MAKE_PROC_LAYOUT(do_aditi_bulk_delete, MR_DETISM_DET,
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_aditi_bulk_delete"", 0, 0);
+MR_MAKE_PROC_LAYOUT(do_aditi_bulk_modify, MR_DETISM_DET,
+ MR_ENTRY_NO_SLOT_COUNT, MR_LONG_LVAL_TYPE_UNKNOWN, MR_PREDICATE,
+ ""aditi"", ""do_aditi_bulk_modify"", 0, 0);
BEGIN_MODULE(do_aditi_call_module)
init_entry_sl(do_nondet_aditi_call);
@@ -430,16 +550,26 @@
MR_INIT_PROC_LAYOUT_ADDR(do_semidet_aditi_call);
init_entry_sl(do_det_aditi_call);
MR_INIT_PROC_LAYOUT_ADDR(do_det_aditi_call);
+ init_entry_sl(do_aditi_insert);
+ MR_INIT_PROC_LAYOUT_ADDR(do_aditi_insert);
+ init_entry_sl(do_aditi_delete);
+ MR_INIT_PROC_LAYOUT_ADDR(do_aditi_delete);
+ init_entry_sl(do_aditi_bulk_insert);
+ MR_INIT_PROC_LAYOUT_ADDR(do_aditi_bulk_insert);
+ init_entry_sl(do_aditi_bulk_delete);
+ MR_INIT_PROC_LAYOUT_ADDR(do_aditi_bulk_delete);
+ init_entry_sl(do_aditi_bulk_modify);
+ MR_INIT_PROC_LAYOUT_ADDR(do_aditi_bulk_modify);
BEGIN_CODE
Define_entry(do_nondet_aditi_call);
{
- mkframe(""do_nondet_aditi_call"",
+ MR_mkframe(""do_nondet_aditi_call"",
(MADITI_NUM_FRAME_VARS + MADITI_num_output_args),
LABEL(do_nondet_aditi_call_i1));
save_transient_registers();
- MADITI_do_call();
+ MADITI_do_nondet_call();
restore_transient_registers();
GOTO(LABEL(do_nondet_aditi_call_i1));
}
@@ -450,22 +580,22 @@
/* Unpack the output tuple into r1 and upwards. */
if (MADITI_get_output_tuple(1)) {
restore_transient_registers();
- succeed();
+ MR_succeed();
} else {
- MADITI_cleanup();
+ MADITI_post_call_cleanup();
restore_transient_registers();
- fail();
+ MR_fail();
}
}
Define_entry(do_semidet_aditi_call);
{
- mkframe(""do_semidet_aditi_call"",
+ MR_mkframe(""do_semidet_aditi_call"",
(MADITI_NUM_FRAME_VARS + MADITI_num_output_args),
ENTRY(do_not_reached));
save_transient_registers();
- MADITI_do_call();
+ MADITI_do_nondet_call();
/* Unpack the output tuple into r2 and upwards for semidet code. */
if (MADITI_get_output_tuple(2)) {
@@ -475,25 +605,25 @@
** We assume that any other solutions are duplicates
** of the one we just collected.
*/
- MADITI_cleanup();
+ MADITI_post_call_cleanup();
restore_transient_registers();
r1 = 1;
} else {
- MADITI_cleanup();
+ MADITI_post_call_cleanup();
restore_transient_registers();
r1 = 0;
}
- succeed_discard();
+ MR_succeed_discard();
}
Define_entry(do_det_aditi_call);
{
- mkframe(""do_det_aditi_call"",
+ MR_mkframe(""do_det_aditi_call"",
(MADITI_NUM_FRAME_VARS + MADITI_num_output_args),
ENTRY(do_not_reached));
save_transient_registers();
- MADITI_do_call();
+ MADITI_do_nondet_call();
/* Unpack the output tuple into r1 and upwards. */
if (!MADITI_get_output_tuple(1)) {
@@ -507,11 +637,76 @@
** of the one we just collected.
*/
- MADITI_cleanup();
+ MADITI_post_call_cleanup();
restore_transient_registers();
- succeed_discard();
+ MR_succeed_discard();
+}
+
+/*---------------------------------------------------------------------------*/
+/*
+** Insert or delete a single tuple into/from a relation.
+**
+** Input arguments:
+** r1 -> name of relation
+** r2 -> arity of relation
+** r3 -> name of the deletion procedure for the relation (aditi_delete only)
+** r4 -> schema of the relation (aditi_delete only)
+** r5 -> type_infos for arguments of tuple to insert
+** -> arguments of tuple to insert
+**
+** There are no output arguments.
+*/
+Define_entry(do_aditi_insert);
+{
+ save_transient_registers();
+ DEBUG(printf(""do_aditi_insert\\n""));
+ MADITI_do_insert_delete_tuple(MADITI_INSERT_TUPLE);
+ restore_transient_registers();
+ proceed();
+}
+Define_entry(do_aditi_delete);
+{
+ save_transient_registers();
+ DEBUG(printf(""do_aditi_delete\\n""));
+ MADITI_do_insert_delete_tuple(MADITI_DELETE_TUPLE);
+ restore_transient_registers();
+ proceed();
+}
+
+
+/*
+** Insert/delete the tuples returned by the query argument
+**
+** Input arguments:
+** r1 -> name of relation
+** r2 -> name of deletion or modification procedure
+** r3 -> closure
+*/
+Define_entry(do_aditi_bulk_insert);
+{
+ save_transient_registers();
+ DEBUG(printf(""do_aditi_bulk_insert\\n""));
+ MADITI_do_bulk_operation(MADITI_INSERT);
+ restore_transient_registers();
+ proceed();
+}
+Define_entry(do_aditi_bulk_delete);
+{
+ save_transient_registers();
+ DEBUG(printf(""do_aditi_bulk_delete\\n""));
+ MADITI_do_bulk_operation(MADITI_DELETE);
+ restore_transient_registers();
+ proceed();
}
+Define_entry(do_aditi_bulk_modify);
+{
+ save_transient_registers();
+ DEBUG(printf(""do_aditi_bulk_modify\\n""));
+ MADITI_do_bulk_operation(MADITI_MODIFY);
+ restore_transient_registers();
+ proceed();
+}
END_MODULE
void mercury_sys_init_aditi_call(void); /* suppress gcc warning */
@@ -520,6 +715,7 @@
}
/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
/*
** The functions below fiddle with the Mercury registers, so be sure
@@ -528,127 +724,439 @@
/*
** Send the input tuple to the database then run the procedure.
+** Afterwards, setup for nondeterministic return of the output tuples.
*/
static void
-MADITI_do_call(void)
-{
+MADITI_do_nondet_call(void)
+{
String proc_name;
int num_input_args;
+ Word *input_typeinfos;
+ Word *input_args;
+
String input_schema;
+ String input_tuple = NULL;
+
int num_output_args;
- /* Ticket identifying the input relation. */
- ticket *input_ticket = NULL;
- /* Ticket identifying the output relation. */
- ticket *output_ticket = NULL;
- /* Ticket identifying the cursor on the output relation. */
- ticket *cursor = NULL;
-
- /* Used to hold the list of attributes of the input tuple
- ** as they are built up.
- */
- Word tuple_list;
- Word new_tuple_list;
+ ticket *output_ticket = NULL; /* ticket for the output relation */
+ ticket *cursor = NULL; /* ticket for the output cursor */
- char *tuple = NULL; /* The input tuple. */
+ int first_output_typeinfo; /* register containing the first of the
+ ** type-infos for the output arguments
+ */
int i;
- /* Register containing the first of the output type_infos. */
- int first_output_typeinfo;
- /* Memory used to hold copies of the input arguments. */
- Word *input_save_area;
-
restore_transient_registers();
proc_name = (String) MADITI_proc_name;
num_input_args = (int) MADITI_num_input_args;
input_schema = (String) MADITI_input_schema;
- num_output_args = MADITI_num_output_args;
+
+ num_output_args = (int) MADITI_num_output_args;
/* save the number of output arguments */
MADITI_saved_num_output_args = num_output_args;
- /* create temporary relation to hold the input tuple */
- DEBUG(printf(""creating input temporary...""));
- input_ticket = MR_NEW(ticket);
- output_ticket = MR_NEW(ticket);
- MADITI_check(ADITI_NAME(tmp_create)(&MADITI_ticket,
- input_schema, input_ticket));
- DEBUG(printf(""done\\n""));
- /*
- ** Copy the input arguments and their type_infos out of the registers.
- ** This is done to avoid having to save/restore the
- ** registers around each call to MADITI__attr_to_string,
- ** which calls back into Mercury.
- */
- input_save_area = MR_GC_NEW_ARRAY(Word, num_input_args * 2);
+ DEBUG(printf(""Handling call to %s\\n"", proc_name));
+ DEBUG(printf(""%d input args; %d output args\\n"",
+ num_input_args, num_output_args));
+ DEBUG(printf(""input schema %s\\n"", input_schema));
+
+ /* extract the input arguments and their type-infos from registers */
+ input_args = MR_GC_NEW_ARRAY(Word, num_input_args);
+ input_typeinfos = MR_GC_NEW_ARRAY(Word, num_input_args);
save_registers();
- for (i = 0; i < num_input_args * 2; i++) {
- input_save_area[i] = virtual_reg(MADITI_FIRST_INPUT + i);
+ for (i = 0; i < num_input_args; i++) {
+ input_typeinfos[i] = virtual_reg(MADITI_CALL_FIRST_INPUT + i);
+ input_args[i] =
+ virtual_reg(MADITI_CALL_FIRST_INPUT + num_input_args + i);
}
/* store the output typeinfos in the nondet stack frame */
- first_output_typeinfo = MADITI_FIRST_INPUT + num_input_args * 2;
+ first_output_typeinfo = MADITI_CALL_FIRST_INPUT + num_input_args * 2;
for (i = 0; i < num_output_args; i++) {
MADITI_OUTPUT_TYPEINFO(i) =
virtual_reg(first_output_typeinfo + i);
}
- /*
- ** We're finished with the virtual_reg array.
- ** There's no need to restore the registers here since
- ** we haven't altered any of the virtual_reg array entries.
- */
+ input_tuple = MADITI_construct_tuple(num_input_args,
+ input_typeinfos, input_args);
+ MR_GC_free(input_args);
+ MR_GC_free(input_typeinfos);
- tuple_list = MR_list_empty();
- DEBUG(printf(""building input tuple...""));
- for (i = 0; i < num_input_args; i++) {
- /* convert the argument to a string, adding it to the tuple */
- MADITI__attr_to_string(input_save_area[i],
- input_save_area[num_input_args + i],
- tuple_list, &new_tuple_list);
- tuple_list = new_tuple_list;
- }
- MADITI__reverse_append_string_list(tuple_list, &tuple);
+ output_ticket = MADITI_run_procedure(proc_name,
+ input_schema, input_tuple);
+
+ /* create cursor on the output relation */
+ DEBUG(printf(""opening output cursor...""));
+ /* XXX MR_GC_NEW_ATOMIC */
+ cursor = (ticket *) MR_GC_NEW(ticket);
+ MADITI_check(ADITI_NAME(rel_cursor_create)(output_ticket, cursor));
+ MADITI_check(ADITI_NAME(cursor_open)(cursor, CUR_FORWARD));
DEBUG(printf(""done\\n""));
+ MADITI_saved_output_rel = (Word) output_ticket;
+ MADITI_saved_cursor = (Word) cursor;
+
+#ifdef MR_USE_TRAIL
+ {
+ MADITI_trail_cleanup_data *cleanup_data;
+ cleanup_data = MR_GC_NEW(MADITI_trail_cleanup_data);
+ cleanup_data->output_rel = output_ticket;
+ cleanup_data->output_cursor = cursor;
+ cleanup_data->cleaned_up = FALSE;
+ MR_trail_function(MADITI_trail_cleanup_call_output,
+ (void *) cleanup_data);
+ }
+#endif /* MR_USE_TRAIL */
+
+ save_transient_registers();
+}
+
+#ifdef MR_USE_TRAIL
+static void
+MADITI_trail_cleanup_call_output(void *data, MR_untrail_reason reason)
+{
+ MADITI_trail_cleanup_data *cleanup_data;
+ switch (reason) {
+ case MR_commit:
+ case MR_exception:
+ case MR_retry:
+ /*
+ ** Cleanup the output relation.
+ */
+ cleanup_data = (MADITI_trail_cleanup_data *) data;
+
+ if (cleanup_data->cleaned_up) {
+
+ /*
+ ** This can happen if there is a commit followed
+ ** by an exception -- the commit will not reset
+ ** the trail.
+ */
+ DEBUG(printf(
+ ""MADITI_trail_cleanup_call_output: already cleaned up (%d)\n"",
+ reason));
+
+ } else {
+
+ DEBUG(printf(
+ ""MADITI_trail_cleanup_call_output: cleaning up (%d)\n"",
+ reason));
+
+ MADITI_cleanup_call_output(cleanup_data->output_rel,
+ cleanup_data->output_cursor);
+ cleanup_data->cleaned_up = TRUE;
+ }
+ break;
+
+ case MR_solve:
+ case MR_undo:
+ /*
+ ** Undo on backtracking will be handled by
+ ** MADITI_post_call_cleanup, so that the
+ ** cleanup will happen even if trailing
+ ** is not being used.
+ */
+ break;
+
+ case MR_gc:
+ default:
+ fatal_error(""MADITI_trail_cleanup_call_output"");
+ }
+}
+#endif /* MR_USE_TRAIL */
+
+/*
+** Given an RL procedure name, the schema of the input relation and a tuple
+** to insert into the input relation, run the procedure, returning a ticket
+** for the output relation.
+** MADITI_run_procedure does not look at the Mercury registers.
+*/
+static ticket *
+MADITI_run_procedure(String proc_name, String input_schema, String input_tuple)
+{
+ /* Ticket identifying the input relation. */
+ ticket input_ticket;
+ /* Ticket identifying the output relation. */
+ ticket *output_ticket = NULL;
+
/*
- ** We're done with the saved input arguments.
+ ** Create a temporary relation to hold the input tuple.
*/
- MR_GC_free(input_save_area);
+ DEBUG(printf(""creating input temporary (schema %s)..."",
+ input_schema));
+ MADITI_check(ADITI_NAME(tmp_create)(&MADITI_ticket,
+ input_schema, &input_ticket));
+ DEBUG(printf(""done\\n""));
- /* insert the input tuple into the relation */
- DEBUG(printf(""adding input tuple...%s"", tuple));
- MADITI_check(ADITI_NAME(tmp_addtup)(input_ticket, tuple));
+ /*
+ ** Insert the input tuple into the relation.
+ */
+ DEBUG(printf(""adding input tuple...%s"", input_tuple));
+ MADITI_check(ADITI_NAME(tmp_addtup)(&input_ticket, input_tuple));
DEBUG(printf(""done\\n""));
- /* run the procedure */
+ /*
+ ** Run the procedure.
+ */
DEBUG(printf(""running procedure... ""));
- MADITI_check(ADITI_NAME(run2)(proc_name, 100000, &MADITI_ticket,
- input_ticket, output_ticket));
+ /* XXX MR_GC_NEW_ATOMIC */
+ output_ticket = (ticket *) MR_GC_NEW(ticket);
+ MADITI_check(ADITI_NAME(run2_s)(proc_name, 100000, &MADITI_ticket,
+ &input_ticket, output_ticket));
DEBUG(printf(""done\\n""));
- /* drop the input relation */
+ /*
+ ** Drop the input relation.
+ */
DEBUG(printf(""dropping input temporary...""));
- MADITI_check(ADITI_NAME(tmp_destroy)(input_ticket));
- MR_free(input_ticket);
+ MADITI_check(ADITI_NAME(tmp_destroy)(&input_ticket));
DEBUG(printf(""done\\n""));
- /* create cursor on the output relation */
- DEBUG(printf(""opening output cursor...""));
- cursor = MR_NEW(ticket);
- MADITI_check(ADITI_NAME(tmp_cursor_create)(output_ticket, cursor));
- MADITI_check(ADITI_NAME(cursor_open)(cursor, CUR_FORWARD));
- DEBUG(printf(""done\\n""));
+ DEBUG(printf(""output tuples\n""));
+ DEBUG(MADITI_list_rel(output_ticket));
+ DEBUG(printf(""\\n\\n""));
- MADITI_saved_output_rel = (Word) output_ticket;
- MADITI_saved_cursor = (Word) cursor;
+ return output_ticket;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+MADITI_do_insert_delete_tuple(MADITI_insert_delete op)
+{
+ String rel_name;
+ int rel_arity;
+ String tuple;
+ String delete_proc_name;
+ String delete_input_schema;
+ Word *input_typeinfos;
+ Word *input_args;
+ int first_input_reg = 5;
+ int i;
+ ticket *delete_output_rel = NULL;
+
+ restore_transient_registers();
+ rel_name = (String) r1;
+ rel_arity = r2;
+ delete_proc_name = (String) r3;
+ delete_input_schema = (String) r4;
+
+ DEBUG(
+ switch (op) {
+ case MADITI_INSERT_TUPLE:
+ printf(""aditi_insert(%s)\\n"",
+ rel_name);
+ break;
+ case MADITI_DELETE_TUPLE:
+ printf(""aditi_delete(%s)\\n"",
+ rel_name);
+ break;
+ }
+ )
+
+ /* extract the input arguments and their type-infos from registers */
+ input_args = MR_GC_NEW_ARRAY(Word, rel_arity);
+ input_typeinfos = MR_GC_NEW_ARRAY(Word, rel_arity);
+ save_registers();
+ for (i = 0; i < rel_arity; i++) {
+ input_typeinfos[i] = virtual_reg(first_input_reg + i);
+ input_args[i] = virtual_reg(first_input_reg + rel_arity + i);
+ }
+
+ tuple = MADITI_construct_tuple(rel_arity, input_typeinfos, input_args);
+
+ MR_GC_free(input_args);
+ MR_GC_free(input_typeinfos);
+
+ switch (op) {
+ case MADITI_INSERT_TUPLE:
+ DEBUG(printf(""inserting tuple %s\\n"", tuple));
+ MADITI_check(ADITI_NAME(addtup)(rel_name, tuple));
+ break;
+ case MADITI_DELETE_TUPLE:
+ DEBUG(printf(""deleting tuple %s\\n"", tuple));
+ delete_output_rel =
+ MADITI_run_procedure(delete_proc_name,
+ delete_input_schema, tuple);
+ MADITI_check(ADITI_NAME(rel_close)(
+ delete_output_rel));
+ MR_GC_free(delete_output_rel);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+MADITI_do_bulk_operation(MADITI_bulk_op operation)
+{
+ String rel_name;
+ int num_input_args;
+ Word *input_args;
+ Word *input_typeinfos;
+ MR_Closure *closure;
+ String called_proc_name;
+ String update_proc_name = NULL;
+ String input_schema;
+ String input_tuple;
+ ticket modified_rel_ticket;
+ ticket dummy_output_ticket;
+ ticket *call_result_ticket;
+
+ restore_transient_registers();
+ rel_name = (String) r1;
+ update_proc_name = (String) r2;
+ closure = (MR_Closure *) r3;
+
+ DEBUG(
+ switch (operation) {
+ case MADITI_INSERT:
+ printf(""aditi_bulk_insert(%s)\\n"",
+ rel_name);
+ break;
+ case MADITI_DELETE:
+ printf(""aditi_bulk_delete(%s)\\n"",
+ rel_name);
+ break;
+ case MADITI_MODIFY:
+ printf(""aditi_bulk_delete(%s)\\n"",
+ rel_name);
+ break;
+ }
+ )
+
+ /*
+ ** The 'code' passed to an aditi_bottom_up closure is
+ ** actually a tuple containing the procedure name and
+ ** the schema of the input relation.
+ */
+ called_proc_name =
+ (String) MR_field(MR_mktag(0), closure->MR_closure_code, 0);
+ input_schema =
+ (String) MR_field(MR_mktag(0), closure->MR_closure_code, 1);
+
+ DEBUG(printf(""closure proc name %s\n"", called_proc_name));
+
+ num_input_args = closure->MR_closure_num_hidden_args;
+ input_args = (Word *) closure->MR_closure_hidden_args_0;
+ input_typeinfos =
+ (Word *) closure->MR_closure_layout->arg_pseudo_type_info;
+
+ input_tuple = MADITI_construct_tuple(num_input_args,
+ input_typeinfos, input_args);
+
+ call_result_ticket = MADITI_run_procedure(called_proc_name,
+ input_schema, input_tuple);
+
+ switch (operation) {
+ case MADITI_INSERT:
+ DEBUG(printf(""Inserting tuples into %s\\n"",
+ rel_name));
+
+ MADITI_check(ADITI_NAME(perm_open)(&MADITI_ticket,
+ rel_name, &modified_rel_ticket));
+ MADITI_check(ADITI_NAME(add_tups_to)(
+ call_result_ticket,
+ &modified_rel_ticket));
+ MADITI_check(ADITI_NAME(perm_close)(
+ &modified_rel_ticket));
+ break;
+
+ case MADITI_DELETE:
+ case MADITI_MODIFY:
+ DEBUG(printf(""Doing delete/modify of %s\n"",
+ rel_name));
+ MADITI_check(ADITI_NAME(run2_s)(update_proc_name,
+ 100000, &MADITI_ticket,
+ call_result_ticket, &dummy_output_ticket)
+ );
+ MADITI_check(
+ ADITI_NAME(rel_close)(&dummy_output_ticket)
+ );
+ break;
+ }
+
+
+ MADITI_check(ADITI_NAME(rel_close)(call_result_ticket));
+ MR_GC_free(call_result_ticket);
+
save_transient_registers();
}
+static void
+MADITI_list_rel(ticket* rel)
+{
+ size_t len;
+ char* ptr;
+ ticket cur;
+
+ MADITI_check(ADITI_NAME(tmp_cursor_create)(rel,&cur));
+ MADITI_check(ADITI_NAME(cursor_open)(&cur,CUR_FORWARD));
+ len = 0;
+ ptr = NULL;
+ fflush(stdout);
+ while (ADITI_NAME(cursor_next)(&cur,&len,&ptr) == ADITI_OK) {
+ fprintf(stdout,""tuple: [%.*s]\n"",(int)len,ptr);
+ free(ptr);
+ len = 0;
+ ptr = NULL;
+ }
+ MADITI_check(ADITI_NAME(cursor_close)(&cur));
+ MADITI_check(ADITI_NAME(cursor_destroy)(&cur));
+}
+
+/*---------------------------------------------------------------------------*/
+
/*
+** Convert a list of arguments in registers into a string representation
+** suitable for sending to Aditi.
+** Starting at register `first_argument', there must be `num_input_args'
+** type_infos, followed by `num_input_args' data values.
+** save_transient_registers()/restore_transient_registers() must be done
+** around calls to this function.
+*/
+String MADITI_construct_tuple(int num_input_args,
+ Word *typeinfos, Word *input_args)
+{
+ /* Used to hold the list of attributes of the input tuple
+ ** as they are built up.
+ */
+ Word tuple_list;
+ Word new_tuple_list;
+
+ String tuple;
+ int i;
+
+ restore_transient_registers();
+
+ /*
+ ** This part calls back into Mercury to construct the tuple.
+ ** The wrapper functions expect the registers to be saved,
+ ** so do that here.
+ */
+ save_registers();
+ tuple_list = MR_list_empty();
+ DEBUG(printf(""building input tuple...""));
+ for (i = 0; i < num_input_args; i++) {
+ /* convert the argument to a string, adding it to the tuple */
+ MADITI__attr_to_string(typeinfos[i], input_args[i],
+ tuple_list, &new_tuple_list);
+ tuple_list = new_tuple_list;
+ }
+ MADITI__reverse_append_string_list(tuple_list, &tuple);
+ DEBUG(printf(""done: tuple = %s\\n"", tuple));
+
+ return tuple;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*
** Get an output tuple from the database, return an indication of success.
** Attributes from the tuple should be placed in consecutive registers
** starting with r(first_reg).
@@ -666,6 +1174,7 @@
String tuple_str_copy;
Word arg;
int found_result;
+ ticket *output_cursor;
int num_output_args;
int rc;
/* Somewhere to put the output arguments before copying them
@@ -675,16 +1184,18 @@
restore_transient_registers();
num_output_args = MADITI_saved_num_output_args;
+ output_cursor = (ticket *)MADITI_saved_cursor;
/* advance cursor, get tuple string */
- rc = ADITI_NAME(cursor_next)((ticket *)MADITI_saved_cursor,
+ DEBUG(printf(""getting output tuple\\n""));
+ rc = ADITI_NAME(cursor_next)(output_cursor,
&tuple_str_len, &tuple_str);
- DEBUG(printf(""handling tuple %s %ld %d\\n"",
- tuple_str, tuple_str_len, num_output_args));
-
if (rc != ADITI_OK) {
+ DEBUG(printf(""no more output tuples\\n""));
found_result = FALSE;
} else {
+ DEBUG(printf(""handling tuple %s %ld %d\\n"",
+ tuple_str, tuple_str_len, num_output_args));
/*
** Found another output tuple.
@@ -692,6 +1203,7 @@
/* Copy out the tuple string. */
make_aligned_string_copy(tuple_str_copy, tuple_str);
+ /* The tuple is on the C heap. */
free(tuple_str);
/*
@@ -700,6 +1212,13 @@
*/
output_save_area = MR_GC_NEW_ARRAY(Word, num_output_args);
+ /*
+ ** This part calls back into Mercury to parse the
+ ** tuple terms from the string returned from Aditi.
+ ** The wrapper functions generated expect the registers
+ ** to be saved, so do that here.
+ */
+ save_registers();
/* convert tuple, put output args in stack slots */
MADITI__init_posn(&pos);
for (i = 0; i < num_output_args; i++) {
@@ -716,7 +1235,6 @@
}
/* Move the output arguments to their registers. */
- save_registers();
for (i = 0; i < num_output_args; i++) {
virtual_reg(first_reg + i) = output_save_area[i];
}
@@ -729,43 +1247,49 @@
return found_result;
}
+/*---------------------------------------------------------------------------*/
+
/*
** Free all resources used by a database call.
*/
static void
-MADITI_cleanup()
+MADITI_post_call_cleanup(void)
{
restore_transient_registers();
+ MADITI_cleanup_call_output((ticket *) MADITI_saved_output_rel,
+ (ticket *) MADITI_saved_cursor);
+ save_transient_registers();
+}
+static void
+MADITI_cleanup_call_output(ticket *output_rel, ticket *cursor)
+{
/* close cursor */
- MADITI_check(ADITI_NAME(cursor_close)(
- (ticket *)MADITI_saved_cursor));
+ MADITI_check(ADITI_NAME(cursor_close)(cursor));
/* destroy cursor */
- MADITI_check(ADITI_NAME(cursor_destroy)(
- (ticket *)MADITI_saved_cursor));
- MR_free((ticket *)MADITI_saved_cursor);
-
- /* destroy output temporary */
- MADITI_check(ADITI_NAME(tmp_destroy)(
- (ticket *)MADITI_saved_output_rel));
- MR_free((ticket *)MADITI_saved_output_rel);
+ MADITI_check(ADITI_NAME(cursor_destroy)(cursor));
+ MR_GC_free(cursor);
- save_transient_registers();
+ /* close output temporary */
+ MADITI_check(ADITI_NAME(rel_close)(output_rel));
+ MR_GC_free(output_rel);
}
+/*---------------------------------------------------------------------------*/
+
/*
** If the status is not OK, abort the transaction.
*/
static void
-MADITI_check(int status)
+MADITI_do_check(int status, int line)
{
if (status != ADITI_OK) {
- MADITI_status = status;
+ DEBUG(printf(""aditi.m:%d MADITI_check_failed, status %d\\n"",
+ line, status));
MR_longjmp(&MADITI_jmp_buf);
}
}
-
").
%-----------------------------------------------------------------------------%
@@ -848,12 +1372,11 @@
:- pragma export(aditi__reverse_append_string_list(in, out),
"MADITI__reverse_append_string_list").
- % Yes, the output of this is meant to have unbalanced parentheses.
aditi__reverse_append_string_list(Strings0, String) :-
( Strings0 = [] ->
String = "()\n"
;
- aditi__construct_attr_list(Strings0, yes, ["\n"], Strings1),
+ aditi__construct_attr_list(Strings0, yes, [")\n"], Strings1),
string__append_list(Strings1, String)
).
@@ -956,7 +1479,7 @@
:- pragma c_code(aditi__error_message(Stat::in, Msg::out),
will_not_call_mercury,
"
- Msg = aditi_strerror(Stat);
+ Msg = aditi_strerror((int) Stat);
").
%-----------------------------------------------------------------------------%
Index: tests/invalid/aditi_update_errors.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/aditi_update_errors.err_exp,v
retrieving revision 1.3
diff -u -u -r1.3 aditi_update_errors.err_exp
--- tests/invalid/aditi_update_errors.err_exp 2000/02/15 00:36:03 1.3
+++ tests/invalid/aditi_update_errors.err_exp 2000/04/04 02:24:48
@@ -1,57 +1,81 @@
-aditi_update_errors.m:091: Error: wrong number of arguments (5; should be 3 or 4)
-aditi_update_errors.m:091: in `aditi_modify'.
-aditi_update_errors.m:090: Error: expected
-aditi_update_errors.m:090: `aditi_modify(
-aditi_update_errors.m:090: (p(<Args0>) ==> p(<Args>) :- <Goal>),
-aditi_update_errors.m:090: DB0, DB)'
-aditi_update_errors.m:090: or `aditi_modify(PredOrFunc p/N, Closure, DB0, DB)'.
-aditi_update_errors.m:081: Error: wrong number of arguments (5; should be 3 or 4)
-aditi_update_errors.m:081: in `aditi_modify'.
-aditi_update_errors.m:080: Error: expected
-aditi_update_errors.m:080: `aditi_modify(
-aditi_update_errors.m:080: (p(<Args0>) ==> p(<Args>) :- <Goal>),
-aditi_update_errors.m:080: DB0, DB)'
-aditi_update_errors.m:080: or `aditi_modify(PredOrFunc p/N, Closure, DB0, DB)'.
-aditi_update_errors.m:071: Error: expected
-aditi_update_errors.m:071: `aditi_modify(
-aditi_update_errors.m:071: (p(<Args0>) ==> p(<Args>) :- <Goal>),
-aditi_update_errors.m:071: DB0, DB)'
-aditi_update_errors.m:071: or `aditi_modify(PredOrFunc p/N, Closure, DB0, DB)'.
-aditi_update_errors.m:067: Error: wrong number of arguments (5; should be 4)
-aditi_update_errors.m:067: in `aditi_bulk_delete'.
-aditi_update_errors.m:066: Error: expected `PredOrFunc Name/Arity' in `aditi_bulk_delete'.
-aditi_update_errors.m:057: Error: wrong number of arguments (5; should be 4)
-aditi_update_errors.m:057: in `aditi_bulk_delete'.
-aditi_update_errors.m:056: Error: expected `PredOrFunc Name/Arity' in `aditi_bulk_insert'.
-aditi_update_errors.m:048: Error: expected `aditi_delete((p(<Args>) :- <Goal>), DB0, DB)'
-aditi_update_errors.m:048: or `aditi_delete(PredOrFunc p/N, Closure, DB0, DB)'.
-aditi_update_errors.m:043: Error: expected `aditi_delete((p(<Args>) :- <Goal>), DB0, DB)'
-aditi_update_errors.m:043: or `aditi_delete(PredOrFunc p/N, Closure, DB0, DB)'.
-aditi_update_errors.m:037: Error: expected `aditi_delete((p(<Args>) :- <Goal>), DB0, DB)'
-aditi_update_errors.m:037: or `aditi_delete(PredOrFunc p/N, Closure, DB0, DB)'.
-aditi_update_errors.m:036: Error: expected `aditi_delete((p(<Args>) :- <Goal>), DB0, DB)'
-aditi_update_errors.m:036: or `aditi_delete(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:090: Error: wrong number of arguments (5; should be 3 or 4)
+aditi_update_errors.m:090: in `aditi_bulk_modify'.
+aditi_update_errors.m:089: Error: expected
+aditi_update_errors.m:089: `aditi_bulk_modify(
+aditi_update_errors.m:089: (p(<Args0>) ==> p(<Args>) :- <Goal>),
+aditi_update_errors.m:089: DB0, DB)'
+aditi_update_errors.m:089: or `aditi_bulk_modify(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:079: Error: wrong number of arguments (5; should be 3 or 4)
+aditi_update_errors.m:079: in `aditi_bulk_modify'.
+aditi_update_errors.m:078: Error: expected
+aditi_update_errors.m:078: `aditi_bulk_modify(
+aditi_update_errors.m:078: (p(<Args0>) ==> p(<Args>) :- <Goal>),
+aditi_update_errors.m:078: DB0, DB)'
+aditi_update_errors.m:078: or `aditi_bulk_modify(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:068: Error: expected
+aditi_update_errors.m:068: `aditi_bulk_modify(
+aditi_update_errors.m:068: (p(<Args0>) ==> p(<Args>) :- <Goal>),
+aditi_update_errors.m:068: DB0, DB)'
+aditi_update_errors.m:068: or `aditi_bulk_modify(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:067: Error: expected
+aditi_update_errors.m:067: `aditi_bulk_modify(
+aditi_update_errors.m:067: (p(<Args0>) ==> p(<Args>) :- <Goal>),
+aditi_update_errors.m:067: DB0, DB)'
+aditi_update_errors.m:067: or `aditi_bulk_modify(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:066: Error: expected
+aditi_update_errors.m:066: `aditi_bulk_modify(
+aditi_update_errors.m:066: (p(<Args0>) ==> p(<Args>) :- <Goal>),
+aditi_update_errors.m:066: DB0, DB)'
+aditi_update_errors.m:066: or `aditi_bulk_modify(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:064: Error: wrong number of arguments (5; should be 3 or 4)
+aditi_update_errors.m:064: in `aditi_bulk_delete'.
+aditi_update_errors.m:063: Error: expected `aditi_bulk_delete((p(<Args>) :- <Goal>), DB0, DB)'
+aditi_update_errors.m:063: or `aditi_bulk_delete(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:046: Error: wrong number of arguments (5; should be 3 or 4)
+aditi_update_errors.m:046: in `aditi_bulk_delete'.
+aditi_update_errors.m:045: Error: expected `aditi_bulk_insert((p(<Args>) :- <Goal>), DB0, DB)'
+aditi_update_errors.m:045: or `aditi_bulk_insert(PredOrFunc p/N, Closure, DB0, DB)'.
+aditi_update_errors.m:037: Error: wrong number of arguments (4; should be 3)
+aditi_update_errors.m:037: in `aditi_delete'.
+aditi_update_errors.m:036: Error: wrong number of arguments (4; should be 3)
+aditi_update_errors.m:036: in `aditi_delete'.
aditi_update_errors.m:034: Error: wrong number of arguments (4; should be 3)
aditi_update_errors.m:034: in `aditi_insert'.
aditi_update_errors.m:033: Error: wrong number of arguments (4; should be 3)
aditi_update_errors.m:033: in `aditi_insert'.
aditi_update_errors.m:031: Error: expected tuple to insert in `aditi_insert'.
-aditi_update_errors.m:073: In clause for predicate `aditi_update_errors:aditi_update_syntax/2':
-aditi_update_errors.m:073: warning: variable `X' has overlapping scopes.
-aditi_update_errors.m:083: In clause for predicate `aditi_update_errors:aditi_update_syntax/2':
-aditi_update_errors.m:083: warning: variable `X' has overlapping scopes.
+aditi_update_errors.m:048: In clause for predicate `aditi_update_errors:aditi_update_syntax/2':
+aditi_update_errors.m:048: warning: variable `X' has overlapping scopes.
+aditi_update_errors.m:070: In clause for predicate `aditi_update_errors:aditi_update_syntax/2':
+aditi_update_errors.m:070: warning: variable `X' has overlapping scopes.
+aditi_update_errors.m:081: In clause for predicate `aditi_update_errors:aditi_update_syntax/2':
+aditi_update_errors.m:081: warning: variable `X' has overlapping scopes.
+aditi_update_errors.m:102: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:102: warning: variable `_Y' occurs more than once in this scope.
+aditi_update_errors.m:102: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:102: warning: variable `_Y' occurs more than once in this scope.
+aditi_update_errors.m:103: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:103: warning: variable `_Y' occurs more than once in this scope.
+aditi_update_errors.m:103: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:103: warning: variable `_Y' occurs more than once in this scope.
+aditi_update_errors.m:166: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:166: warning: variable `DB' occurs only once in this scope.
aditi_update_errors.m:007: Error: no clauses for
aditi_update_errors.m:007: predicate `aditi_update_errors:aditi_update_syntax/2'.
+aditi_update_errors.m:096: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:096: error: wrong number of arguments (2; should be 3)
+aditi_update_errors.m:096: in call to predicate `p'.
aditi_update_errors.m:097: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:097: error: wrong number of arguments (2; should be 3)
-aditi_update_errors.m:097: in call to predicate `p'.
+aditi_update_errors.m:097: error: undefined predicate `q/2'.
+aditi_update_errors.m:097: (There is a *function* with that name, however.
+aditi_update_errors.m:097: Perhaps you forgot to add ` = ...'?)
aditi_update_errors.m:098: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:098: error: undefined predicate `q/2'.
-aditi_update_errors.m:098: (There is a *function* with that name, however.
-aditi_update_errors.m:098: Perhaps you forgot to add ` = ...'?)
+aditi_update_errors.m:098: error: wrong number of arguments (1; should be 2)
+aditi_update_errors.m:098: in call to function `q'.
aditi_update_errors.m:099: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:099: error: wrong number of arguments (1; should be 2)
-aditi_update_errors.m:099: in call to function `q'.
+aditi_update_errors.m:099: in argument 2 of `aditi_insert' of predicate `p/3':
+aditi_update_errors.m:099: type error: argument has type `int',
+aditi_update_errors.m:099: expected type was `(aditi:state)'.
aditi_update_errors.m:100: In clause for predicate `aditi_update_errors:aditi_update_types/2':
aditi_update_errors.m:100: in argument 2 of `aditi_insert' of predicate `p/3':
aditi_update_errors.m:100: type error: argument has type `int',
@@ -65,6 +89,9 @@
aditi_update_errors.m:103: type error: argument has type `float',
aditi_update_errors.m:103: expected type was `int'.
aditi_update_errors.m:105: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:105: error: wrong number of arguments (2; should be 3)
+aditi_update_errors.m:105: in call to predicate `p'.
+aditi_update_errors.m:105: In clause for predicate `aditi_update_errors:aditi_update_types/2':
aditi_update_errors.m:105: in argument 2 of call to predicate `</2':
aditi_update_errors.m:105: type error: argument has type `float',
aditi_update_errors.m:105: expected type was `int'.
@@ -72,83 +99,86 @@
aditi_update_errors.m:105: error: wrong number of arguments (2; should be 3)
aditi_update_errors.m:105: in call to predicate `p'.
aditi_update_errors.m:106: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:106: in argument 1 of call to predicate `</2':
+aditi_update_errors.m:106: type error: variable `Y' has type `((func int) = int)',
+aditi_update_errors.m:106: expected type was `int'.
+aditi_update_errors.m:106: In clause for predicate `aditi_update_errors:aditi_update_types/2':
aditi_update_errors.m:106: error: wrong number of arguments (1; should be 2)
aditi_update_errors.m:106: in call to function `q'.
-aditi_update_errors.m:112: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:112: in argument 2 of `aditi_delete' of predicate `p/3':
-aditi_update_errors.m:112: type error: variable `DeleteP' has type `(aditi_top_down pred(V_10, int))',
-aditi_update_errors.m:112: expected type was `(aditi_top_down pred((aditi:state), int, int))'.
-aditi_update_errors.m:113: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:113: error: undefined predicate `q/2'.
-aditi_update_errors.m:113: (There is a *function* with that name, however.
-aditi_update_errors.m:113: Perhaps you forgot to add ` = ...'?)
-aditi_update_errors.m:118: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:118: in argument 2 of `aditi_delete' of function `q/2':
-aditi_update_errors.m:118: type error: variable `DeleteQ' has type `((aditi_top_down (func V_12)) = int)',
-aditi_update_errors.m:118: expected type was `((aditi_top_down func((aditi:state), int)) = int)'.
-aditi_update_errors.m:119: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:119: error: undefined function `p/3'.
-aditi_update_errors.m:119: (There is a *predicate* with that name, however.)
-aditi_update_errors.m:124: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:124: in argument 2 of `aditi_delete' of function `q/2':
-aditi_update_errors.m:124: type error: variable `DeleteQ2' has type `((func V_14) = int)',
-aditi_update_errors.m:124: expected type was `((aditi_top_down func((aditi:state), int)) = int)'.
-aditi_update_errors.m:132: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:132: error: wrong number of arguments (4; should be 3)
-aditi_update_errors.m:132: in call to predicate `p'.
-aditi_update_errors.m:133: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:133: in argument 2 of `aditi_bulk_insert' of predicate `p/3':
-aditi_update_errors.m:133: type error: variable `InsertP' has type `(aditi_bottom_up pred(V_16, int, float))',
-aditi_update_errors.m:133: expected type was `(aditi_bottom_up pred((aditi:state), int, int))'.
-aditi_update_errors.m:134: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:134: error: undefined predicate `q/2'.
-aditi_update_errors.m:134: (There is a *function* with that name, however.
-aditi_update_errors.m:134: Perhaps you forgot to add ` = ...'?)
-aditi_update_errors.m:142: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:142: in argument 2 of `aditi_bulk_insert' of predicate `p/3':
-aditi_update_errors.m:142: type error: variable `InsertP2' has type `pred(V_19, int, float)',
-aditi_update_errors.m:142: expected type was `(aditi_bottom_up pred((aditi:state), int, int))'.
+aditi_update_errors.m:109: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:109: in argument 2 of `aditi_bulk_delete' of predicate `p/3':
+aditi_update_errors.m:109: type error: variable `DeleteP' has type `(aditi_bottom_up pred(V_11, int))',
+aditi_update_errors.m:109: expected type was `(aditi_bottom_up pred((aditi:state), int, int))'.
+aditi_update_errors.m:110: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:110: error: undefined predicate `q/2'.
+aditi_update_errors.m:110: (There is a *function* with that name, however.
+aditi_update_errors.m:110: Perhaps you forgot to add ` = ...'?)
+aditi_update_errors.m:115: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:115: in argument 2 of `aditi_bulk_delete' of function `q/2':
+aditi_update_errors.m:115: type error: variable `DeleteQ' has type `((aditi_bottom_up (func V_13)) = int)',
+aditi_update_errors.m:115: expected type was `((aditi_bottom_up func((aditi:state), int)) = int)'.
+aditi_update_errors.m:116: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:116: error: undefined function `p/3'.
+aditi_update_errors.m:116: (There is a *predicate* with that name, however.)
+aditi_update_errors.m:121: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:121: in argument 2 of `aditi_bulk_delete' of function `q/2':
+aditi_update_errors.m:121: type error: variable `DeleteQ2' has type `((func V_15) = int)',
+aditi_update_errors.m:121: expected type was `((aditi_bottom_up func((aditi:state), int)) = int)'.
+aditi_update_errors.m:129: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:129: error: wrong number of arguments (4; should be 3)
+aditi_update_errors.m:129: in call to predicate `p'.
+aditi_update_errors.m:130: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:130: in argument 2 of `aditi_bulk_insert' of predicate `p/3':
+aditi_update_errors.m:130: type error: variable `InsertP' has type `(aditi_bottom_up pred(V_17, int, float))',
+aditi_update_errors.m:130: expected type was `(aditi_bottom_up pred((aditi:state), int, int))'.
+aditi_update_errors.m:131: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:131: error: undefined predicate `q/2'.
+aditi_update_errors.m:131: (There is a *function* with that name, however.
+aditi_update_errors.m:131: Perhaps you forgot to add ` = ...'?)
+aditi_update_errors.m:139: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:139: in argument 2 of `aditi_bulk_insert' of predicate `p/3':
+aditi_update_errors.m:139: type error: variable `InsertP2' has type `pred(V_20, int, float)',
+aditi_update_errors.m:139: expected type was `(aditi_bottom_up pred((aditi:state), int, int))'.
+aditi_update_errors.m:149: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:149: error: undefined predicate `q/2'.
+aditi_update_errors.m:149: (There is a *function* with that name, however.
+aditi_update_errors.m:149: Perhaps you forgot to add ` = ...'?)
aditi_update_errors.m:152: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:152: error: undefined predicate `q/2'.
-aditi_update_errors.m:152: (There is a *function* with that name, however.
-aditi_update_errors.m:152: Perhaps you forgot to add ` = ...'?)
-aditi_update_errors.m:155: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:155: in argument 1 of `aditi_modify' of predicate `p/3':
-aditi_update_errors.m:155: type error: argument has type `(aditi_top_down pred(int, int, V_27, int, int, V_30))',
-aditi_update_errors.m:155: expected type was `(aditi_top_down pred((aditi:state), int, int, (aditi:state), int, int))'.
-aditi_update_errors.m:156: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:156: error: wrong number of arguments (1; should be 2)
-aditi_update_errors.m:156: in call to function `q'.
-aditi_update_errors.m:157: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:157: error: undefined predicate `q/3'.
-aditi_update_errors.m:157: (There is a *function* with that name, however.
-aditi_update_errors.m:157: Perhaps you forgot to add ` = ...'?)
-aditi_update_errors.m:163: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:163: in unification of variable `X'
-aditi_update_errors.m:163: and term `(X0 + Y0)':
-aditi_update_errors.m:163: type error in argument(s) of functor `+/2'.
-aditi_update_errors.m:163: Argument 1 (X0) has type `float',
-aditi_update_errors.m:163: expected type was `int';
-aditi_update_errors.m:163: argument 2 (Y0) has type `V_43',
-aditi_update_errors.m:163: expected type was `int'.
-aditi_update_errors.m:164: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:164: in unification of variable `Y'
-aditi_update_errors.m:164: and term `(X0 - Y0)':
-aditi_update_errors.m:164: type error in argument(s) of functor `-/2'.
-aditi_update_errors.m:164: Argument 1 (X0) has type `float',
-aditi_update_errors.m:164: expected type was `int';
-aditi_update_errors.m:164: argument 2 (Y0) has type `V_43',
-aditi_update_errors.m:164: expected type was `int'.
-aditi_update_errors.m:166: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:166: in argument 2 of `aditi_modify' of predicate `p/3':
-aditi_update_errors.m:166: type error: variable `ModifyP' has type `(aditi_top_down pred(V_41, float, V_43, V_44, V_45, V_46))',
-aditi_update_errors.m:166: expected type was `(aditi_top_down pred((aditi:state), int, int, (aditi:state), int, int))'.
-aditi_update_errors.m:175: In clause for predicate `aditi_update_errors:aditi_update_types/2':
-aditi_update_errors.m:175: in argument 2 of `aditi_modify' of function `q/2':
-aditi_update_errors.m:175: type error: variable `ModifyQ' has type `((aditi_top_down func(V_47, int, int, V_50, int)) = int)',
-aditi_update_errors.m:175: expected type was `(aditi_top_down pred((aditi:state), int, int, (aditi:state), int, int))'.
+aditi_update_errors.m:152: in argument 4 of clause head:
+aditi_update_errors.m:152: in unification of argument
+aditi_update_errors.m:152: and term `(X0 + V_91)':
+aditi_update_errors.m:152: type error in argument(s) of functor `+/2'.
+aditi_update_errors.m:152: Argument 1 (X0) has type `(aditi:state)',
+aditi_update_errors.m:152: expected type was `int'.
+aditi_update_errors.m:153: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:153: in argument 4 of clause head:
+aditi_update_errors.m:153: in unification of argument
+aditi_update_errors.m:153: and term `(Y0 + V_87)':
+aditi_update_errors.m:153: type error in argument(s) of functor `+/2'.
+aditi_update_errors.m:153: Argument 1 (Y0) has type `((func int) = int)',
+aditi_update_errors.m:153: expected type was `int'.
+aditi_update_errors.m:153: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:153: error: wrong number of arguments (1; should be 2)
+aditi_update_errors.m:153: in call to function `q'.
+aditi_update_errors.m:154: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:154: error: undefined predicate `q/3'.
+aditi_update_errors.m:154: (There is a *function* with that name, however.
+aditi_update_errors.m:154: Perhaps you forgot to add ` = ...'?)
+aditi_update_errors.m:154: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:154: error: undefined predicate `q/3'.
+aditi_update_errors.m:154: (There is a *function* with that name, however.
+aditi_update_errors.m:154: Perhaps you forgot to add ` = ...'?)
+aditi_update_errors.m:160: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:160: type error in unification of variable `X0'
+aditi_update_errors.m:160: and constant `1.00000000000000'.
+aditi_update_errors.m:160: variable `X0' has type `int',
+aditi_update_errors.m:160: constant `1.00000000000000' has type `float'.
+aditi_update_errors.m:173: In clause for predicate `aditi_update_errors:aditi_update_types/2':
+aditi_update_errors.m:173: in argument 2 of `aditi_bulk_modify' of function `q/2':
+aditi_update_errors.m:173: type error: variable `ModifyQ' has type `((aditi_bottom_up func(V_48, int, int, V_51, int)) = int)',
+aditi_update_errors.m:173: expected type was `(aditi_bottom_up pred((aditi:state), int, int, (aditi:state), int, int))'.
aditi_update_errors.m:026: Error: no clauses for
aditi_update_errors.m:026: predicate `aditi_update_errors:anc/3'.
-aditi_update_errors.m:094: In `aditi_insert' of predicate `anc/3':
-aditi_update_errors.m:094: error: the modified predicate is not a base relation.
+aditi_update_errors.m:093: In `aditi_insert' of predicate `anc/3':
+aditi_update_errors.m:093: error: the modified predicate is not a base relation.
For more information, try recompiling with `-E'.
Index: tests/invalid/aditi_update_errors.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/aditi_update_errors.m,v
retrieving revision 1.1
diff -u -u -r1.1 aditi_update_errors.m
--- tests/invalid/aditi_update_errors.m 1999/07/13 08:55:06 1.1
+++ tests/invalid/aditi_update_errors.m 2000/04/04 02:24:29
@@ -33,20 +33,9 @@
aditi_insert(p(_, 1, 2), foo),
aditi_insert(q(_, 1) = 2, foo),
- aditi_delete(p(_, X, _Y) :- X < 2, foo),
- aditi_delete(q(_, X) = _Y :- X < 2, foo),
+ aditi_delete(p(_, X, _Y), _),
+ aditi_delete(q(_, X) = _Y, _),
- { DeleteP =
- (aditi_top_down pred(_::unused, 1::in, 2::in) is semidet :-
- true
- ) },
- aditi_delete(p/3, DeleteP),
-
- { DeleteQ =
- (aditi_top_down func(_::unused, 1::in) = (2::in) is semidet)
- },
- aditi_delete(q/2, DeleteQ),
-
{ InsertP =
(aditi_bottom_up pred(_::aditi_ui, A1::out, A2::out) is nondet :-
( A1 = 1, A2 = 2
@@ -56,6 +45,14 @@
aditi_bulk_insert(p/3, InsertP),
aditi_bulk_delete(pred p/3, InsertP, foo),
+ aditi_bulk_insert(
+ (p(_, X, Y, Z) :-
+ ( X = 1, Y = 2, Z = 2
+ ; X = 2, Y = 3, Z = 4
+ )
+ )
+ ),
+
{ InsertQ =
(aditi_bottom_up func(_::aditi_ui, A1::out)
= (A2::out) is nondet :-
@@ -66,29 +63,31 @@
aditi_bulk_delete(q/2, InsertQ),
aditi_bulk_delete(func q/2, InsertQ, foo),
- aditi_modify(p(_, X0, Y0) ==> p(_, X0 + 1, Y0 + 1)),
- aditi_modify((q(_, X0) = Y0) ==> (q(_, X0 + 1) = (Y0 + 1))),
- aditi_modify(q(_, _X0) ==> _Y0),
+ aditi_bulk_modify(p(_, X0, Y0, _) ==> p(_, X0 + 1, Y0 + 1)),
+ aditi_bulk_modify((q(_, X0, _) = Y0) ==> (q(_, X0 + 1) = (Y0 + 1))),
+ aditi_bulk_modify(q(_, _X0) ==> _Y0),
{ ModifyP =
- (aditi_top_down pred(_::unused, X0::in, Y0::in,
- _::unused, X::out, Y::out) is semidet :-
+ (aditi_bottom_up pred(DB::aditi_ui, X0::out, Y0::out,
+ _::unused, X::out, Y::out) is nondet :-
+ p(DB, X0, Y0),
X0 = 1,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(p/3, ModifyP),
- aditi_modify(pred p/3, ModifyP, foo),
+ aditi_bulk_modify(p/3, ModifyP),
+ aditi_bulk_modify(pred p/3, ModifyP, foo),
{ ModifyQ =
- (aditi_top_down pred(_::unused, X0::in, Y0::in,
- _::unused, X::out, Y::out) is semidet :-
+ (aditi_bottom_up pred(DB::aditi_ui, X0::out, Y0::out,
+ _::unused, X::out, Y::out) is nondet :-
+ q(DB, X) = Y,
X0 = 1,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(q/2, ModifyQ),
- aditi_modify(func q/2, ModifyQ, foo).
+ aditi_bulk_modify(q/2, ModifyQ),
+ aditi_bulk_modify(func q/2, ModifyQ, foo).
aditi_update_derived_relation -->
aditi_insert(anc(_, 1, 2)).
@@ -98,30 +97,28 @@
aditi_insert(q(_, 1)),
aditi_insert(q(_) = 2),
{ aditi_insert(p(_, 1, 2), 1, _) },
+ { aditi_delete(p(_, 1, 2), 1, _) },
- aditi_delete(p(_, X, _Y) :- X < 2.0),
- aditi_delete(q(_, X) = _Y :- X < 2.0),
+ aditi_bulk_delete(p(_, X, _Y) :- X < 2.0),
+ aditi_bulk_delete(q(_, X) = _Y :- X < 2.0),
- aditi_delete(p(_, X) :- X < 2.0),
- aditi_delete(q(_) = Y :- Y < 2),
+ aditi_bulk_delete(p(_, X) :- X < 2.0),
+ aditi_bulk_delete(q(_) = Y :- Y < 2),
- { DeleteP =
- (aditi_top_down pred(_::unused, 2::in) is semidet :-
- true
- ) },
- aditi_delete(pred p/3, DeleteP),
- aditi_delete(pred q/2, DeleteP),
+ { DeleteP = (aditi_bottom_up pred(_::aditi_ui, 2::out) is nondet) },
+ aditi_bulk_delete(pred p/3, DeleteP),
+ aditi_bulk_delete(pred q/2, DeleteP),
{ DeleteQ =
- (aditi_top_down func(_::unused) = (2::in) is semidet)
+ (aditi_bottom_up func(_::unused) = (2::in) is nondet)
},
- aditi_delete(func q/2, DeleteQ),
- aditi_delete(func p/3, DeleteQ),
+ aditi_bulk_delete(func q/2, DeleteQ),
+ aditi_bulk_delete(func p/3, DeleteQ),
{ DeleteQ2 =
- (func(_::unused) = (2::in) is semidet)
+ (func(_::aditi_ui) = (2::out) is nondet)
},
- aditi_delete(func q/2, DeleteQ2),
+ aditi_bulk_delete(func q/2, DeleteQ2),
{ InsertP =
(aditi_bottom_up pred(_::aditi_ui, A1::out, A2::out) is nondet :-
@@ -152,25 +149,26 @@
aditi_bulk_insert(pred q/2, InsertQ),
aditi_bulk_delete(func q/2, InsertQ),
- aditi_modify(p(X0, Y0, _) ==> p(X0 + 1, Y0 + 1, _)),
- aditi_modify((q(_) = Y0) ==> (q(_) = (Y0 + 1))),
- aditi_modify(q(_, X0, Y0) ==> q(_, X0 + 1, Y0 + 1)),
+ aditi_bulk_modify(p(X0, Y0, _) ==> p(X0 + 1, Y0 + 1, _)),
+ aditi_bulk_modify((q(_) = Y0) ==> (q(_) = (Y0 + 1))),
+ aditi_bulk_modify(q(_, X0, Y0) ==> q(_, X0 + 1, Y0 + 1)),
{ ModifyP =
- (aditi_top_down pred(_::unused, X0::in, Y0::in,
- _::unused, X::out, Y::out) is semidet :-
+ (aditi_bottom_up pred(DB::aditi_ui, X0::out, Y0::out,
+ _::unused, X::out, Y::out) is nondet :-
+ p(DB, X0, Y0),
X0 = 1.0,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(pred p/3, ModifyP),
+ aditi_bulk_modify(pred p/3, ModifyP),
{ ModifyQ =
- (aditi_top_down func(_::unused, X0::in, Y0::in,
- _::unused, X::out) = (Y::out) is semidet :-
+ (aditi_bottom_up func(DB::aditi_ui, X0::out, Y0::out,
+ _::unused, X::out) = (Y::out) is nondet :-
X0 = 1,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(func q/2, ModifyQ).
+ aditi_bulk_modify(func q/2, ModifyQ).
Index: tests/invalid/aditi_update_mode_errors.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/aditi_update_mode_errors.err_exp,v
retrieving revision 1.2
diff -u -u -r1.2 aditi_update_mode_errors.err_exp
--- tests/invalid/aditi_update_mode_errors.err_exp 1999/07/14 07:03:38 1.2
+++ tests/invalid/aditi_update_mode_errors.err_exp 2000/04/04 02:24:58
@@ -1,10 +1,26 @@
aditi_update_mode_errors.m:062: In clause for predicate `aditi_update_mode_errors:aditi_update_modes4/2':
+aditi_update_mode_errors.m:062: warning: variables `_X, _Y' occur more than once in this scope.
+aditi_update_mode_errors.m:062: In clause for predicate `aditi_update_mode_errors:aditi_update_modes4/2':
+aditi_update_mode_errors.m:062: warning: variables `_X, _Y' occur more than once in this scope.
+aditi_update_mode_errors.m:062: In clause for predicate `aditi_update_mode_errors:aditi_update_modes4/2':
aditi_update_mode_errors.m:062: warning: variable `X' occurs only once in this scope.
aditi_update_mode_errors.m:065: In clause for predicate `aditi_update_mode_errors:aditi_update_modes5/2':
+aditi_update_mode_errors.m:065: warning: variables `_X, _Y' occur more than once in this scope.
+aditi_update_mode_errors.m:065: In clause for predicate `aditi_update_mode_errors:aditi_update_modes5/2':
+aditi_update_mode_errors.m:065: warning: variables `_X, _Y' occur more than once in this scope.
+aditi_update_mode_errors.m:065: In clause for predicate `aditi_update_mode_errors:aditi_update_modes5/2':
aditi_update_mode_errors.m:065: warning: variable `X' occurs only once in this scope.
aditi_update_mode_errors.m:102: In clause for predicate `aditi_update_mode_errors:aditi_update_modes10/2':
+aditi_update_mode_errors.m:102: warning: variable `_X0' occurs more than once in this scope.
+aditi_update_mode_errors.m:102: In clause for predicate `aditi_update_mode_errors:aditi_update_modes10/2':
+aditi_update_mode_errors.m:102: warning: variable `_X0' occurs more than once in this scope.
+aditi_update_mode_errors.m:102: In clause for predicate `aditi_update_mode_errors:aditi_update_modes10/2':
aditi_update_mode_errors.m:102: warning: variable `X0' occurs only once in this scope.
aditi_update_mode_errors.m:105: In clause for predicate `aditi_update_mode_errors:aditi_update_modes11/2':
+aditi_update_mode_errors.m:105: warning: variable `_X0' occurs more than once in this scope.
+aditi_update_mode_errors.m:105: In clause for predicate `aditi_update_mode_errors:aditi_update_modes11/2':
+aditi_update_mode_errors.m:105: warning: variable `_X0' occurs more than once in this scope.
+aditi_update_mode_errors.m:105: In clause for predicate `aditi_update_mode_errors:aditi_update_modes11/2':
aditi_update_mode_errors.m:105: warning: variable `X0' occurs only once in this scope.
aditi_update_mode_errors.m:053: In clause for `aditi_update_modes1((aditi:aditi_di), (aditi:aditi_uo))':
aditi_update_mode_errors.m:053: in argument 2 of the inserted tuple of `aditi_insert' of predicate `p/3':
@@ -27,13 +43,13 @@
aditi_update_mode_errors.m:065: mode error: variable `X' has instantiatedness `free',
aditi_update_mode_errors.m:065: expected instantiatedness was `ground'.
aditi_update_mode_errors.m:072: In clause for `aditi_update_modes6((aditi:aditi_di), (aditi:aditi_uo))':
-aditi_update_mode_errors.m:072: in argument 2 of `aditi_delete' of predicate `p/3':
-aditi_update_mode_errors.m:072: mode error: variable `DeleteP' has instantiatedness `/* unique */(pred((free -> free), (free -> ground), (ground -> ground)) is semidet)',
-aditi_update_mode_errors.m:072: expected instantiatedness was `(pred(unused, in, in) is semidet)'.
+aditi_update_mode_errors.m:072: in argument 2 of `aditi_bulk_delete' of predicate `p/3':
+aditi_update_mode_errors.m:072: mode error: variable `DeleteP' has instantiatedness `/* unique */(pred((free -> free), (free -> ground), (ground -> ground)) is nondet)',
+aditi_update_mode_errors.m:072: expected instantiatedness was `(pred(in, out, out) is nondet)'.
aditi_update_mode_errors.m:078: In clause for `aditi_update_modes7((aditi:aditi_di), (aditi:aditi_uo))':
-aditi_update_mode_errors.m:078: in argument 2 of `aditi_delete' of function `q/2':
-aditi_update_mode_errors.m:078: mode error: variable `DeleteQ' has instantiatedness `/* unique */(func((free -> free), (free -> ground)) = (ground -> ground) is semidet)',
-aditi_update_mode_errors.m:078: expected instantiatedness was `(func(unused, in) = in is semidet)'.
+aditi_update_mode_errors.m:078: in argument 2 of `aditi_bulk_delete' of function `q/2':
+aditi_update_mode_errors.m:078: mode error: variable `DeleteQ' has instantiatedness `/* unique */(func((free -> free), (free -> ground)) = (ground -> ground) is nondet)',
+aditi_update_mode_errors.m:078: expected instantiatedness was `(func(in, out) = out is nondet)'.
aditi_update_mode_errors.m:087: In clause for `aditi_update_modes8((aditi:aditi_di), (aditi:aditi_uo))':
aditi_update_mode_errors.m:087: in argument 2 of `aditi_bulk_insert' of predicate `p/3':
aditi_update_mode_errors.m:087: mode error: variable `InsertP' has instantiatedness `/* unique */(pred((ground -> ground), (ground -> ground), (free -> ground)) is nondet)',
@@ -53,13 +69,13 @@
aditi_update_mode_errors.m:105: have insts `free, unique(1), free',
aditi_update_mode_errors.m:105: which does not match any of the modes for function `int:+/2'.
aditi_update_mode_errors.m:115: In clause for `aditi_update_modes12((aditi:aditi_di), (aditi:aditi_uo))':
-aditi_update_mode_errors.m:115: in argument 2 of `aditi_modify' of predicate `p/3':
+aditi_update_mode_errors.m:115: in argument 2 of `aditi_bulk_modify' of predicate `p/3':
aditi_update_mode_errors.m:115: mode error: variable `ModifyP' has instantiatedness `/* unique */(pred((free -> free), (free -> ground), (free -> ground), (free -> free), (ground -> ground), (ground -> ground)) is semidet)',
-aditi_update_mode_errors.m:115: expected instantiatedness was `(pred(unused, in, in, unused, out, out) is semidet)'.
+aditi_update_mode_errors.m:115: expected instantiatedness was `(pred(in, out, out, unused, out, out) is nondet)'.
aditi_update_mode_errors.m:125: In clause for `aditi_update_modes13((aditi:aditi_di), (aditi:aditi_uo))':
-aditi_update_mode_errors.m:125: in argument 2 of `aditi_modify' of function `q/2':
-aditi_update_mode_errors.m:125: mode error: variable `ModifyQ' has instantiatedness `/* unique */(pred((free -> free), (ground -> ground), (ground -> ground), (free -> free), (ground -> ground), (ground -> ground)) is semidet)',
-aditi_update_mode_errors.m:125: expected instantiatedness was `(pred(unused, in, in, unused, out, out) is semidet)'.
+aditi_update_mode_errors.m:125: in argument 2 of `aditi_bulk_modify' of function `q/2':
+aditi_update_mode_errors.m:125: mode error: variable `ModifyQ' has instantiatedness `/* unique */(pred((free -> free), (ground -> ground), (ground -> ground), (free -> free), (ground -> ground), (ground -> ground)) is nondet)',
+aditi_update_mode_errors.m:125: expected instantiatedness was `(pred(in, out, out, unused, out, out) is nondet)'.
aditi_update_mode_errors.m:047: In clause for `anc((aditi:aditi_ui), out, out)':
aditi_update_mode_errors.m:047: in argument 2 of clause head:
aditi_update_mode_errors.m:047: mode error in unification of `HeadVar__2' and `X'.
Index: tests/invalid/aditi_update_mode_errors.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/aditi_update_mode_errors.m,v
retrieving revision 1.1
diff -u -u -r1.1 aditi_update_mode_errors.m
--- tests/invalid/aditi_update_mode_errors.m 1999/07/13 08:55:07 1.1
+++ tests/invalid/aditi_update_mode_errors.m 2000/04/04 02:24:29
@@ -59,23 +59,23 @@
{ aditi_insert(p(_, 1, 2), _, _) }.
aditi_update_modes4 -->
- aditi_delete(p(_, _X, _Y) :- X < 2).
+ aditi_bulk_delete(p(_, _X, _Y) :- X < 2).
aditi_update_modes5 -->
- aditi_delete(q(_, _X) = _Y :- X < 2).
+ aditi_bulk_delete(q(_, _X) = _Y :- X < 2).
aditi_update_modes6 -->
{ DeleteP =
- (aditi_top_down pred(_::unused, 1::out, 2::in) is semidet :-
+ (aditi_bottom_up pred(_::unused, 1::out, 2::in) is nondet :-
true
) },
- aditi_delete(pred p/3, DeleteP).
+ aditi_bulk_delete(pred p/3, DeleteP).
aditi_update_modes7 -->
{ DeleteQ =
- (aditi_top_down func(_::unused, 1::out) = (2::in) is semidet)
+ (aditi_bottom_up func(_::unused, 1::out) = (2::in) is nondet)
},
- aditi_delete(func q/2, DeleteQ).
+ aditi_bulk_delete(func q/2, DeleteQ).
aditi_update_modes8 -->
{ InsertP =
@@ -99,28 +99,28 @@
aditi_bulk_delete(func q/2, InsertQ).
aditi_update_modes10 -->
- aditi_modify(p(_, _X0, Y0) ==> p(_, X0 + 1, Y0 + 1)).
+ aditi_bulk_modify(p(_, _X0, Y0) ==> p(_, X0 + 1, Y0 + 1)).
aditi_update_modes11 -->
- aditi_modify((q(_, _X0) = Y0) ==> (q(_, X0 + 1) = (Y0 + 1))).
+ aditi_bulk_modify((q(_, _X0) = Y0) ==> (q(_, X0 + 1) = (Y0 + 1))).
aditi_update_modes12 -->
{ ModifyP =
- (aditi_top_down pred(_::unused, X0::out, Y0::out,
+ (aditi_bottom_up pred(_::unused, X0::out, Y0::out,
_::unused, X::in, Y::in) is semidet :-
X0 = 1,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(pred p/3, ModifyP).
+ aditi_bulk_modify(pred p/3, ModifyP).
aditi_update_modes13 -->
{ ModifyQ =
- (aditi_top_down pred(_::unused, X0::in, Y0::in,
- _::unused, X::in, Y::in) is semidet :-
+ (aditi_bottom_up pred(_::unused, X0::in, Y0::in,
+ _::unused, X::in, Y::in) is nondet :-
X0 = 1,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(func q/2, ModifyQ).
+ aditi_bulk_modify(func q/2, ModifyQ).
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.60
diff -u -u -r1.60 Mmakefile
--- tests/valid/Mmakefile 2000/04/06 05:33:32 1.60
+++ tests/valid/Mmakefile 2000/04/11 05:52:03
@@ -27,6 +27,7 @@
instance_unconstrained_tvar.m
OTHER_SOURCES= \
+ aditi_update.m \
base_relation.m \
base_relation2.m \
common_struct_bug.m \
@@ -135,10 +136,6 @@
vn_float.m \
zero_arity.m
-# Code generation is not yet implemented for Aditi updates,
-# so don't attempt to compile to C.
-# aditi_update.m
-
# The mode system can't handle the following test cases yet:
# assoc_list.m
# determinism.m
@@ -233,7 +230,7 @@
intermod_nested_module2.date: intermod_nested_module2.date0
intermod_user_equality_nested2.date: intermod_user_equality_nested2.date0
-check: objs aditi_update.err
+check: objs
objs: $(OBJS)
Index: tests/valid/aditi_update.m
===================================================================
RCS file: /home/mercury1/repository/tests/valid/aditi_update.m,v
retrieving revision 1.1
diff -u -u -r1.1 aditi_update.m
--- tests/valid/aditi_update.m 1999/07/13 08:55:28 1.1
+++ tests/valid/aditi_update.m 2000/03/22 00:42:21
@@ -19,19 +19,18 @@
aditi_insert(p(_, 1, 2)),
aditi_insert(q(_, 1) = 2),
- aditi_delete(p(_, X, _Y) :- X < 2),
- aditi_delete(q(_, X) = _Y :- X < 2),
+ aditi_delete(p(_, 1, 2)),
+ aditi_delete(q(_, 1) = 2),
- { DeleteP =
- (aditi_top_down pred(_::unused, 1::in, 2::in) is semidet :-
- true
- ) },
- aditi_delete(pred p/3, DeleteP),
-
- { DeleteQ =
- (aditi_top_down func(_::unused, 1::in) = (2::in) is semidet)
- },
- aditi_delete(func q/2, DeleteQ),
+ aditi_bulk_insert(
+ (p(_, X, Y) :-
+ ( X = 1, Y = 2
+ ; X = 2, Y = 3
+ )
+ )),
+
+ aditi_bulk_delete(p(_, X, _) :- X < 2),
+ aditi_bulk_delete(q(_, X) = _ :- X < 2),
{ InsertP =
(aditi_bottom_up pred(_::aditi_ui, A1::out, A2::out) is nondet :-
@@ -42,6 +41,14 @@
aditi_bulk_insert(pred p/3, InsertP),
aditi_bulk_delete(pred p/3, InsertP),
+ aditi_bulk_insert(
+ (p(_, A1, A2) :-
+ ( A1 = 1, A2 = 2
+ ; A1 = 2, A2 = 3
+ )
+ )
+ ),
+
{ InsertQ =
(aditi_bottom_up func(_::aditi_ui, A1::out)
= (A2::out) is nondet :-
@@ -51,29 +58,39 @@
) },
aditi_bulk_insert(func q/2, InsertQ),
aditi_bulk_delete(func q/2, InsertQ),
+
+ aditi_bulk_insert(
+ (q(_, A1) = A2 :-
+ ( A1 = 1, A2 = 2
+ ; A1 = 2, A2 = 3
+ )
+ )
+ ),
- aditi_modify(p(_, X0, Y0) ==> p(_, X0 + 1, Y0 + 1)),
- aditi_modify((p(_, X0, Y0) ==> p(_, X, Y) :-
+ aditi_bulk_modify(p(_, X0, Y0) ==> p(_, X0 + 1, Y0 + 1)),
+ aditi_bulk_modify((p(_, X0, Y0) ==> p(_, X, Y) :-
X = X0 + 1,
Y = Y0 + 1
)),
- aditi_modify((q(_, X0) = Y0) ==> (q(_, X0 + 1) = (Y0 + 1))),
+ aditi_bulk_modify((q(_, X0) = Y0) ==> (q(_, X0 + 1) = (Y0 + 1))),
- { ModifyP =
- (aditi_top_down pred(_::unused, X0::in, Y0::in,
- _::unused, X::out, Y::out) is semidet :-
+ { ModifyP1 =
+ (aditi_bottom_up pred(DB::aditi_ui, X0::out, Y0::out,
+ _::unused, X::out, Y::out) is nondet :-
+ p(DB, X0, Y0),
X0 = 1,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(pred p/3, ModifyP),
+ aditi_bulk_modify(pred p/3, ModifyP1),
{ ModifyQ =
- (aditi_top_down pred(_::unused, X0::in, Y0::in,
- _::unused, X::out, Y::out) is semidet :-
+ (aditi_bottom_up pred(DB::aditi_ui, X0::out, Y0::out,
+ _::unused, X::out, Y::out) is nondet :-
+ q(DB, X0) = Y0,
X0 = 1,
X = X0 + Y0,
Y = X0 - Y0
) },
- aditi_modify(func q/2, ModifyQ).
+ aditi_bulk_modify(func q/2, ModifyQ).
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list