[m-dev.] for review: Aditi update doc extract

Simon Taylor stayl at cs.mu.OZ.AU
Fri Jul 2 17:04:54 AEST 1999


Hi,

As Fergus suggested, this is the part of mercury_ref.info relating
to Aditi updates.

David Overton, could you please take a look at this.

Thanks,
Simon.


File: mercury_ref.info,  Node: Aditi update syntax,  Next: Aditi glossary,  Prev: Aditi pragma declarations,  Up: Aditi deductive database interface

Aditi update syntax
...................

   The Melbourne Mercury compiler provides special syntax to specify
updates of Aditi base relations.

   Note: Only error checking is implemented for Aditi updates -- no
code is generated yet.

Aditi update notes
..................

   There must be a `:- pragma base_relation' declaration for any
relation to be updated.

   It is currently up to the application to ensure that any
modifications do not change 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 examples make use of the following declarations.
     :- pred p(aditi__state::aditi_ui, int::out, int::out) is nondet.
     :- pragma base_relation(p/3).
     
     :- func f(aditi__state::aditi_ui, int::out) = (int::out) is nondet.
     :- pragma base_relation(f/2).
     
     :- pred ancestor(aditi__state::aditi_ui, int::out, int::out) is nondet.
     :- pragma aditi(ancestor/3).

   Variables named `DBN' are `aditi__state' variables. When occuring as
a pair at the end of an argument list, they have mode
`aditi_di, aditi_uo'.

   Predicate and function names in Aditi update goals may be module
qualified.

Insertion
.........

     aditi_insert(PREDNAME(VAR1, VAR2, ...), DB0, DB).
     
     aditi_insert(FUNCNAME(VAR1, VAR2, ...) = RETVAR, DB0, DB).

   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 `in', except the `aditi__state' argument which has
mode `unused'.

   Note that `PREDNAME(VAR1, VAR2, ...)' in a call to `aditi_insert' is
not a higher-order term.
`Pred = p(DB0, X, Y), aditi_insert(Pred, DB0, DB)' is a syntax error.

   Examples:
     insert_example_1(DB0, DB) :-
             aditi_insert(p(_, 1, 2), DB0, DB).
     
     insert_example_2(DB0, DB) :-
             aditi_insert(f(_, 1) = 2, DB0, DB).

Deletion
........

     aditi_delete((PREDNAME(VAR1, VAR2, ...) :- GOAL), DB0, DB).
     
     aditi_delete((FUNCNAME(VAR1, VAR2, ...) = RETVAR :- GOAL), DB0, DB).
     
     aditi_delete(PREDORFUNC NAME/ARITY, CLOSURE, DB0, DB).

   Delete all tuples for which `GOAL' or `CLOSURE' succeeds from the
named base relation.

   For the third alternative `PREDORFUNC' must be either `pred' or
`func'.

   When deleting from a predicate with type declaration
`:- pred p(aditi__state, TYPE1, ...)', `CLOSURE' must have type
`aditi_top_down pred(aditi__state, TYPE1, ...)', and inst
`pred(unused, in, ...) is semidet'.

   When deleting from a function with type declaration
`:- func p(aditi__state, TYPE1, ...) = TYPE2', `CLOSURE' must have type
`aditi_top_down func(aditi__state, TYPE1, ...) = TYPE2', and inst
`func(unused, in, ...) = in is semidet'.

   The `aditi_top_down' annotation on the lambda expression is needed to
tell the compiler to generate code for execution by the Aditi database
using the normal Mercury execution algorithm.

   The `aditi__state' argument of `CLOSURE' must have mode `unused' --
it is not possible to call an Aditi relation from the deletion
condition. All other arguments of `CLOSURE' must have mode `in'.

   If the construction of the lambda expression is in the same
conjunction as the `aditi_delete' call, the compiler may be able to do
a better job of optimizing the deletion using indexes.

   Examples:
     delete_example_1(DB0, DB) :-
             aditi_delete((p(_, X, Y) :- X + Y = 2), DB0, DB).
     
     delete_example_2(DB0, DB) :-
             aditi_delete(f(_, 2) = _Y, DB0, DB).
     
     delete_example_3(DB0, DB) :-
             DeleteP = (aditi_top_down
                    pred(_::unused, X::in, Y::in) is semidet :-
                             X = 2
                    ),
             aditi_delete(pred p/3, DeleteP, DB0, DB).
     
     delete_example_4(DB0, DB) :-
             DeleteQ = (aditi_top_down
                    func(_::unused, X::in) = (Y::in) is semidet :-
                             X = 2
                    ),
             aditi_delete(func f/2, DeleteQ, DB0, DB).
     
     delete_example_5 -->
     	aditi_delete((p(_, X, Y) :- X = 2, Y = 2)).

   The type of `DeleteP' is
`aditi_top_down pred(aditi__state, int, int)'.  Its inst is
`pred(unused, in, in) is nondet', as for a normal lambda expression.

   Note that in `delete_example_5' the extra set of parentheses around
the goal are needed, otherwise the second goal in the conjunction in
the deletion goal is parsed as an argument of the `aditi_delete' call.
This behaviour is inconsistent with ISO Prolog syntax. An ISO Prolog
implementation would report a syntax error without the extra set of
parentheses.

