# Communicating with Databases in Natural Language - Wallace M.

**Download**(direct link)

**:**

**52**> 53 54 55 56 57 58 .. 59 >> Next

LIST place, custcode, place .ordercode

WHERE place custcode=‘Cl’ OR place,custcode=‘C2’

The list command clearly reflects the meaning of the D&Qs formula. It shows how the disjunctive interpretation of ‘C1’&‘C2’ (or in general ‘Descl & Desc2’) works in the conversion of D&Qs to simplified list commands

3 THE PROLOG PROGRAM

Two of the predicates used in this program are not actually defined They are ‘writeout’ and ‘error’

?- op(700, xfy, or)

?- op(600, xfy, & ),

?- op(500, xfy, not),

?- op(700, xfy, ‘,’)

3]

A PROLOG PROGRAM FOR CONVERTING D&Qs 145

/* ‘not not . ’ undoes all the variable bindings that result from the conversion /* process. The predicate ‘used’ is a kind of ‘blackboard’ for recording which /* relations have been used in the query. */ convert(DandQs) not not conv(DandQs),!,ietractall(used(_)). convert(DandQs): -

error (‘Formula could not be converted’, DandQs), retractall(used( _)).

/* Displays the final list command. */ conv(DandQs) convqual(DandQs, Results, Rules), write(‘LIST’), writeout(Results), write (‘WHERE’), writeout(Rules),nl

I* Clause as described in Chapter 4, section 3,2.3 except that this version rejects /* logical combinations of DESCRIPTIONS and adds a final check that the /* variable is bound. */

convqual (Desc is qual(V, Qual), Results, Rule): —

not (Desc = (D1 or D2)), not (Desc = (D1 & D2)),!,

convqual (Qual, Resl, Rulel),

convdesc(Desc, W, Res2, Rule2),

substitute(V, W, Rule.3),

union(Resl, Res2, Results),

conjunct([Rulel, Rule2, Rule.3], Rule),

check (V, Desc is qual(V, Qual) ).

convqual (Quail & Qual2, Results, Rule) :-convqual (Quail, Resl, Rulel), convqual(Qual2, Res2, Rule2), union(Resl, Res2, Results), conjunct ([Rulel, Rule2], Rule)

/* We could define a predicate ‘disjunct’, similar to ‘conjunct’, which would /* simplify ‘Rule or false’ to ‘Rule’.. */

convqual (Quail or Qual2, Results, Rulel or Rule2) : — convqual (Quail, Resl, Rulel), convqual(Qual2, Res2, Rule2), union (Resl, Res2, Results)

convqual (not Quail, Results, not Rule ) : — convqual (Quail, Results, Rule),

convqual (true, [ ], true) :—! convqual (fail, [], false) :—!

146 A PROLOG PROGRAM FOR CONVERTING D&Qs

[Appendix

/* Converts simple QUALIFIERS as described in Chapter 4, section 3.2.2 */

convqual (Qual, [], Rule) : —

Qual= . , [Rel i Atts],

relation (Rel),!, convrel (Rel, Atts, Rule).

/* Converts built-in functions such as ‘total’, ‘average’, ‘max’ and ‘min’. */ convqual (Qual, [],true) : —

Qual=. . [Rel | Atts],

built_in(Rel),!, convfunct (Rel, Atts).

convqual (Qual, _)

functor (Qual, Rel, _), Rel\= is,!, error (‘unrecognised relation name’, Rel).

check(V,_) nonvar (V),!. check (V, Qualifier) : —

error (‘No constraints on variable’, Qualifier)

/* As in Chapter 4, section 3.2.2 */

convrel (Rel, [Att = Rel. Att | Selections], Rule) : —

!,convrel (Rel, Selections, Rule)

/* An extension to Chapter 4, section .3,2.2 to deal with ‘>’, ‘<’ etc */ convrel(Rel, [Selection I Sel], Rule) : —

Selection= [Comp, Att, Arg],

Rulel=. [Comp, Rel.Att, Arg], convrel (Rel, Sel, Rule2), conjunct([Rulel,Rule2], Rule)

/* Rejects queries like “What costs more than pencils?”. Without this clause this /* query would yield

/* “LIST PRODUCT WHERE PRODUCT.UNIT-PRICE >

/* PRODUCT.UNIT-PRICE AND

/* PRODUCT.PRODUCTDESC = ‘pencils’ ”. */

convrel(Rel, [ ],_) : —

used (Rel),!, error (‘relation used twice’, Rel).

convrel (Rel, [ ], true) : — assert (used (Rel))

convrel(Rel, _,_):— not (retract (used (Rel)))

/* The QUALIFIER ‘total(result=X, arguments=Y)’ would result in the binding /* of ‘X’ to ‘total (Y)’. */

convfunct(Funct, [result = X, arguments = Y]) : —

X= . [Funct,Y], !

3]

A PROLOG PROGRAM FOR CONVERTING D&Qs 147

/* If ‘X’ is not itself a variable, the converter gives up. It should only work if ‘X’ /* ultimately ends up in the result spec. */ convfunct(Funct,_) : —

error (‘embedded function’, Funct)

/* Chapter 4, section .3,2.3 */ convdesc(Const, Const, [ ], true): — atomic(Const),!,

/* Already converted. */

convdesc (Rel, Att, Rei.Att, [ ], true):— !.

/* Rejects “Who placed 2 pencils, */ convdesc(Det-N-qual (V, Qual),_,_,_) : — nonvar(N), N>1, !,

enor (‘embedded count’, Det-N-qual(V, Qual)),

/* Chapter 4, section .3.2.5 */

convdesc(what-N-qual (V, Qual), W, [V | Results], Rule): — convdesc (any-N-qual(V, Qual), W, Results, Rule).

I* Chapter 4, section .3.2.4 */ convdesc (Det-N-qual (V, Qual), V, Results, Rule) : — convqual(Qual, Results, Rule).

/* This works because, under the constraints specified in 2.1 above,

/ * ‘(Dl is funct(V, D2)) is qual(W, Qual)’

/* has the same semantics as

/* ‘Dl is qual (V, D2 is qual(W, Qual))’,, */

convdesc (Dl is funct(V, D2), W, Results, Rule) : —

convqual (Dl is qual (V, D2 is qual (W, true)),

Results,

Rule).

/* Chapter 4, section 3.2..3 */ substitute (X, X, true): —! substitute (X,Y,X=Y),

/* Messy Bits */

/* See 2.3, above, */

convqual ((Dl & D2) is qual(V, Qual), Results, Rule) : —

convqual ((Dl or D2) is qual (V, Qual), Results, Rule),

**52**> 53 54 55 56 57 58 .. 59 >> Next