This tutorial describes what you need to know to use LC++.
To declare a functor, use one of the FUNn
macros, where
n
is the arity of the functor. The macro arguments should
be the functor name followed by the argument types of the functor.
For example:
FUN2(parent,string,string) // parent() takes 2 strings FUN3(ancestor,string,string,int) // ancestor() takes 2 strings and an intBy convention, we name functors with an initial lowercase letter.
To declare a logic variable, use the DECLARE
macro. Its
arguments are the logic variable name, its type, and an integer unique
to that variable. For example:
DECLARE( X, int, 1 ); // X is a LogicVar<int> DECLARE( Str, string, 2 ); // Str is a LogicVar<string>By convention, we name logic variables with an initial capital letter.
The syntax of LC++ is designed to be similar to Prolog.
-= implication == unification && conjunction || disjunction not_provable() not provable LV.is(fun,args) computationWe'll see some examples of these below.
lassert()
.
For example:
lassert( parent( homer, bart ) ); lassert( ancestor( Par, Kid, 1 ) -= parent( Par, Kid ) );
To run a query, use the iquery()
or
lquery()
function. iquery
prints the
results, and lquery
returns them as a lazy list:
iquery( parent( Par, Kid ) ); // prints all answers typedef QRT::IE IE; List l = lquery( parent( homer, Kid ) ); while( !null(l) ) { IE env = head(l); // env->show(); // one way to print entire environment std::cout << "Kid is " << *env->at(Kid) << std::endl; l = tail(l); }
lquery()
deserves more explanation. It returns a list of
IRef
s (reference-counted pointers) to
Environment
objects. This type is named by the
QRT
type computer:
QRT<LV1_TYPE, ... LVn_TYPE>::IEis the type of result of a query involving the logic variables
LV1
thru LVn
. We use the FC++ list functions
to traverse the list. The environment object understands the messages
show()
(which prints the entire environment contents) and
at(SomeLV)
(which returns info about that logic variable's
binding).
See examples like family.cc for more info.