2014-04-28 11:47:09 +01:00
# define YAP_CPP_INTERFACE 1
2014-05-04 22:31:22 +01:00
/**
*
* @ defgroup yap - cplus - interface An object oriented interface for YAP .
*
*
* @ tableofcontents
*
*
* C + + interface to YAP . Designed to be object oriented and to fit naturally
* with the swig interface language generator . It uses ideas from the old YAP
* interface and from the SWI foreign language interface .
*
2014-06-11 19:27:54 +01:00
* @ {
*
2014-05-04 22:31:22 +01:00
*/
2014-04-28 11:47:09 +01:00
# include <stdlib.h>
2014-05-04 22:31:22 +01:00
# include <config.h>
2014-06-11 19:27:54 +01:00
extern " C " {
2014-06-12 01:48:36 +01:00
# include <stddef.h>
2014-06-12 11:03:35 +01:00
# ifdef __cplusplus
2014-06-11 19:27:54 +01:00
# define old_cplusplus __cplusplus
# undef __cplusplus
2014-06-12 01:48:36 +01:00
# endif
2014-05-04 22:31:22 +01:00
# if USE_GMP
2014-04-28 11:47:09 +01:00
# include <gmp.h>
2014-05-04 22:31:22 +01:00
# endif
2014-06-12 01:48:36 +01:00
# ifdef old_cplusplus
2014-06-11 19:27:54 +01:00
# define __cplusplus old_cplusplus
# undef old_cplusplus
# endif
2014-04-28 11:47:09 +01:00
# include "Yap.h"
# include "Yatom.h"
# include "YapHeap.h"
# include "pl-shared.h"
# include "clause.h"
# include "yapio.h"
# include "Foreign.h"
# include "attvar.h"
# include "SWI-Stream.h"
# include "YapText.h"
# if HAVE_STDARG_H
# include <stdarg.h>
# endif
# if HAVE_STDINT_H
# include <stdint.h>
# endif
# if HAVE_STRING_H
# include <string.h>
# endif
# if _MSC_VER || defined(__MINGW32__)
# include <windows.h>
# endif
2014-06-11 19:27:54 +01:00
// taken from yap_structs.h
2014-04-28 11:47:09 +01:00
# include "iopreds.h"
2014-06-11 19:27:54 +01:00
extern Term Yap_StringToTerm ( const char * s , size_t len , term_t bindings ) ;
2014-06-04 22:08:37 +01:00
2014-06-11 19:27:54 +01:00
// we cannot consult YapInterface.h, that conflicts with what we declare, though
// it shouldn't
2014-04-28 11:47:09 +01:00
}
2014-05-04 22:31:22 +01:00
//#include <vector>
2014-06-11 19:27:54 +01:00
2014-05-04 22:31:22 +01:00
class YAPEngine ;
2014-04-28 11:47:09 +01:00
class YAPAtom ;
class YAPFunctor ;
2014-06-04 22:08:37 +01:00
class YAPApplTerm ;
class YAPPairTerm ;
2014-04-28 11:47:09 +01:00
class YAPQuery ;
2014-06-11 19:27:54 +01:00
class TypeError { } ;
2014-05-04 22:31:22 +01:00
/**
* @ brief Generic Prolog Term
*/
2014-04-28 11:47:09 +01:00
class YAPTerm {
2014-06-11 19:27:54 +01:00
friend class YAPPredicate ;
friend class YAPApplTerm ;
friend class YAPPairTerm ;
friend class YAPListTerm ;
2014-04-28 11:47:09 +01:00
protected :
2014-06-16 14:41:54 +01:00
yhandle_t t ;
2014-06-11 19:27:54 +01:00
void mk ( Term t0 ) ;
Term gt ( ) ;
YAPTerm ( Term tn ) { mk ( tn ) ; }
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
YAPTerm ( ) { mk ( TermNil ) ; } // do nothing constructor
YAPTerm ( intptr_t i ) ;
YAPTerm ( void * ptr ) ;
YAPTerm ( char * s ) { Term tp ; mk ( YAP_ReadBuffer ( s , & tp ) ) ; }
/*~YAPTerm(void) {
2014-06-04 22:08:37 +01:00
CACHE_REGS
Yap_RecoverSlots ( 1 , t PASS_REGS ) ;
} */
2014-06-11 19:27:54 +01:00
Term term ( ) { return gt ( ) ; }
YAP_tag_t tag ( ) ;
YAPTerm deepCopy ( ) ;
//const YAPTerm *vars();
bool exactlyEqual ( YAPTerm t1 ) ;
bool unify ( YAPTerm t1 ) ;
bool unifiable ( YAPTerm t1 ) ;
bool variant ( YAPTerm t1 ) ;
intptr_t hash ( size_t sz , size_t depth , bool variant ) ;
bool isVar ( ) { return IsVarTerm ( gt ( ) ) ; }
bool isAtom ( ) { return IsAtomTerm ( gt ( ) ) ; }
bool isInteger ( ) { return IsIntegerTerm ( gt ( ) ) ; }
bool isFloat ( ) { return IsFloatTerm ( gt ( ) ) ; }
bool isCompound ( ) { return ! ( IsVarTerm ( gt ( ) ) | | IsNumTerm ( gt ( ) ) ) ; }
bool isAppl ( ) { return IsApplTerm ( gt ( ) ) ; }
bool isPair ( ) { return IsPairTerm ( gt ( ) ) ; }
bool isGround ( ) { return Yap_IsGroundTerm ( gt ( ) ) ; }
bool isList ( ) { return Yap_IsListTerm ( gt ( ) ) ; }
bool isString ( ) { return IsStringTerm ( gt ( ) ) ; }
inline YAPTerm getArg ( int i ) {
Term t0 = gt ( ) ;
if ( IsApplTerm ( t0 ) )
return YAPTerm ( ArgOfTerm ( i , t0 ) ) ;
else if ( IsPairTerm ( t0 ) ) {
if ( i = = 1 )
return YAPTerm ( HeadOfTerm ( t0 ) ) ;
if ( i = = 2 )
return YAPTerm ( TailOfTerm ( t0 ) ) ;
}
return YAPTerm ( ( Term ) 0 ) ;
}
char * text ( ) ;
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
* @ brief Variable Term
*/
2014-06-11 19:27:54 +01:00
class YAPVarTerm : public YAPTerm {
YAPVarTerm ( Term t ) { if ( IsVarTerm ( t ) ) mk ( t ) ; }
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
YAPVarTerm ( ) ;
CELL * getVar ( ) { return VarOfTerm ( gt ( ) ) ; }
bool unbound ( ) { return IsUnboundVar ( VarOfTerm ( gt ( ) ) ) ; }
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
* @ brief Compound Term
*/
2014-06-11 19:27:54 +01:00
class YAPApplTerm : public YAPTerm {
2014-06-04 22:08:37 +01:00
friend class YAPTerm ;
YAPApplTerm ( Term t0 ) { mk ( t0 ) ; }
2014-04-28 11:47:09 +01:00
public :
2014-06-04 22:08:37 +01:00
YAPApplTerm ( YAPTerm t0 ) { mk ( t0 . term ( ) ) ; }
2014-06-11 19:27:54 +01:00
YAPApplTerm ( YAPFunctor f , YAPTerm ts [ ] ) ;
YAPApplTerm ( YAPFunctor f ) ;
YAPFunctor getFunctor ( ) ;
YAPTerm getArg ( int i ) ;
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
* @ brief List Constructor Term
*/
2014-06-11 19:27:54 +01:00
class YAPPairTerm : public YAPTerm {
2014-06-04 22:08:37 +01:00
friend class YAPTerm ;
2014-06-11 19:27:54 +01:00
YAPPairTerm ( Term t0 ) { if ( IsPairTerm ( t0 ) ) mk ( t0 ) ; else mk ( 0 ) ; }
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
YAPPairTerm ( YAPTerm hd , YAPTerm tl ) ;
YAPPairTerm ( ) ;
YAPTerm getHead ( ) { return YAPTerm ( HeadOfTerm ( gt ( ) ) ) ; }
YAPTerm getTail ( ) { return YAPTerm ( TailOfTerm ( gt ( ) ) ) ; }
2014-05-04 22:31:22 +01:00
} ;
/**
* @ brief Integer Term
*/
2014-06-11 19:27:54 +01:00
class YAPIntegerTerm : public YAPTerm {
2014-05-04 22:31:22 +01:00
public :
2014-06-11 19:27:54 +01:00
YAPIntegerTerm ( intptr_t i ) ;
intptr_t getInteger ( ) { return IntegerOfTerm ( gt ( ) ) ; }
bool isTagged ( ) { return IsIntTerm ( gt ( ) ) ; }
2014-05-04 22:31:22 +01:00
} ;
2014-06-11 19:27:54 +01:00
class YAPListTerm : public YAPTerm {
2014-05-04 22:31:22 +01:00
public :
2014-06-04 22:08:37 +01:00
/// Create a list term out of a standard term. Check if a valid operation.
///
2014-06-11 19:27:54 +01:00
/// @param[in] the term
YAPListTerm ( Term t0 ) { mk ( t0 ) ; /* else type_error */ }
/* /// Create a list term out of an array of terms.
2014-06-04 22:08:37 +01:00
///
/// @param[in] the array of terms
/// @param[in] the length of the array
2014-06-11 19:27:54 +01:00
YAPListTerm ( YAPTerm ts [ ] , size_t n ) ;
*/
// YAPListTerm( vector<YAPTerm> v );
2014-06-04 22:08:37 +01:00
/// Return the number of elements in a list term.
size_t length ( ) { Term * tailp ; Term t1 = gt ( ) ; return Yap_SkipList ( & t1 , & tailp ) ; }
2014-06-11 19:27:54 +01:00
/// Extract the first element of a list.
///
/// @param[in] the list
YAPTerm car ( ) ;
/// Extract the tail elements of a list.
///
/// @param[in] the list
YAPListTerm cdr ( )
{
Term to = gt ( ) ;
if ( IsPairTerm ( to ) )
return YAPListTerm ( TailOfTerm ( to ) ) ;
else
return MkIntTerm ( - 1 ) ;
}
/// Check if the list is empty.
///
/// @param[in] the list
bool nil ( ) ;
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
* @ brief Atom
*/
2014-04-28 11:47:09 +01:00
class YAPAtom {
2014-06-11 19:27:54 +01:00
friend class YAPPredicate ;
friend class YAPFunctor ;
friend class YAPAtomTerm ;
Atom a ;
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
YAPAtom ( Atom at ) { a = at ; }
YAPAtom ( char * s ) { a = Yap_LookupAtom ( s ) ; }
YAPAtom ( wchar_t * s ) { a = Yap_LookupMaybeWideAtom ( s ) ; }
YAPAtom ( char * s , size_t len ) { a = Yap_LookupAtomWithLength ( s , len ) ; }
YAPAtom ( wchar_t * s , size_t len ) { a = Yap_LookupMaybeWideAtomWithLength ( s , len ) ; }
char * name ( void ) ;
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
* @ brief String Term
*/
2014-06-11 19:27:54 +01:00
class YAPStringTerm : public YAPTerm {
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
YAPStringTerm ( char * s ) ;
YAPStringTerm ( char * s , size_t len ) ;
YAPStringTerm ( wchar_t * s ) ;
YAPStringTerm ( wchar_t * s , size_t len ) ;
const char * getString ( ) { return StringOfTerm ( gt ( ) ) ; }
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
* @ brief Atom Term
*/
2014-06-11 19:27:54 +01:00
class YAPAtomTerm : public YAPTerm {
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
YAPAtomTerm ( YAPAtom a ) : YAPTerm ( ) { mk ( MkAtomTerm ( a . a ) ) ; }
YAPAtomTerm ( Atom a ) : YAPTerm ( ) { mk ( MkAtomTerm ( a ) ) ; }
YAPAtomTerm ( char * s ) ;
YAPAtomTerm ( char * s , size_t len ) ;
YAPAtomTerm ( wchar_t * s ) ;
YAPAtomTerm ( wchar_t * s , size_t len ) ;
YAPAtom getAtom ( ) { return YAPAtom ( AtomOfTerm ( gt ( ) ) ) ; }
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
2014-06-11 19:27:54 +01:00
* @ brief YAPFunctor represents Prolog functors Name / Arity
2014-05-04 22:31:22 +01:00
*/
2014-04-28 11:47:09 +01:00
class YAPFunctor {
2014-06-11 19:27:54 +01:00
friend class YAPApplTerm ;
friend class YAPPredicate ;
Functor f ;
/// Constructor: receives Prolog functor and casts it to YAPFunctor
///
/// Notice that this is designed for internal use only.
YAPFunctor ( Functor ff ) { f = ff ; }
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
/// Constructor: receives name as a string plus arity
///
/// Notice that this is designed for ISO-LATIN-1 right now
YAPFunctor ( char * s , arity_t arity ) { f = Yap_MkFunctor ( Yap_LookupAtom ( s ) , arity ) ; }
/// Constructor: receives name as a wide string plus arity
///
/// Notice that this is designed for UNICODE right now
YAPFunctor ( wchar_t * s , arity_t arity ) { f = Yap_MkFunctor ( Yap_LookupWideAtom ( s ) , arity ) ; }
/// Constructor: receives name as an atom, plus arity
///
/// This is the default method, and the most popi;at
YAPFunctor ( YAPAtom at , arity_t arity ) { f = Yap_MkFunctor ( at . a , arity ) ; }
2014-04-28 11:47:09 +01:00
2014-06-11 19:27:54 +01:00
/// Getter: extract name of functor as an atom
///
/// this is for external usage.
YAPAtom name ( void ) {
return YAPAtom ( NameOfFunctor ( f ) ) ;
}
2014-05-04 22:31:22 +01:00
2014-06-11 19:27:54 +01:00
/// Getter: extract arity of functor as an unsigned integer
///
/// this is for external usage.
arity_t arity ( void ) {
return ArityOfFunctor ( f ) ;
}
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
2014-06-11 19:27:54 +01:00
* @ brief Predicates
*
* This class interfaces with PredEntry in Yatom . g
2014-05-04 22:31:22 +01:00
*/
2014-04-28 11:47:09 +01:00
class YAPPredicate {
2014-06-11 19:27:54 +01:00
friend class YAPQuery ;
private :
PredEntry * ap ;
/// auxiliary routine to find a predicate in the current module.
PredEntry * getPred ( Term t , Term * * outp ) ;
/// String constructor for predicates
///
/// It also communicates the array of arguments t[] abd the array of variables
/// back to yapquery
2014-06-16 14:41:54 +01:00
YAPPredicate ( const char * s , Term * * outp , yhandle_t & vnames ) ;
2014-06-11 19:27:54 +01:00
/// Term constructor for predicates
///
/// It is just a call to getPred
inline YAPPredicate ( Term t ) {
2014-06-12 01:25:50 +01:00
ap = getPred ( t , ( Term * * ) NULL ) ;
2014-06-11 19:27:54 +01:00
}
/// Cast constructor for predicates,
/// if we have the implementation data.
///
inline YAPPredicate ( PredEntry * pe ) {
ap = pe ;
}
2014-06-04 22:08:37 +01:00
public :
2014-06-11 19:27:54 +01:00
/// Functor constructor for predicates
///
/// Asssumes that we use the current module.
YAPPredicate ( YAPFunctor f ) ;
/// Functor constructor for predicates, is given a specific module.
///
inline YAPPredicate ( YAPFunctor f , YAPTerm mod ) {
ap = RepPredProp ( PredPropByFunc ( f . f , mod . t ) ) ;
}
/// Name/arity constructor for predicates.
///
inline YAPPredicate ( YAPAtom at , YAPTerm mod ) {
ap = RepPredProp ( PredPropByAtom ( at . a , mod . t ) ) ;
}
/// Name/0 constructor for predicates.
///
YAPPredicate ( YAPAtom at ) ;
/// Mod:Name/Arity constructor for predicates.
///
inline YAPPredicate ( YAPAtom at , arity_t arity , YAPTerm mod ) {
if ( arity ) {
Functor f = Yap_MkFunctor ( at . a , arity ) ;
ap = RepPredProp ( PredPropByFunc ( f , mod . t ) ) ;
} else {
ap = RepPredProp ( PredPropByAtom ( at . a , mod . t ) ) ;
}
}
/// Atom/Arity constructor for predicates.
///
YAPPredicate ( YAPAtom at , arity_t arity ) ;
/// String constructor for predicates.
///
/// String is a Prolog term, we extract the main functor after considering the module qualifiers.
inline YAPPredicate ( char * s ) {
Term t , tp ;
t = YAP_ReadBuffer ( s , & tp ) ;
2014-06-12 01:25:50 +01:00
ap = getPred ( t , ( Term * * ) NULL ) ;
2014-06-11 19:27:54 +01:00
}
/// String constructor for predicates, also keeps arguments in tp[]
///
/// String is a Prolog term, we extract the main functor after considering the module qualifiers.
inline YAPPredicate ( char * s , Term * * outp ) {
Term t , tp ;
t = YAP_ReadBuffer ( s , & tp ) ;
2014-06-12 01:25:50 +01:00
ap = getPred ( t , ( Term * * ) NULL ) ;
2014-06-11 19:27:54 +01:00
}
/// meta-call this predicate, with arguments ts[]
///
int call ( YAPTerm ts [ ] ) ;
/// module of a predicate
///
/// notice that modules are currently treated as atoms, this should change.
YAPAtom module ( ) {
if ( ap - > ModuleOfPred = = PROLOG_MODULE )
return YAPAtom ( AtomProlog ) ;
else
return YAPAtom ( AtomOfTerm ( ap - > ModuleOfPred ) ) ;
}
/// name of predicate
///
/// notice that we return the atom, not a string.
YAPAtom name ( ) { if ( ap - > ArityOfPE )
return YAPAtom ( ( Atom ) ap - > FunctorOfPred ) ;
else
return YAPAtom ( NameOfFunctor ( ap - > FunctorOfPred ) ) ;
}
/// arity of predicate
///
/// we return a positive number.
arity_t getArity ( ) { return ap - > ArityOfPE ; }
2014-04-28 11:47:09 +01:00
} ;
2014-05-04 22:31:22 +01:00
/**
2014-06-04 22:08:37 +01:00
* @ brief Queries
2014-05-04 22:31:22 +01:00
*
* interface to a YAP Query ;
* uses an SWI - like status info internally .
*/
2014-06-11 19:27:54 +01:00
class YAPQuery : public YAPPredicate {
int q_open ;
int q_state ;
Term * q_g ;
yamop * q_p , * q_cp ;
jmp_buf q_env ;
int q_flags ;
YAP_dogoalinfo q_h ;
YAPQuery * oq ;
2014-06-16 14:41:54 +01:00
yhandle_t vnames ;
2014-06-11 19:27:54 +01:00
void initQuery ( Term ts [ ] ) ;
void initQuery ( YAPTerm t [ ] , arity_t arity ) ;
public :
/// main constructor, uses a predicate and an array of terms
///
/// It is given a YAPPredicate _p_ , and an array of terms that must have at least
/// the same arity as the functor.
YAPQuery ( YAPPredicate p , YAPTerm t [ ] ) ;
/// full constructor,
///
/// It is given a functor, module, and an array of terms that must have at least
/// the same arity as the functor.
YAPQuery ( YAPFunctor f , YAPTerm mod , YAPTerm t [ ] ) ;
/// functor/term constructor,
///
/// It is given a functor, and an array of terms that must have at least
/// the same arity as the functor. Works within the current module.
YAPQuery ( YAPFunctor f , YAPTerm t [ ] ) ;
/// string constructor with varnames
///
/// It is given a string, calls the parser and obtains a Prolog term that should be a callable
/// goal and a list of variables. Useful for top-level simulation. Works within the current module.
inline YAPQuery ( char * s ) : YAPPredicate ( s , & this - > q_g , vnames )
{
Term * ts = this - > q_g ;
initQuery ( ts ) ;
}
/// first query
///
/// actually implemented by calling the next();
inline bool first ( ) { return next ( ) ; }
/// ask for the next solution of the current query
/// same call for every solution
bool next ( ) ;
/// remove alternatives in the current search space, and finish the current query
void cut ( ) ;
/// finish the current query: undo all bindings.
void close ( ) ;
/// query variables.
YAPListTerm namedVars ( ) ;
} ;
// Java support
// This class implements a callback Prolog-side
class YAPCallback {
2014-04-28 11:47:09 +01:00
public :
2014-06-11 19:27:54 +01:00
virtual ~ YAPCallback ( ) { printf ( " ~YAPCallback \n " ) ; }
virtual void run ( ) { __android_log_print ( ANDROID_LOG_INFO , __FUNCTION__ , " callback " ) ; }
virtual void displayInWindow ( char * s ) { }
} ;
2014-04-29 11:45:19 +01:00
2014-05-04 22:31:22 +01:00
/**
2014-06-11 19:27:54 +01:00
* @ brief YAP Engine : takes care of constructing an execution environment where we can go executing goals
2014-05-04 22:31:22 +01:00
*
*/
class YAPEngine {
2014-06-11 19:27:54 +01:00
private :
YAPCallback * _callback ;
YAP_init_args init_args ;
2014-04-29 11:45:19 +01:00
public :
2014-06-12 01:25:50 +01:00
YAPEngine ( char * savedState = ( char * ) NULL ,
2014-06-11 19:27:54 +01:00
size_t stackSize = 0 ,
size_t trailSize = 0 ,
size_t maxStackSize = 0 ,
size_t maxTrailSize = 0 ,
2014-06-12 01:25:50 +01:00
char * libDir = ( char * ) NULL ,
char * bootFile = ( char * ) NULL ,
char * goal = ( char * ) NULL ,
char * topLevel = ( char * ) NULL ,
2014-06-11 19:27:54 +01:00
bool script = FALSE ,
bool fastBoot = FALSE ,
2014-06-12 01:25:50 +01:00
YAPCallback * callback = ( YAPCallback * ) NULL ) ; /// construct a new engine, including aaccess to callbacks
2014-06-11 19:27:54 +01:00
~ YAPEngine ( ) { delYAPCallback ( ) ; } /// kill engine
void delYAPCallback ( ) { _callback = 0 ; } /// remove current callback
void setYAPCallback ( YAPCallback * cb ) { delYAPCallback ( ) ; _callback = cb ; __android_log_print ( ANDROID_LOG_INFO , __FILE__ , " after loading startup %p " , cb ) ; } /// set a new callback
void call ( ) { if ( _callback ) _callback - > run ( ) ; } /// execute the callback.
void display ( char * s ) { __android_log_print ( ANDROID_LOG_INFO , __FUNCTION__ , " bef calling disp %s %p " , s , _callback ) ; if ( _callback ) _callback - > displayInWindow ( s ) ; } /// execute the callback.
YAPQuery * query ( char * s ) ; /// build a query on the engine
2014-04-29 11:45:19 +01:00
} ;
2014-06-11 19:27:54 +01:00
/*
* @ }
2014-05-04 22:31:22 +01:00
*
*/