Bulk insertion
..............

     aditi_bulk_insert(PREDORFUNC NAME/ARITY, CLOSURE, DB0, DB).

   Insert all solutions of `CLOSURE' into the named relation.
`PREDORFUNC' must be either `pred' or `func'.

   The closure for producing the tuples to insert must have the same
type signature as the base relation, with all arguments except the
`aditi__state' output. It must also be evaluable bottom-up by the Aditi
system. This means the predicate passed must have a
`:- pragma aditi(...)' declaration. Lambda expressions can be marked as
evaluable by Aditi using an `aditi_bottom_up' annotation on the lambda
expression.

   Examples:
     bulk_insert_example_1(DB0, DB) :-
             aditi_bulk_insert(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 :-
                             ancestor(DB1, X, Y)
                     ),
             aditi_bulk_insert(pred p/3, InsertP, DB0, DB).
     
     bulk_insert_example_3(DB0, DB) :-
             InsertQ = (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).

   The type of `InsertP' is
`aditi_bottom_up pred(aditi__state, int, int)'.  Its inst is
`pred(aditi_ui, out, out) is nondet', as for a normal lambda expression.

Bulk deletion
.............

     aditi_bulk_delete(PREDORFUNC NAME/ARITY, CLOSURE, DB0, DB).

   Delete all solutions of `CLOSURE' from the named relation.
`PREDORFUNC' must be either `pred' or `func'.

   The restrictions on the closure passed to `aditi_bulk_insert' also
apply to `aditi_bulk_delete'.

Modification
............

     aditi_modify(
             (PREDNAME(VAR1, VAR2, ...) ==> PREDNAME(VAR3, VAR4, ...) :-
                     GOAL
             ),
             DB0, DB).
     
     aditi_modify(
             ((FUNCNAME(VAR1, VAR2, ...) = RETVAR0) ==>
             (PREDNAME(VAR3, VAR4, ...) = RETVAR) :-
                     GOAL
             ),
             DB0, DB).
     
     aditi_modify(PREDORFUNC PREDNAME/ARITY, CLOSURE, DB0, DB).

   Modify tuples for which `GOAL' or `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.

   For the third alternative `PREDORFUNC' must be either `pred' or
`func'.

   When modifying a predicate with type declaration
`:- pred p(aditi__state, TYPE1, ...)', `CLOSURE' must have type
`aditi_top_down pred(aditi__state, TYPE1, ..., aditi__state, TYPE1,
...)', and inst `pred(unused, in, ..., unused, out, ...) is semidet'.

   When modifying a function with type declaration
`:- func p(aditi__state, TYPE1, ...) = TYPE2', `CLOSURE' must have type
`aditi_top_down pred(aditi__state, TYPE1, ..., TYPE2, aditi__state,
TYPE1, ..., TYPE2)', and inst
`pred(unused, in, ..., in, unused, out, ..., out) is semidet'.

   The `aditi__state' arguments of `CLOSURE' must have mode `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 as the `aditi_modify' call, the compiler may be able to do
a better job of optimizing the modification using indexes.

   Examples:
     modify_example_1(DB0, DB) :-
             aditi_modify(
                     (p(_DB0, X, Y0) ==> p(_DB, X, Y) :-
                             X > 2, X < 5, Y = Y0 + 1
                     ), DB0, DB).
     
     modify_example_2(DB0, DB) :-
             aditi_modify(
                     ((f(_DB0, X) = Y0) ==> (f(_DB, X) = Y) :-
                             X > 2, X < 5, Y = Y0 + 1
                     ), DB0, DB).
     
     modify_example_3(DB0, DB) :-
             ModifyP = (aditi_top_down pred(_::unused, X::in, Y0::in,
                             _::unused, X::out, Y::out) is semidet :-
                         X > 2, X < 5, Y = Y0 + 1
                      ),
             aditi_modify(pred p/3, ModifyP, DB0, DB).
     
     modify_example_4(DB0, DB) :-
             ModifyQ = (aditi_top_down pred(_::unused, X::in, Y0::in,
                             _::unused, X::out, Y::out) is semidet :-
                         X > 2, X < 5, Y = Y0 + 1
                      ),
             aditi_modify(func f/2, ModifyQ, DB0, DB).
     
     modify_example_5 -->
             aditi_modify(
                     (p(_DB0, X, Y0) ==> p(_DB, X, Y) :-
                             X > 2, X < 5, Y = Y0 + 1
                     )).

   Note that in `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 are parsed as arguments of the
`aditi_modify' call. This behaviour is inconsistent with ISO Prolog
syntax. An ISO Prolog implementation would report a syntax error
without the extra set of parentheses.


File: mercury_ref.info,  Node: Aditi glossary,  Prev: Aditi update syntax,  Up: Aditi deductive database interface

--------------------------------------------------------------------------
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