[m-dev.] for review: Aditi update doc extractuu
Simon Taylor
stayl at cs.mu.OZ.AU
Mon Jul 12 14:30:37 AEST 1999
> On 06-Jul-1999, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> >
> > > If I have a `det' base relation, does it make any sense to do insertions
> > > or deletions on it? Modifications make sense, but I think any insertions
> > > (except perhaps inserting tuples that are already present) or deletions
> > > will always violate the declared determinism, won't they?
> >
> > Yes.
>
> In that case, would it be a good idea for the compiler to report
> an error or warning if you attempt to do that?
Possibly, although I would expect `det' base relations to be fairly uncommon.
To deal with your other points, I've duplicated the syntax conventions
for each update goal type.
Simon.
--- reference_manual.texi 1999/07/08 02:02:25 1.7
+++ reference_manual.texi 1999/07/12 04:20:50
@@ -511,6 +511,19 @@
higher-order call using the @code{call/N} syntax, i.e.
@samp{call(Var)}, @samp{call(Var, Arg1)}, etc.
+ at ifset aditi
+
+ at item @code{aditi_bulk_delete(@dots{})}
+ at item @code{aditi_bulk_insert(@dots{})}
+ at item @code{aditi_delete(@dots{})}
+ at item @code{aditi_insert(@dots{})}
+ at item @code{aditi_modify(@dots{})}
+These goal forms are used for the Aditi database interface.
+ at xref{Aditi update syntax}.
+
+ at end ifset
+ at c aditi
+
@item @code{@var{Call}}
Any goal which does not match any of the above forms
must be a predicate call.
@@ -5341,13 +5498,13 @@
be stratified (@pxref{Aditi glossary}) and must not be mutually recursive
with predicates in other modules.
-Every predicate with a @samp{:- pragma aditi} or
- at samp{:- pragma base_relation} declaration must have an input
+Every predicate with a @samp{pragma aditi} or
+ at samp{pragma base_relation} declaration must have an input
argument of type @samp{aditi__state}. This ensures that Aditi predicates
are only called from within transactions and that updates and database
calls are ordered correctly, in the same way that @samp{io__state} arguments
are used to ensure ordering of I/O operations. Within the clauses for
-predicates with a @samp{:- pragma aditi} declaration variables with
+predicates with a @samp{pragma aditi} declaration variables with
type @samp{aditi__state} may only be passed to other database predicates --
they may not be packaged into terms or passed to top-down Mercury predicates.
This allows the compiler to remove all instances of @samp{aditi__state}
@@ -5416,7 +5573,7 @@
The predicate is owned by the named user. A predicate in the database
is identified by owner, module name, predicate name and arity. The owner
-field is used for security checks. If no @samp{:- pragma owner}
+field is used for security checks. If no @samp{pragma owner}
declaration is given, the owner is taken from the @samp{--aditi-user}
option, which defaults to the value of the environment variable @samp{USER},
or ``guest'' if that is not set.
@@ -5450,8 +5607,7 @@
* Aditi update notes::
* Insertion::
* Deletion::
-* Bulk insertion::
-* Bulk deletion::
+* Bulk insertion and deletion::
* Modification::
@end menu
@end ignore
@@ -5459,46 +5615,17 @@
@c @node Aditi update notes::
@subsubheading Aditi update notes
-There must be a @w{@samp{:- pragma base_relation}} declaration for
+All Aditi update goals have determinism @samp{det}.
+
+There must be a @w{@samp{pragma base_relation}} declaration for
any relation to be updated.
It is currently up to the application to ensure that any modifications
-do not violate the determinism of a base relation. Updates of relations
-with unique B-tree indexes are checked to ensure that a key is not
-given multiple values. The transaction will abort if this occurs.
-
-The following naming conventions are used in the specification
-of the Aditi update syntax:
- at itemize @bullet
- at item
- at samp{@var{PredName}} is the name of a predicate.
-
- at item
- at samp{@var{FuncName}} is the name of a function.
-
- at item
- at samp{@var{Name}} is the name of a predicate or a function.
-
- at item
- at samp{@var{PredOrFunc}} is either @samp{pred} or @samp{func},
-depending on whether a predicate or function is being updated.
-
- at item
- at samp{@var{Arity}} is the arity of the predicate or function
-being updated.
-
- at item
- at samp{@var{Goal}} is any Mercury goal.
-
- at item
- at samp{@var{Closure}} is a term which has a higher-order type.
-
- at item
-Variables named @samp{DB at var{N}} are @samp{aditi__state} variables.
-When occuring as a pair at the end of an argument list, they have
-mode @w{@samp{aditi_di, aditi_uo}}.
-
- at end itemize
+do not violate the determinism of a base relation. If any modification
+does violate the determinism of a base relation, then the behaviour
+is undefined. However, updates of relations with unique B-tree indexes
+are checked to ensure that a key is not given multiple values. The transaction
+will abort if this occurs.
Predicate and function names in Aditi update goals may be module qualified.
@@ -5523,11 +5650,29 @@
aditi_insert(@var{FuncName}(@var{Arg1}, @var{Arg2}, @dots{}) = @var{RetVal}, @var{DB0}, @var{DB}).
@end example
-Insert the specified tuple into a relation. The tuple to be inserted
-must have the same type signature as the relation. All the arguments
-of the tuple have mode @samp{in}, except the @samp{aditi__state} argument
+Insert the specified tuple into a relation.
+
+ at itemize @bullet
+ at item
+ at samp{@var{PredName}} must be the name of a predicate.
+
+ at item
+ at samp{@var{FuncName}} must be the name of a function.
+
+ at item
+ at samp{@var{Arg1}}, @samp{@var{Arg2}}, @dots{} and @samp{@var{RetVal}}
+must be data-terms.
+
+The tuple to be inserted must have the same type signature as the relation
+being inserted into. All the arguments of the tuple (including the return value
+of a function) have mode @samp{in}, except the @samp{aditi__state} argument
which has mode @samp{unused}.
+ at item
+ at samp{@var{DB0}} and @samp{@var{DB}} must be data-terms of type
+ at samp{aditi__state}. They have mode @w{@samp{aditi_di, aditi_uo}}.
+ at end itemize
+
Note that @w{@samp{@var{PredName}(@var{Arg1}, @var{Arg2}, @dots{})}}
in an @samp{aditi_insert} goal is not a higher-order term.
@w{@samp{Pred = p(DB0, X, Y), aditi_insert(Pred, DB0, DB)}}
@@ -5556,6 +5701,37 @@
Delete all tuples for which @samp{@var{Goal}} or @samp{@var{Closure}}
succeeds from the named base relation.
+ at itemize @bullet
+ at item
+ at samp{@var{PredName}} must be the name of a predicate.
+
+ at item
+ at samp{@var{FuncName}} must be the name of a function.
+
+ at item
+ at samp{@var{Name}} must be the name of a predicate or a function.
+If it is a predicate, @samp{@var{PredOrFunc}} must be @samp{pred}.
+If it is a function, @samp{@var{PredOrFunc}} must be @samp{func}.
+
+ at item
+ at samp{@var{Arity}} must be the arity of the predicate or function
+being updated.
+
+ at item
+ at samp{@var{Arg1}}, @samp{@var{Arg2}}, @dots{} and @samp{@var{RetVal}}
+must be data-terms. The head of the deletion rule must have the same
+type signature as the relation being deleted from. The arguments
+(including the return value of a function) all have mode @samp{in},
+except for the @samp{aditi__state} argument, which has mode
+ at samp{unused} --- it is not possible to call an Aditi relation
+from the deletion goal.
+
+ at item
+ at samp{@var{Goal}} must be a Mercury goal.
+
+ at item
+ at samp{@var{Closure}} must be a data-term which has a higher-order type.
+
When deleting from a predicate with type declaration
@w{@samp{:- pred p(aditi__state, @var{Type1}, @dots{})}},
@samp{@var{Closure}} must have type
@@ -5577,10 +5753,15 @@
relation from the deletion condition. All other arguments of
@samp{@var{Closure}} must have mode @samp{in}.
-If the construction of the lambda expression is in the same conjunction
+If the construction of @samp{@var{Closure}} is in the same conjunction
as the @samp{aditi_delete} call, the compiler may be able to do a better
job of optimizing the deletion using indexes.
+ at item
+ at samp{@var{DB0}} and @samp{@var{DB}} must be data-terms of type
+ at samp{aditi__state}. They have mode @w{@samp{aditi_di, aditi_uo}}.
+ at end itemize
+
Examples:
@example
delete_example_1(DB0, DB) :-
@@ -5616,10 +5797,10 @@
Note that in @samp{delete_example_5} the extra set of parentheses around
the goal are needed, otherwise the second goal in the conjunction
in the deletion goal would be parsed as an extra argument of the
-`aditi_delete' call, resulting in a syntax error.
+ at samp{aditi_delete} call, resulting in a syntax error.
- at c @node Bulk insertion
- at subsubheading Bulk insertion
+ at c @node Bulk insertion and deletion
+ at subsubheading Bulk insertion and deletion
@example
aditi_bulk_insert(@var{PredOrFunc} @var{Name}/@var{Arity}, @var{Closure}, @var{DB0}, @var{DB}).
@@ -5627,18 +5808,49 @@
Insert all solutions of @samp{@var{Closure}} into the named relation.
- at samp{@var{Closure}} must have the same type signature as the base relation to
-be inserted into, with all arguments except the @samp{aditi__state} output.
-It must also be evaluable bottom-up by the Aditi system --- the predicate or
-function passed must have a @w{@samp{:- pragma aditi}} declaration.
-Lambda expressions can be marked as evaluable by Aditi using an
- at samp{aditi_bottom_up} annotation on the lambda expression.
+ at example
+aditi_bulk_delete(@var{PredOrFunc} @var{Name}/@var{Arity}, @var{Closure}, @var{DB0}, @var{DB}).
+ at end example
+
+Delete all solutions of @samp{@var{Closure}} from the named relation.
+
+ at itemize @bullet
+ at item
+ at samp{@var{Name}} must be the name of a predicate or a function.
+If it is a predicate, @samp{@var{PredOrFunc}} must be @samp{pred}.
+If it is a function, @samp{@var{PredOrFunc}} must be @samp{func}.
+
+ at item
+ at samp{@var{Arity}} must be the arity of the predicate or function
+being updated.
+
+ at item
+ at samp{@var{Closure}} must be a data-term which has a higher-order type with
+the same type signature as the base relation being updated.
+
+The @samp{aditi__state} argument of @samp{@var{Closure}} must have
+mode @samp{aditi_ui}. All other arguments must have mode @samp{out}.
+The determinism of @samp{@var{Closure}} must be @samp{nondet}.
+
+ at samp{@var{Closure}} must be evaluable bottom-up by the Aditi
+system --- the predicate or function passed must have a
+ at w{@samp{pragma aditi}} declaration. Lambda expressions can be
+marked as evaluable by Aditi using an @samp{aditi_bottom_up} annotation
+on the lambda expression.
+
+ at item
+ at samp{@var{DB0}} and @samp{@var{DB}} must be data-terms of type
+ at samp{aditi__state}. They have mode @w{@samp{aditi_di, aditi_uo}}.
+ at end itemize
Examples:
@example
bulk_insert_example_1(DB0, DB) :-
aditi_bulk_insert(pred p/3, ancestor, DB0, DB).
+bulk_delete_example_1(DB0, DB) :-
+ aditi_bulk_delete(pred p/3, ancestor, DB0, DB).
+
bulk_insert_example_2(DB0, DB) :-
InsertP = (aditi_bottom_up
pred(DB1::aditi_ui, X::out, Y::out) is nondet :-
@@ -5646,12 +5858,12 @@
),
aditi_bulk_insert(pred p/3, InsertP, DB0, DB).
-bulk_insert_example_3(DB0, DB) :-
- InsertQ = (aditi_bottom_up
+bulk_delete_example_2(DB0, DB) :-
+ DeleteQ = (aditi_bottom_up
func(DB1::aditi_ui, X::out) = (Y::out) is nondet :-
ancestor(DB1, X, Y)
),
- aditi_bulk_insert(pred p/3, InsertQ, DB0, DB).
+ aditi_bulk_insert(func f/2, DeleteQ, DB0, DB).
@end example
The type of @samp{InsertP} is
@@ -5659,18 +5871,6 @@
Its inst is @w{@samp{pred(aditi_ui, out, out) is nondet}},
as for a normal lambda expression.
- at c @node Bulk deletion
- at subsubheading Bulk deletion
-
- at example
-aditi_bulk_delete(@var{PredOrFunc} @var{Name}/@var{Arity}, @var{Closure}, @var{DB0}, @var{DB}).
- at end example
-
-Delete all solutions of @samp{@var{Closure}} from the named relation.
-
-The restrictions on the closure passed to @samp{aditi_bulk_insert} also
-apply to @samp{aditi_bulk_delete}.
-
@c @node Modification
@subsubheading Modification
@@ -5693,10 +5893,44 @@
@end example
-Modify tuples for which @samp{@var{Goal}} or @samp{@var{Closure}} succeeds.
-Tuples for which the modification goal fails are left unchanged.
-The original tuple is given by the first set of arguments, the
-updated tuple is given by the second set.
+Modify tuples for which @samp{@var{Goal}} or @samp{@var{Closure}} succeeds,
+leaving any other tuples unchanged.
+
+ at itemize @bullet
+ at item
+ at samp{@var{PredName}} must be the name of a predicate.
+
+ at item
+ at samp{@var{FuncName}} must be the name of a function.
+
+ at item
+ at samp{@var{Name}} must be the name of a predicate or a function.
+If it is a predicate, @samp{@var{PredOrFunc}} must be @samp{pred}.
+If it is a function, @samp{@var{PredOrFunc}} must be @samp{func}.
+
+ at item
+ at samp{@var{Arity}} must be the arity of the predicate or function
+being updated.
+
+ at item
+ at samp{@var{OldArg1}}, @samp{@var{OldArg2}}, @dots{}, @samp{@var{OldRetVal}},
+ at samp{@var{NewArg1}}, @samp{@var{NewArg2}}, @dots{}, and @samp{@var{NewRetVal}}
+must be data-terms.
+
+The original tuple is given by the first set of arguments, which
+have mode @samp{in}. The updated tuple is given by the second set
+of arguments, which have mode @samp{out}. The @samp{aditi__state}
+arguments for both tuples have mode @samp{unused} --- it is not possible
+to call an Aditi relation from the modification goal.
+
+The argument types of each tuple must match the argument types
+of the base relation being modified.
+
+ at item
+ at samp{@var{Goal}} must be a Mercury goal.
+
+ at item
+ at samp{@var{Closure}} must be a data-term which has a higher-order type.
When modifying a predicate with type declaration
@w{@samp{:- pred p(aditi__state, @var{Type1}, @dots{})}}, @samp{@var{Closure}}
@@ -5715,10 +5949,15 @@
mode @samp{unused} --- it is not possible to call an Aditi
relation from the modification goal.
-If the construction of the lambda expression is in the same conjunction
+If the construction of @samp{@var{Closure}} is in the same conjunction
as the @samp{aditi_modify} call, the compiler may be able to do a better
job of optimizing the modification using indexes.
+ at item
+ at samp{@var{DB0}} and @samp{@var{DB}} must be data-terms of type
+ at samp{aditi__state}. They have mode @w{@samp{aditi_di, aditi_uo}}.
+ at end itemize
+
Examples:
@example
modify_example_1(DB0, DB) :-
@@ -5757,7 +5996,7 @@
Note that in @samp{modify_example_5} the extra set of parentheses around
the goal are needed, otherwise the second and third goals in
the conjunction in the modification goal would be parsed as extra arguments
-of the `aditi_modify' call, resulting in a syntax error.
+of the @samp{aditi_modify} call, resulting in a syntax error.
@node Aditi glossary
@subsubsection Aditi glossary
--------------------------------------------------------------------------
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