DyALog tries to comply with the standard syntax of Prolog, with extensions to handle hilog terms and typed features terms. On the contrary, the DyALog reader may miss some obscure points of the standard.
A standard term is either a simple term (an integer, a character, a
symbol or a variable as defined in most Prolog) or a term
f(t1,...,tN)
where ti is a term. Note that
floats are not yet implemented and that chars are not implemented as a
subset of integers (but as a proper type).
DyALog performs immediate unification at reading time when encountering
infix operator ::/2
. Immediate unification is generally used to
assign in a single step a variable for a whole structure and variables
for its sub-structures.
For example:
p(X::f(Y,Z)) :- check(Y),check(Z),q(X).
is a shortcut for
p(f(Y,Z)) :- check(Y),check(Z),q(f(Y,Z)).
Mutiple immediate unification may take place at the same time, which is sometimes usefull in conjonction with feature terms.
Infix, prefix or postfix operators with precedence are allowed in DyALog
and are just syntactic sugar for standard Prolog term. For instance
t+q
is equivalent to +(t,q)
.
The declaration of new operators is possible through the usual directive
op/3
.
It is possible to associate to a symbol (say employee
) a list of
features (say [name,job,salary]
). When building a term based on
employee
, it is not necessary to assign explicitely and in order
a value for all its features because the missing values will be filled
by new anonymous variables. For instance, the feature term
employee{salary=>6000,name=>john}
is equivalent to the term
employee(john,_,5000)
. Note the use of enclosing {} instead
of enclosing () to mark feature terms.
To associate a feature table to a symbol, use the directive
features/2
.
:-features(employee,[name,job,salary]).
It is also possible to use Typed Feature Structure, following the same syntax.
DyALog provides Enumeration Variables, i.e. variables that may take
their values from some defined enumeration. For instance, the term
X::tense[present,past]
denotes a variable X
with value in
the sub-enumeration [present,past]
of some user-defined
enumeration tense
. Note the use of enclosing [] instead
of enclosing ().
To associate an enumeration to a symbole, use the directive
finite_set/2
.
:-finite_set(tense,[present,past,futur]).
It is also possible to define sub-enumeration using the directive
subset/2
:-finite_set(letter,[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p, q,r,s,t,u,v,w,x,y,z ]). :-subset(voyel,letter[a,e,i,o,u,y])
Enumeration are restricted to at most 30 elements. These elements should be ground objects. Enumeration variable may be unified with variables, enumeration variables based on the same enumeration and with elements of their enumeration.
Hilog terms are an extension found in some Prolog evaluators (XSB among others) that gives a flavor of (pseudo) higher order very practical to build meta-predicates or closures.
The key idea is to consider that a sequence t
(t1,..,tN)
(with a SPC between the terms) is
equivalent to apply(t,t1,...,tN)
.
The middle space can be removed when there is no ambiguity, for instance when t is an integer, a char, a variable, a compound term or a symbol declared as being hilog.
In case of ambiguity between an operator-based expression or an hilog
expression, the operator-based expression will be chosen. For instance,
- (a+b)
represents the term -(a+b)
and not
apply(-,a+b)
.
One can force the hilog interpretation of a symbol by using the
directive hilog/1
.
The following program illustrate the use of hilog terms to build meta-predicates.
closure(R)(X,Y) :- R(X,Y). closure(R)(X,Y) :- R(X,Z),closure(R)(Z,Y). :-hilog(r). r(a,b). r(b,c).
A clause of a Definite Clause Grammar is introduced with the binary
predicate -->/2
and closed by a dot. Lists in position of
predicates in the clause denote terminals to be scanned. Scanning is
done either from a Prolog list or from a token database (implementing a
Finite State Automata).
The following program implements reverse with a Definite Clause Grammar.
reverse(X,Y) :- phrase(rev(Y),X,[]). rev([]) --> []. rev([X|Y]) --> rev(Y),[X].
Directive clauses are conjunctions of directives introduced par the
unary predicate :-/1
and close by a dot mark.
:-include('foo.pl'),op(300,xfx,[hello]).
Go to the first, previous, next, last section, table of contents.