Merge ssh://ssh.dcc.fc.up.pt:31064/home/vsc/yap

This commit is contained in:
Vitor Santos Costa 2018-05-22 21:40:22 +01:00
commit 30a3b72d62
16 changed files with 803 additions and 1009 deletions

View File

@ -34,9 +34,10 @@ X_API bool do_init_python(void);
YAPPredicate::YAPPredicate(Term &t, Term &tmod, CELL *&ts, const char *pname) { YAPPredicate::YAPPredicate(Term &t, Term &tmod, CELL *&ts, const char *pname) {
Term t0 = t; Term t0 = t;
ap = nullptr; ap = nullptr;
Yap_DebugPlWriteln(t);
restart: restart:
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
throw YAPError( SOURCE(), INSTANTIATION_ERROR, t0, pname); throw YAPError(SOURCE(), INSTANTIATION_ERROR, t0, pname);
} else if (IsAtomTerm(t)) { } else if (IsAtomTerm(t)) {
ap = RepPredProp(Yap_GetPredPropByAtom(AtomOfTerm(t), tmod)); ap = RepPredProp(Yap_GetPredPropByAtom(AtomOfTerm(t), tmod));
ts = nullptr; ts = nullptr;
@ -49,15 +50,16 @@ restart:
} else if (IsApplTerm(t)) { } else if (IsApplTerm(t)) {
Functor fun = FunctorOfTerm(t); Functor fun = FunctorOfTerm(t);
if (IsExtensionFunctor(fun)) { if (IsExtensionFunctor(fun)) {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, Yap_PredicateIndicator(t, tmod), pname); throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE,
Yap_PredicateIndicator(t, tmod), pname);
} }
if (fun == FunctorModule) { if (fun == FunctorModule) {
tmod = ArgOfTerm(1, t); tmod = ArgOfTerm(1, t);
if (IsVarTerm(tmod)) { if (IsVarTerm(tmod)) {
throw YAPError( SOURCE(), INSTANTIATION_ERROR, t0, pname); throw YAPError(SOURCE(), INSTANTIATION_ERROR, t0, pname);
} }
if (!IsAtomTerm(tmod)) { if (!IsAtomTerm(tmod)) {
throw YAPError( SOURCE(), TYPE_ERROR_ATOM, t0, pname); throw YAPError(SOURCE(), TYPE_ERROR_ATOM, t0, pname);
} }
t = ArgOfTerm(2, t); t = ArgOfTerm(2, t);
goto restart; goto restart;
@ -65,18 +67,18 @@ restart:
ap = RepPredProp(Yap_GetPredPropByFunc(fun, tmod)); ap = RepPredProp(Yap_GetPredPropByFunc(fun, tmod));
ts = RepAppl(t) + 1; ts = RepAppl(t) + 1;
} else { } else {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, t0, pname); throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t0, pname);
} }
} }
Term YAPTerm::getArg(arity_t i) { Term YAPTerm::getArg(arity_t i) {
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
Term tf = 0; Term tf = 0;
Term t0 = gt(); Term t0 = gt();
if (IsApplTerm(t0)) { if (IsApplTerm(t0)) {
if (i > ArityOfFunctor(FunctorOfTerm(t0))) if (i > ArityOfFunctor(FunctorOfTerm(t0)))
throw YAPError( SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()"); throw YAPError(SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
tf = (ArgOfTerm(i, t0)); tf = (ArgOfTerm(i, t0));
} else if (IsPairTerm(t0)) { } else if (IsPairTerm(t0)) {
if (i == 1) if (i == 1)
@ -84,13 +86,13 @@ restart:
else if (i == 2) else if (i == 2)
tf = (TailOfTerm(t0)); tf = (TailOfTerm(t0));
else else
throw YAPError( SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()"); throw YAPError(SOURCE(), DOMAIN_ERROR_OUT_OF_RANGE, t0, "t0.getArg()");
} else { } else {
throw YAPError( SOURCE(), TYPE_ERROR_COMPOUND, t0, "t0.getArg()"); throw YAPError(SOURCE(), TYPE_ERROR_COMPOUND, t0, "t0.getArg()");
} }
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return tf; return tf;
} }
YAPAtomTerm::YAPAtomTerm(char s[]) { // build string YAPAtomTerm::YAPAtomTerm(char s[]) { // build string
BACKUP_H(); BACKUP_H();
@ -265,7 +267,7 @@ Term &YAPTerm::operator[](arity_t i) {
tf = RepPair(t0) + 1; tf = RepPair(t0) + 1;
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
} else { } else {
throw YAPError( SOURCE(), TYPE_ERROR_COMPOUND, t0, ""); throw YAPError(SOURCE(), TYPE_ERROR_COMPOUND, t0, "");
} }
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return *tf; return *tf;
@ -307,7 +309,7 @@ std::vector<Term> YAPPairTerm::listToArray() {
Term t1 = gt(); Term t1 = gt();
Int l = Yap_SkipList(&t1, &tailp); Int l = Yap_SkipList(&t1, &tailp);
if (l < 0) { if (l < 0) {
throw YAPError( SOURCE(), TYPE_ERROR_LIST, (t), nullptr); throw YAPError(SOURCE(), TYPE_ERROR_LIST, (t), nullptr);
} }
std::vector<Term> o = std::vector<Term>(l); std::vector<Term> o = std::vector<Term>(l);
int i = 0; int i = 0;
@ -317,8 +319,7 @@ std::vector<Term> YAPPairTerm::listToArray() {
t = TailOfTerm(t); t = TailOfTerm(t);
} }
return o; return o;
} }
YAP_tag_t YAPTerm::tag() { YAP_tag_t YAPTerm::tag() {
Term tt = gt(); Term tt = gt();
@ -381,8 +382,8 @@ Term YAPListTerm::cdr() {
else if (to == TermNil) else if (to == TermNil)
return TermNil; return TermNil;
/* error */ /* error */
throw YAPError( SOURCE(), TYPE_ERROR_LIST, to, ""); throw YAPError(SOURCE(), TYPE_ERROR_LIST, to, "");
} }
Term YAPListTerm::dup() { Term YAPListTerm::dup() {
yhandle_t tn; yhandle_t tn;
@ -431,7 +432,7 @@ Term YAPListTerm::car() {
if (IsPairTerm(to)) if (IsPairTerm(to))
return (HeadOfTerm(to)); return (HeadOfTerm(to));
else { else {
throw YAPError( SOURCE(), TYPE_ERROR_LIST, to, ""); throw YAPError(SOURCE(), TYPE_ERROR_LIST, to, "");
return TermUnique; return TermUnique;
} }
} }
@ -487,7 +488,8 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) {
if (LOCAL_CommittedError != nullptr) { if (LOCAL_CommittedError != nullptr) {
std::cerr << "Exception received by " << __func__ << "( " std::cerr << "Exception received by " << __func__ << "( "
<< YAPError( LOCAL_CommittedError).text() << ").\n Forwarded...\n\n"; << YAPError(LOCAL_CommittedError).text()
<< ").\n Forwarded...\n\n";
// Yap_PopTermFromDB(info->errorTerm); // Yap_PopTermFromDB(info->errorTerm);
// throw throw YAPError( SOURCE(), ); // throw throw YAPError( SOURCE(), );
} }
@ -508,8 +510,10 @@ bool YAPEngine::mgoal(Term t, Term tmod) {
try { try {
if (IsStringTerm(tmod)) if (IsStringTerm(tmod))
tmod = MkAtomTerm(Yap_LookupAtom(StringOfTerm(tmod))); tmod = MkAtomTerm(Yap_LookupAtom(StringOfTerm(tmod)));
PredEntry *ap = (new YAPPredicate(t, tmod, ts, "C++"))->ap; YAPPredicate *p = new YAPPredicate(t, tmod, ts, "C++");
if (ap == nullptr || ap->OpcodeOfPred == UNDEF_OPCODE) { PredEntry *ap = nullptr;
if (p == nullptr || (ap = p->ap) == nullptr ||
ap->OpcodeOfPred == UNDEF_OPCODE) {
ap = rewriteUndefEngineQuery(ap, t, tmod); ap = rewriteUndefEngineQuery(ap, t, tmod);
} }
if (IsApplTerm(t)) if (IsApplTerm(t))
@ -534,19 +538,28 @@ bool YAPEngine::mgoal(Term t, Term tmod) {
result = (bool)YAP_EnterGoal(ap, nullptr, &q); result = (bool)YAP_EnterGoal(ap, nullptr, &q);
if (LOCAL_CommittedError != nullptr && if (LOCAL_CommittedError != nullptr &&
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) { LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
throw YAPError( LOCAL_CommittedError); throw YAPError(LOCAL_CommittedError);
} }
{ {
YAP_LeaveGoal(result, &q); YAP_LeaveGoal(result, &q);
if (LOCAL_CommittedError != nullptr &&
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
throw YAPError(LOCAL_CommittedError);
}
// PyEval_RestoreThread(_save); // PyEval_RestoreThread(_save);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return result; return result;
} }
} catch ( ... ) { } catch (...) {
if (LOCAL_CommittedError != nullptr && if (LOCAL_CommittedError != nullptr &&
LOCAL_CommittedError->errorNo != YAP_NO_ERROR) { LOCAL_CommittedError->errorNo != YAP_NO_ERROR) {
std::cerr << "Exception received by " << __func__ << "( " std::cerr << "Exception received by " << __func__ << "( "
<< YAPError( LOCAL_CommittedError).text() << ").\n Forwarded...\n\n"; << YAPError(LOCAL_CommittedError).text()
<< ").\n Forwarded...\n\n";
YAP_LeaveGoal(result, &q);
// free(LOCAL_CommittedError);
return false;
} }
} }
} }
@ -585,7 +598,7 @@ Term YAPEngine::fun(Term t) {
name = AtomDot; name = AtomDot;
f = FunctorDot; f = FunctorDot;
} else { } else {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, t, 0); throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t, 0);
return 0L; return 0L;
} }
XREGS[arity + 1] = MkVarTerm(); XREGS[arity + 1] = MkVarTerm();
@ -606,7 +619,8 @@ Term YAPEngine::fun(Term t) {
bool result = (bool)YAP_EnterGoal(ap, nullptr, &q); bool result = (bool)YAP_EnterGoal(ap, nullptr, &q);
if (LOCAL_CommittedError != nullptr) { if (LOCAL_CommittedError != nullptr) {
std::cerr << "Exception received by " << __func__ << "( " std::cerr << "Exception received by " << __func__ << "( "
<< YAPError( LOCAL_CommittedError).text() << ").\n Forwarded...\n\n"; << YAPError(LOCAL_CommittedError).text()
<< ").\n Forwarded...\n\n";
// Yap_PopTermFromDB(info->errorTerm); // Yap_PopTermFromDB(info->errorTerm);
// throw throw YAPError( SOURCE(), ); // throw throw YAPError( SOURCE(), );
} }
@ -912,14 +926,14 @@ PredEntry *YAPPredicate::getPred(YAPTerm &tt, CELL *&outp) {
Term m = Yap_CurrentModule(), t = tt.term(); Term m = Yap_CurrentModule(), t = tt.term();
t = Yap_StripModule(t, &m); t = Yap_StripModule(t, &m);
std::cerr << "Exception received by " << __func__ << "( " std::cerr << "Exception received by " << __func__ << "( " << tt.text()
<< tt.text() << ").\n Forwarded...\n\n"; << ").\n Forwarded...\n\n";
if (IsVarTerm(t) || IsNumTerm(t)) { if (IsVarTerm(t) || IsNumTerm(t)) {
if (IsVarTerm(t)) if (IsVarTerm(t))
throw YAPError( SOURCE(), INSTANTIATION_ERROR, tt.term(), 0); throw YAPError(SOURCE(), INSTANTIATION_ERROR, tt.term(), 0);
else if (IsNumTerm(t)) else if (IsNumTerm(t))
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, tt.term(), 0); throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, tt.term(), 0);
} }
tt.put(t); tt.put(t);
if (IsAtomTerm(t)) { if (IsAtomTerm(t)) {
@ -938,7 +952,7 @@ PredEntry *YAPPredicate::getPred(YAPTerm &tt, CELL *&outp) {
} }
Functor f = FunctorOfTerm(t); Functor f = FunctorOfTerm(t);
if (IsExtensionFunctor(f)) { if (IsExtensionFunctor(f)) {
throw YAPError( SOURCE(), TYPE_ERROR_CALLABLE, t, 0); throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t, 0);
} else { } else {
ap = RepPredProp(PredPropByFunc(f, m)); ap = RepPredProp(PredPropByFunc(f, m));
outp = RepAppl(t) + 1; outp = RepAppl(t) + 1;
@ -1002,7 +1016,10 @@ void *YAPPrologPredicate::retractClause(YAPTerm skeleton, bool all) {
std::string YAPError::text() { std::string YAPError::text() {
char buf[256]; char buf[256];
std::string s = ""; return "Error";
#if 0
std::stringstream s;
s << "";
if (info->errorNo == YAP_NO_ERROR) if (info->errorNo == YAP_NO_ERROR)
return 0; return 0;
if (info->errorFunction) { if (info->errorFunction) {
@ -1012,21 +1029,19 @@ std::string YAPError::text() {
s += buf; s += buf;
s += ":0 in C-code"; s += ":0 in C-code";
} }
return s;
if (info->prologPredLine) { if (info->prologPredLine) {
s += "\n"; s += "\n";
s += info->prologPredFile; s += info->prologPredFile;
s += ":"; s += ":";
sprintf(buf, "%ld", (long int)info->prologPredLine); s << info->prologPredLine;
s += buf; // std::to_string(info->prologPredLine) ;
// YAPIntegerTerm(info->prologPredLine).text(); // YAPIntegerTerm(info->prologPredLine).text();
s += ":0 "; s += ":0 ";
s += info->prologPredModule; s += info->prologPredModule;
s += ":"; s += ":";
s += (info->prologPredName); s += (info->prologPredName);
s += "/"; s += "/";
sprintf(buf, "%ld", (long int)info->prologPredArity); s << info->prologPredArity;
s += // std::to_string(info->prologPredArity);
buf;
} }
s += " error "; s += " error ";
if (info->classAsText == nullptr) if (info->classAsText == nullptr)
@ -1041,6 +1056,7 @@ std::string YAPError::text() {
s += ".\n"; s += ".\n";
// printf("%s\n", s.c_str()); // printf("%s\n", s.c_str());
return s.c_str(); return s.c_str();
#endif
} }
void YAPEngine::reSet() { void YAPEngine::reSet() {
@ -1063,7 +1079,6 @@ void YAPEngine::reSet() {
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
} }
Term YAPEngine::top_level(std::string s) { Term YAPEngine::top_level(std::string s) {
/// parse string s and make term with var names /// parse string s and make term with var names
/// available. /// available.
@ -1072,7 +1087,7 @@ Term YAPEngine::top_level(std::string s) {
ARG2 = tp; ARG2 = tp;
ARG3 = MkVarTerm(); ARG3 = MkVarTerm();
if (ARG1 == 0) if (ARG1 == 0)
throw YAPError( SOURCE(), SYNTAX_ERROR, ARG1, "in input query"); throw YAPError(SOURCE(), SYNTAX_ERROR, ARG1, "in input query");
YAPPredicate p = YAPPredicate(YAP_TopGoal()); YAPPredicate p = YAPPredicate(YAP_TopGoal());
YAPQuery *Q = new YAPQuery(p, 0); YAPQuery *Q = new YAPQuery(p, 0);
Term ts[2]; Term ts[2];

View File

@ -8,10 +8,8 @@
* * * *
************************************************************************** **************************************************************************
* * * *
* File: YapGFlagInfo.h * * File: YapGFlagInfo.h * Last rev:
* Last rev: * ** mods: * comments: global flag enumeration. *
* mods: *
* comments: global flag enumeration. *
* * * *
*************************************************************************/ *************************************************************************/
@ -24,49 +22,55 @@
@brief global flags and their values. @brief global flags and their values.
*/ */
START_GLOBAL_FLAGS START_GLOBAL_FLAGS
/** YAP_FLAG(ADDRESS_BITS_FLAG, "address_bits", false, nat, BITNESS, NULL), /**<
`address_bits` Number of address bits in the machine, either 64 or 32 bits.
Number of address bits in the machine, either 64 or 32 bits
*/ */
YAP_FLAG(ADDRESS_BITS_FLAG, "address_bits", false, nat, BITNESS, NULL),
/**< `agc_margin`
An integer: if this amount of atoms has been created since the last
atom-garbage collection, perform atom garbage collection at the first
opportunity. Initial value is 10,000. May be changed. A value of 0
(zero) disables atom garbage collection.
*/
YAP_FLAG(AGC_MARGIN_FLAG, "agc_margin", true, nat, "10000", YAP_FLAG(AGC_MARGIN_FLAG, "agc_margin", true, nat, "10000",
agc_threshold), agc_threshold), /**<
An integer: if this amount of atoms has been created since the last
atom-garbage collection, perform atom garbage collection at the first
opportunity. Initial value is 10,000. May be changed. A value of 0
(zero) disables atom garbage collection.
*/
/**< `allow_assert_for_static_predicates` allow asserting and retracting clauses of static
predicates. */
YAP_FLAG(ALLOW_ASSERT_FOR_STATIC_PREDICATES, YAP_FLAG(ALLOW_ASSERT_FOR_STATIC_PREDICATES,
"allow_assert_for_static_predicates", true, booleanFlag, "true", "allow_assert_for_static_predicates", true, booleanFlag, "true",
NULL), NULL), /**<
boolean: allow asserting and retracting clauses of static
predicates. */
/**< `allow_variable_name_as_functor` boolean flag allows constructs such as YAP_FLAG(ALLOW_VARIABLE_NAME_AS_FUNCTOR_FLAG,
"allow_variable_name_as_functor", false, booleanFlag, "false",
NULL), /**<
boolean flag allows syntax such
as
~~~ ~~~
Tree(Node(L,node,R)) :- Tree(Node(L,node,R)) :-
Tree(L), Tree(L),
Tree(R). Tree(R).
~~~ ~~~
*/ */
YAP_FLAG( ALLOW_VARIABLE_NAME_AS_FUNCTOR_FLAG, "allow_variable_name_as_functor", false, booleanFlag, "false", NULL),
/**< `answer_format` how to present answers, default is `~p`. */ /**< `answer_format` how to present answers, default is `~p`. */
YAP_FLAG(ANSWER_FORMAT_FLAG, "answer_format", true, isatom, "~p", YAP_FLAG(ANSWER_FORMAT_FLAG, "answer_format", true, isatom, "~p", NULL),
NULL),
#if __APPLE__ #if __APPLE__
/**< YAP_FLAG(APPLE_FLAG, "apple", false, booleanFlag, "true", NULL), /**<
`apple`: read-only boolean, a machine running an Apple Operating System * `read-only boolean, a machine running an Apple Operating System *
*/ *
YAP_FLAG(APPLE_FLAG, "apple", false, booleanFlag, "true",
NULL),
#endif #endif
YAP_FLAG(ARCH_FLAG, "arch", false, isatom, YAP_ARCH, NULL),
YAP_FLAG(ARCH_FLAG, "arch", false, isatom, YAP_ARCH, NULL),/**<
`apple`: read-only atom, it describes the ISA used in this version of YAP.
Available from YAP_AEH.
*/
YAP_FLAG(ARGV_FLAG, "argv", false, argv, "@boot", NULL), YAP_FLAG(ARGV_FLAG, "argv", false, argv, "@boot", NULL),
/**< `arithmetic_exceptions` /**< `arithmetic_exceptions`
@ -103,8 +107,7 @@
on whether YAP uses the GMP library or not. on whether YAP uses the GMP library or not.
*/ */
YAP_FLAG(BOUNDED_FLAG, "bounded", false, booleanFlag, "false", YAP_FLAG(BOUNDED_FLAG, "bounded", false, booleanFlag, "false", NULL),
NULL),
YAP_FLAG(C_CC_FLAG, "c_cc", false, isatom, C_CC, NULL), YAP_FLAG(C_CC_FLAG, "c_cc", false, isatom, C_CC, NULL),
YAP_FLAG(C_CFLAGS_FLAG, "c_cflags", false, isatom, C_CFLAGS, NULL), YAP_FLAG(C_CFLAGS_FLAG, "c_cflags", false, isatom, C_CFLAGS, NULL),
YAP_FLAG(C_LDFLAGS_FLAG, "c_ldflags", false, isatom, C_LDFLAGS, NULL), YAP_FLAG(C_LDFLAGS_FLAG, "c_ldflags", false, isatom, C_LDFLAGS, NULL),
@ -129,8 +132,8 @@
true, booleanFlag, "true", NULL), true, booleanFlag, "true", NULL),
/**< `compiled_at ` /**< `compiled_at `
Read-only flag that gives the time when the main YAP binary was compiled. It is Read-only flag that gives the time when the main YAP binary was compiled. It
obtained staight from the __TIME__ macro, as defined in the C99. is obtained staight from the __TIME__ macro, as defined in the C99.
*/ */
YAP_FLAG(COMPILED_AT_FLAG, "compiled_at", false, isatom, YAP_COMPILED_AT, YAP_FLAG(COMPILED_AT_FLAG, "compiled_at", false, isatom, YAP_COMPILED_AT,
NULL), NULL),
@ -140,8 +143,7 @@
`false`. If _Value_ is bound to `true` enable debugging, and if `false`. If _Value_ is bound to `true` enable debugging, and if
it is bound to `false` disable debugging. it is bound to `false` disable debugging.
*/ */
YAP_FLAG(DEBUG_FLAG, "debug", true, booleanFlag, "false", YAP_FLAG(DEBUG_FLAG, "debug", true, booleanFlag, "false", NULL),
NULL),
YAP_FLAG(DEBUG_INFO_FLAG, "debug_info", true, booleanFlag, "true", NULL), YAP_FLAG(DEBUG_INFO_FLAG, "debug_info", true, booleanFlag, "true", NULL),
YAP_FLAG(DEBUG_ON_ERROR_FLAG, "debug_on_error", true, booleanFlag, "true", YAP_FLAG(DEBUG_ON_ERROR_FLAG, "debug_on_error", true, booleanFlag, "true",
NULL), NULL),
@ -160,13 +162,12 @@
Read-only flag that always returns `yap`. Read-only flag that always returns `yap`.
*/ */
YAP_FLAG(DIALECT_FLAG, "dialect", false, ro, "yap", YAP_FLAG(DIALECT_FLAG, "dialect", false, ro, "yap", NULL),
NULL),
/**< `discontiguous_warnings ` /**< `discontiguous_warnings `
If `true` (default `true`) YAP checks for definitions of the same predicate that If `true` (default `true`) YAP checks for definitions of the same predicate
are separated by clauses for other predicates. This may indicate that different that are separated by clauses for other predicates. This may indicate that
procedures have the same name. different procedures have the same name.
The declaration discontiguous/1 disables this warning for user-specified The declaration discontiguous/1 disables this warning for user-specified
predicates. predicates.
@ -180,24 +181,21 @@
`on` consider `$` a lower case character. `on` consider `$` a lower case character.
*/ */
YAP_FLAG(DOLLAR_AS_LOWER_CASE_FLAG, "dollar_as_lower_case", true, YAP_FLAG(DOLLAR_AS_LOWER_CASE_FLAG, "dollar_as_lower_case", true,
booleanFlag, "false", booleanFlag, "false", NULL),
NULL),
/**< `double_quotes is iso ` /**< `double_quotes is iso `
If _Value_ is unbound, tell whether a double quoted list of characters If _Value_ is unbound, tell whether a double quoted list of characters
token is converted to a list of atoms, `chars`, to a list of integers, token is converted to a list of atoms, `chars`, to a list of integers,
`codes`, or to a single atom, `atom`. If _Value_ is bound, set to `codes`, or to a single atom, `atom`. If _Value_ is bound, set to
the corresponding behavior. The default value is `codes`. */ the corresponding behavior. The default value is `codes`. */
YAP_FLAG(DOUBLE_QUOTES_FLAG, "double_quotes", true, isatom, "codes", YAP_FLAG(DOUBLE_QUOTES_FLAG, "double_quotes", true, isatom, "codes", dqs),
dqs),
YAP_FLAG(EDITOR_FLAG, "editor", true, isatom, "$EDITOR", NULL), YAP_FLAG(EDITOR_FLAG, "editor", true, isatom, "$EDITOR", NULL),
/**< `executable ` /**< `executable `
Read-only flag. It unifies with an atom that gives the Read-only flag. It unifies with an atom that gives the
original program path. original program path.
*/ */
YAP_FLAG(EXECUTABLE_FLAG, "executable", false, executable, "@boot", YAP_FLAG(EXECUTABLE_FLAG, "executable", false, executable, "@boot", NULL),
NULL),
/**< `fast ` /**< `fast `
If `on` allow fast machine code, if `off` (default) disable it. Only If `on` allow fast machine code, if `off` (default) disable it. Only
@ -215,8 +213,7 @@
printed, `%g` will print all floats using 6 digits instead of the printed, `%g` will print all floats using 6 digits instead of the
default 15. default 15.
*/ */
YAP_FLAG(FLOAT_FORMAT_FLAG, "float_format", true, isatom, "%.16f", YAP_FLAG(FLOAT_FORMAT_FLAG, "float_format", true, isatom, "%.16f", NULL),
NULL),
/**< `gc` /**< `gc`
If `on` allow garbage collection (default), if `off` disable it. If `on` allow garbage collection (default), if `off` disable it.
@ -228,8 +225,7 @@
collection. The default depends on total stack size. collection. The default depends on total stack size.
*/ */
YAP_FLAG(GC_MARGIN_FLAG, "gc_margin", true, nat, "0", YAP_FLAG(GC_MARGIN_FLAG, "gc_margin", true, nat, "0", gc_margin),
gc_margin),
/**< `gc_trace ` /**< `gc_trace `
If `off` (default) do not show information on garbage collection If `off` (default) do not show information on garbage collection
@ -239,8 +235,7 @@
information on data-structures found during the garbage collection information on data-structures found during the garbage collection
process, namely, on choice-points. process, namely, on choice-points.
*/ */
YAP_FLAG(GC_TRACE_FLAG, "gc_trace", true, isatom, "off", YAP_FLAG(GC_TRACE_FLAG, "gc_trace", true, isatom, "off", NULL),
NULL),
/**< `generate_debug_info ` /**< `generate_debug_info `
If `true` (default) generate debugging information for If `true` (default) generate debugging information for
@ -265,8 +260,7 @@
Return `configure` system information, including the machine-id Return `configure` system information, including the machine-id
for which YAP was compiled and Operating System information. for which YAP was compiled and Operating System information.
*/ */
YAP_FLAG(HOST_TYPE_FLAG, "host_type", false, isatom, HOST_ALIAS, YAP_FLAG(HOST_TYPE_FLAG, "host_type", false, isatom, HOST_ALIAS, NULL),
NULL),
/**< `index ` /**< `index `
If `on` allow indexing (default), if `off` disable it, if If `on` allow indexing (default), if `off` disable it, if
@ -275,7 +269,8 @@
YAP_FLAG(INDEX_FLAG, "index", true, indexer, "multi", NULL), YAP_FLAG(INDEX_FLAG, "index", true, indexer, "multi", NULL),
/**< `Index_sub_term_search_depth ` /**< `Index_sub_term_search_depth `
Maximum bound on searching sub-terms for indexing, if `0` (default) no bound. Maximum bound on searching sub-terms for indexing, if `0` (default) no
bound.
*/ */
YAP_FLAG(INDEX_SUB_TERM_SEARCH_DEPTH_FLAG, "index_sub_term_search_depth", YAP_FLAG(INDEX_SUB_TERM_SEARCH_DEPTH_FLAG, "index_sub_term_search_depth",
true, nat, "0", NULL), true, nat, "0", NULL),
@ -290,12 +285,11 @@
isatom, "normal", NULL), isatom, "normal", NULL),
/**< `integer_rounding_function is iso ` /**< `integer_rounding_function is iso `
Read-only flag telling the rounding function used for integers. Takes the value Read-only flag telling the rounding function used for integers. Takes the
`toward_zero` for the current version of YAP. value `toward_zero` for the current version of YAP.
*/ */
YAP_FLAG(INTEGER_ROUNDING_FUNCTION_FLAG, "integer_rounding_function", true, YAP_FLAG(INTEGER_ROUNDING_FUNCTION_FLAG, "integer_rounding_function", true,
isatom, "toward_zero", isatom, "toward_zero", NULL),
NULL),
YAP_FLAG(ISO_FLAG, "iso", true, booleanFlag, "false", NULL), YAP_FLAG(ISO_FLAG, "iso", true, booleanFlag, "false", NULL),
/**< `language ` /**< `language `
@ -306,21 +300,23 @@
are interpreted, when to use dynamic, character escapes, and how files are interpreted, when to use dynamic, character escapes, and how files
are consulted. Also check the `dialect` option. are consulted. Also check the `dialect` option.
*/ */
YAP_FLAG(LANGUAGE_FLAG, "language", true, isatom, "yap", YAP_FLAG(LANGUAGE_FLAG, "language", true, isatom, "yap", NULL),
NULL), /**< if defined, first location where YAP expects to find the YAP Prolog
/**< if defined, first location where YAP expects to find the YAP Prolog library. Takes precedence over library_directory */ library. Takes precedence over library_directory */
YAP_FLAG(PROLOG_LIBRARY_DIRECTORY_FLAG, "prolog_library_directory", true, isatom, "", NULL), YAP_FLAG(PROLOG_LIBRARY_DIRECTORY_FLAG, "prolog_library_directory", true,
isatom, "", NULL),
/**< if defined, first location where YAP expects to find the YAP Prolog shared libraries (DLLS). Takes precedence over executable_directory/2. */ /**< if defined, first location where YAP expects to find the YAP Prolog
YAP_FLAG(PROLOG_FOREIGN_DIRECTORY_FLAG, "prolog_foreign_directory", true, isatom, "", NULL), shared libraries (DLLS). Takes precedence over executable_directory/2. */
YAP_FLAG(PROLOG_FOREIGN_DIRECTORY_FLAG, "prolog_foreign_directory", true,
isatom, "", NULL),
/**< `max_arity is iso ` /**< `max_arity is iso `
Read-only flag telling the maximum arity of a functor. Takes the value Read-only flag telling the maximum arity of a functor. Takes the value
`unbounded` for the current version of YAP. `unbounded` for the current version of YAP.
*/ */
YAP_FLAG(MAX_ARITY_FLAG, "max_arity", false, isatom, "unbounded", YAP_FLAG(MAX_ARITY_FLAG, "max_arity", false, isatom, "unbounded", NULL),
NULL),
YAP_FLAG(MAX_TAGGED_INTEGER_FLAG, "max_tagged_integer", false, at2n, YAP_FLAG(MAX_TAGGED_INTEGER_FLAG, "max_tagged_integer", false, at2n,
"INT_MAX", NULL), "INT_MAX", NULL),
YAP_FLAG(MAX_THREADS_FLAG, "max_threads", false, at2n, "MAX_THREADS", NULL), YAP_FLAG(MAX_THREADS_FLAG, "max_threads", false, at2n, "MAX_THREADS", NULL),
@ -365,19 +361,18 @@
If `off` (default) do not compile call counting information for If `off` (default) do not compile call counting information for
procedures. If `on` compile predicates so that they calls and procedures. If `on` compile predicates so that they calls and
retries to the predicate may be counted. Profiling data can be read through the retries to the predicate may be counted. Profiling data can be read through
call_count_data/3 built-in. the call_count_data/3 built-in.
*/ */
YAP_FLAG(PROFILING_FLAG, "profiling", true, booleanFlag, "false", YAP_FLAG(PROFILING_FLAG, "profiling", true, booleanFlag, "false", NULL),
NULL),
/**< `prompt_alternatives_on(atom, /**< `prompt_alternatives_on(atom,
changeable) ` changeable) `
SWI-Compatible option, determines prompting for alternatives in the Prolog SWI-Compatible option, determines prompting for alternatives in the Prolog
toplevel. Default is <tt>groundness</tt>, YAP prompts for alternatives if and toplevel. Default is <tt>groundness</tt>, YAP prompts for alternatives if
only if the query contains variables. The alternative, default in SWI-Prolog is and only if the query contains variables. The alternative, default in
<tt>determinism</tt> which implies the system prompts for alternatives if the SWI-Prolog is <tt>determinism</tt> which implies the system prompts for
goal succeeded while leaving choicepoints. */ alternatives if the goal succeeded while leaving choicepoints. */
YAP_FLAG(PROMPT_ALTERNATIVES_ON_FLAG, "prompt_alternatives_on", true, YAP_FLAG(PROMPT_ALTERNATIVES_ON_FLAG, "prompt_alternatives_on", true,
isatom, "determinism", NULL), isatom, "determinism", NULL),
YAP_FLAG(QUASI_QUOTATIONS_FLAG, "quasi_quotations", true, booleanFlag, YAP_FLAG(QUASI_QUOTATIONS_FLAG, "quasi_quotations", true, booleanFlag,
@ -385,8 +380,8 @@
/**< `readline(boolean, changeable)` /**< `readline(boolean, changeable)`
} }
enable the use of the readline library for console interactions, true by default enable the use of the readline library for console interactions, true by
if readline was found. */ default if readline was found. */
YAP_FLAG(READLINE_FLAG, "readline", true, booleanFlag, "false", YAP_FLAG(READLINE_FLAG, "readline", true, booleanFlag, "false",
Yap_InitReadline), Yap_InitReadline),
YAP_FLAG(REPORT_ERROR_FLAG, "report_error", true, booleanFlag, "true", YAP_FLAG(REPORT_ERROR_FLAG, "report_error", true, booleanFlag, "true",
@ -420,9 +415,9 @@
*/ */
YAP_FLAG(SHARED_OBJECT_SEARCH_PATH_FLAG, "shared_object_search_path", true, YAP_FLAG(SHARED_OBJECT_SEARCH_PATH_FLAG, "shared_object_search_path", true,
isatom, SO_PATH, NULL), isatom, SO_PATH, NULL),
/**< `single_quoted text is usuallly interpreted as atoms. This flagTerm allows other inerpretations such as strings_contains_strings */ /**< `single_quoted text is usuallly interpreted as atoms. This flagTerm
YAP_FLAG(SINGLE_QUOTES_FLAG, "single_quotes", true, isatom, "atom", allows other inerpretations such as strings_contains_strings */
sqf), YAP_FLAG(SINGLE_QUOTES_FLAG, "single_quotes", true, isatom, "atom", sqf),
/**< `signals` /**< `signals`
@ -430,16 +425,14 @@
(`SIGINT`). (`SIGINT`).
*/ */
YAP_FLAG(SIGNALS_FLAG, "signals", true, booleanFlag, "true", YAP_FLAG(SIGNALS_FLAG, "signals", true, booleanFlag, "true", NULL),
NULL),
/**< `source` /**< `source`
If `true` maintain the source for all clauses. Notice that this is trivially If `true` maintain the source for all clauses. Notice that this is trivially
supported for facts, and always supported for dynamic code. supported for facts, and always supported for dynamic code.
*/ */
YAP_FLAG(SOURCE_FLAG, "source", true, booleanFlag, "true", YAP_FLAG(SOURCE_FLAG, "source", true, booleanFlag, "true", NULL),
NULL),
/**< `strict_iso ` /**< `strict_iso `
If _Value_ is unbound, tell whether strict ISO compatibility mode If _Value_ is unbound, tell whether strict ISO compatibility mode
@ -462,8 +455,7 @@
depends on a Prolog's platform specific features. depends on a Prolog's platform specific features.
*/ */
YAP_FLAG(STRICT_ISO_FLAG, "strict_iso", true, booleanFlag, "false", YAP_FLAG(STRICT_ISO_FLAG, "strict_iso", true, booleanFlag, "false", NULL),
NULL),
/**< `system_options ` /**< `system_options `
This read only flag tells which options were used to compile This read only flag tells which options were used to compile
@ -482,8 +474,7 @@
(see Tabling) for the list of options. (see Tabling) for the list of options.
*/ */
YAP_FLAG(TABLING_MODE_FLAG, "tabling_mode", true, isatom, "[]", YAP_FLAG(TABLING_MODE_FLAG, "tabling_mode", true, isatom, "[]", NULL),
NULL),
YAP_FLAG(THREADS_FLAG, "threads", false, ro, "MAX_THREADS", NULL), YAP_FLAG(THREADS_FLAG, "threads", false, ro, "MAX_THREADS", NULL),
YAP_FLAG(TIMEZONE_FLAG, "timezone", false, ro, "18000", NULL), YAP_FLAG(TIMEZONE_FLAG, "timezone", false, ro, "18000", NULL),
YAP_FLAG(TOPLEVEL_PRINT_ANON_FLAG, "toplevel_print_anon", true, booleanFlag, YAP_FLAG(TOPLEVEL_PRINT_ANON_FLAG, "toplevel_print_anon", true, booleanFlag,
@ -538,8 +529,7 @@
are `error`, `fail`, and `warning`. Yap includes the following extensions: are `error`, `fail`, and `warning`. Yap includes the following extensions:
`fast_fail` does not invoke any handler. `fast_fail` does not invoke any handler.
*/ */
YAP_FLAG(UNKNOWN_FLAG, "unknown", true, isatom, "error", YAP_FLAG(UNKNOWN_FLAG, "unknown", true, isatom, "error", Yap_unknown),
Yap_unknown),
YAP_FLAG(VARIABLE_NAMES_MAY_END_WITH_QUOTES_FLAG, YAP_FLAG(VARIABLE_NAMES_MAY_END_WITH_QUOTES_FLAG,
"variable_names_may_end_with_quotes", true, booleanFlag, "false", "variable_names_may_end_with_quotes", true, booleanFlag, "false",
NULL), NULL),
@ -551,8 +541,7 @@
YAP is booted with the `-q` or `-L` flag. YAP is booted with the `-q` or `-L` flag.
*/ */
YAP_FLAG(VERBOSE_FLAG, "verbose", true, isatom, "normal", YAP_FLAG(VERBOSE_FLAG, "verbose", true, isatom, "normal", NULL),
NULL),
YAP_FLAG(VERBOSE_AUTOLOAD_FLAG, "verbose_autoload", true, booleanFlag, YAP_FLAG(VERBOSE_AUTOLOAD_FLAG, "verbose_autoload", true, booleanFlag,
"false", NULL), "false", NULL),
/**< `verbose_file_search ` /**< `verbose_file_search `
@ -571,8 +560,7 @@
is `normal` by default except if YAP is booted with the `-L` is `normal` by default except if YAP is booted with the `-L`
flag. flag.
*/ */
YAP_FLAG(VERBOSE_LOAD_FLAG, "verbose_load", true, isatom, "normal", YAP_FLAG(VERBOSE_LOAD_FLAG, "verbose_load", true, isatom, "normal", NULL),
NULL),
/**< `version_data ` /**< `version_data `
Read-only flag that unifies with a number of the form Read-only flag that unifies with a number of the form
@ -580,22 +568,19 @@
_Major_ is the major version, _Minor_ is the minor version, _Major_ is the major version, _Minor_ is the minor version,
and _Patch_ is the patch number. and _Patch_ is the patch number.
*/ */
YAP_FLAG(VERSION_FLAG, "version", false, nat, YAP_NUMERIC_VERSION, YAP_FLAG(VERSION_FLAG, "version", false, nat, YAP_NUMERIC_VERSION, NULL),
NULL),
/**< /**<
`version ` Read-only flag that returns a compound term with the `version ` Read-only flag that returns a compound term with the
current version of YAP. The term will have the name `yap` and arity 4, the first current version of YAP. The term will have the name `yap` and arity 4, the
argument will be the first argument will be the major version, the second the minor version, the
major version, the second the minor version, the third the patch number, and the third the patch number, and the last one is reserved.
last one is reserved.
*/ */
YAP_FLAG(VERSION_DATA_FLAG, "version_data", false, ro, YAP_TVERSION, YAP_FLAG(VERSION_DATA_FLAG, "version_data", false, ro, YAP_TVERSION, NULL),
NULL),
/**< `version_git ` /**< `version_git `
` `
this is the unique identifier for the last commit of the current GIT HEAD, it this is the unique identifier for the last commit of the current GIT HEAD,
xan be used to identify versions that differ on small (or large) updates. it xan be used to identify versions that differ on small (or large) updates.
*/ */
YAP_FLAG(VERSION_GIT_FLAG, "version_git", false, isatom, YAP_GIT_HEAD, YAP_FLAG(VERSION_GIT_FLAG, "version_git", false, isatom, YAP_GIT_HEAD,
NULL), NULL),
@ -621,4 +606,4 @@
END_GLOBAL_FLAGS END_GLOBAL_FLAGS
//! @} //! @}

View File

@ -66,10 +66,12 @@ if(R_COMMAND)
find_library(R_LIBRARY_READLINE readline find_library(R_LIBRARY_READLINE readline
DOC "(Optional) system readline library. Only required if the R libraries were built with readline support.") DOC "(Optional) system readline library. Only required if the R libraries were built with readline support.")
else()
# Note: R_LIBRARY_BASE is added to R_LIBRARIES twice; this may be due to circular linking dependencies; needs further investigation message(SEND_ERROR "FindR.cmake requires the following variables to be set: R_COMMAND")
set(R_LIBRARIES ${R_LIBRARY_BASE} ${R_LIBRARY_BLAS} ${R_LIBRARY_LAPACK} ${R_LIBRARY_BASE}) endif()
if(R_LIBRARY_READLINE)
set(R_LIBRARIES ${R_LIBRARIES} ${R_LIBRARY_READLINE}) # Note: R_LIBRARY_BASE is added to R_LIBRARIES twice; this may be due to circular linking dependencies; needs further investigation
endif() set(R_LIBRARIES ${R_LIBRARY_BASE} ${R_LIBRARY_BLAS} ${R_LIBRARY_LAPACK} ${R_LIBRARY_BASE})
if(R_LIBRARY_READLINE)
set(R_LIBRARIES ${R_LIBRARIES} ${R_LIBRARY_READLINE})
endif() endif()

View File

@ -2109,20 +2109,20 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = # PREDEFINED = \
# YAP_FLAG(ITEM,NAME,WRITABLE,DEF,INIT,HELPER)=ITEM \ YAP_FLAG(ITEM,NAME,WRITABLE,DEF,INIT,HELPER):=NAME \
# START_LOCAL_FLAGS="enum THREAD_LOCAL_FLAGS {" \ START_LOCAL_FLAGS:="enum THREAD_LOCAL_FLAGS {" \
# END_LOCAL_FLAGS=" };"\ END_LOCAL_FLAGS:=" };"\
# START_GLOBAL_FLAGS="enum GLOBAL_FLAGS {" \ START_GLOBAL_FLAGS:="enum GLOBAL_FLAGS {" \
# END_GLOBAL_FLAGS="};" \ END_GLOBAL_FLAGS:="};" \
# LOCAL(A, B)="A B" \ LOCAL(A, B):="A B" \
# LOCAL_INIT(A, B, C)="A B;B = C" \ LOCAL_INIT(A, B, C):="A B;B := C" \
# LOCAL_ARRAY(A, B, C)="A B[C]" \ LOCAL_ARRAY(A, B, C):="A B[C]" \
# LOCAL_ARRAY_ARRAY(A, B, C,D)="A B[C][D]"\ LOCAL_ARRAY_ARRAY(A, B, C,D):="A B[C][D]"\
# LOCAL_INIT(A, B, C, D)="A B[C][D]"\ LOCAL_INIT(A, B, C, D):="A B[C][D]"\
# LOCAL_INITF(A, B, C)=" A B; C"\ LOCAL_INITF(A, B, C):=" A B; C"\
# LOCAL_INIT_RESTORE(A,B,C,D)="A B; C; D;"\ LOCAL_INIT_RESTORE(A,B,C,D):="A B; C; D;"\
# PREG=Yap_REGS.P_ PREG:=Yap_REGS.P_
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The # tag can be used to specify a list of macro names that should be expanded. The

View File

@ -7,20 +7,5 @@
YAP includes a number of extensions over the original Prolog YAP includes a number of extensions over the original Prolog
language. Next, we discuss how to use the most important ones. language. Next, we discuss how to use the most important ones.
+ @ref Rational_Trees
+ @ref AttributedVariables
+ @ref DepthLimited
+ @ref Tabling
+ @ref Threads
+ @ref Profiling
+ @ref YAPArrays
+ @ref Parallelism
@} @}

View File

@ -28,7 +28,8 @@ static char SccsId[] = "%W% %G%";
*/ */
/* /*
* This file includes the definition of a miscellania of standard predicates * * This file includes the definition of a miscellania of standard predicates *
*for yap refering to: Files and GLOBAL_Streams, Simple Input/Output, *for yap refering to: Files and GLOBAL_1588
*ams, Simple Input/Output,
* *
*/ */
@ -1584,7 +1585,7 @@ int Yap_OpenStream(Term tin, const char *io_mode, Term user_name,
st->file = fopen(fname, io_mode); st->file = fopen(fname, io_mode);
} }
if (!st->file) { if (!st->file) {
fprintf(stderr, "trying %s\n", fname);
PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s", fname); PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s", fname);
/* extract BACK info passed through the stream descriptor */ /* extract BACK info passed through the stream descriptor */
return -1; return -1;
@ -1632,12 +1633,10 @@ int Yap_OpenStream(Term tin, const char *io_mode, Term user_name,
if (!strchr(io_mode, 'b') && binary_file(fname)) { if (!strchr(io_mode, 'b') && binary_file(fname)) {
UNLOCK(st->streamlock); UNLOCK(st->streamlock);
if (errno == ENOENT && !strchr(io_mode, 'r')) { if (errno == ENOENT && !strchr(io_mode, 'r')) {
PlIOError(EXISTENCE_ERROR_SOURCE_SINK, PlIOError(EXISTENCE_ERROR_SOURCE_SINK, tin, "%s: %s", fname,
tin, "%s: %s", fname,
strerror(errno)); strerror(errno));
} else { } else {
PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, tin, "%s: %s", fname,
tin, "%s: %s", fname,
strerror(errno)); strerror(errno));
} }
} }

View File

@ -200,7 +200,7 @@
int getRealNumber(char *c, double *number); int getRealNumber(char *c, double *number);
int getIntNumber(char *c, int *number); int getIntNumber(char *c, int *number);
inline int getPosNumber(char *c, int *number); //inline int getPosNumber(char *c, int *number);
int IsRealNumber(char *c); int IsRealNumber(char *c);
int IsPosNumber(const char *c); int IsPosNumber(const char *c);
int IsNumber(const char *c); int IsNumber(const char *c);

View File

@ -188,12 +188,13 @@
//#include <stdio.h> //#include <stdio.h>
//#include <stdlib.h> //#include <stdlib.h>
#include <unistd.h>
#include "simplecudd.h" #include "simplecudd.h"
#include "problogmath.h" #include "problogmath.h"
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#define VERSION "2.0.1" #define PROBLOGBDD_VERSION "2.0.1"
#ifndef max #ifndef max
@ -1550,7 +1551,7 @@ int argtype(const char *arg) {
} }
void printhelp(int argc, char **arg) { void printhelp(int argc, char **arg) {
fprintf(stderr, "\n\nProbLogBDD Tool Version: %s\n\n", VERSION); fprintf(stderr, "\n\nProbLogBDD Tool Version: %s\n\n", PROBLOGBDD_VERSION);
fprintf(stderr, "SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html)\n"); fprintf(stderr, "SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html)\n");
fprintf(stderr, "SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be)\n"); fprintf(stderr, "SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be)\n");
fprintf(stderr, "Copyright Katholieke Universiteit Leuven 2008\n"); fprintf(stderr, "Copyright Katholieke Universiteit Leuven 2008\n");

View File

@ -400,7 +400,7 @@ int simpleNamedBDDtoDot(DdManager *manager, namedvars varmap, DdNode *bdd,
// Cudd_AutodynEnable(mana, CUDD_REORDER_EXACT); // Cudd_AutodynEnable(mana, CUDD_REORDER_EXACT);
// Cudd_ReduceHeap(manager, CUDD_REORDER_SIFT, 1); // Cudd_ReduceHeap(manager, CUDD_REORDER_SIFT, 1);
ret = Cudd_DumpDot(manager, 1, f, varmap.vars, NULL, fd); ret = Cudd_DumpDot(manager, 1, f, (const char *const *)varmap.vars, NULL, fd);
fclose(fd); fclose(fd);
return ret; return ret;
} }

View File

@ -7,8 +7,7 @@
YAP_Term TermErrStream, TermOutStream; YAP_Term TermErrStream, TermOutStream;
static int py_put(int sno, int ch) static int py_put(int sno, int ch) {
{
// PyObject *pyw; // buffer // PyObject *pyw; // buffer
// int pyw_kind; // int pyw_kind;
// PyObject *pyw_data; // PyObject *pyw_data;
@ -33,8 +32,7 @@ static int py_put(int sno, int ch)
PyObject_CallMethodObjArgs(st->u.private_data, PyUnicode_FromString("write"), PyObject_CallMethodObjArgs(st->u.private_data, PyUnicode_FromString("write"),
PyUnicode_FromString(s), NULL); PyUnicode_FromString(s), NULL);
python_release_GIL(g0); python_release_GIL(g0);
if ((err = PyErr_Occurred())) if ((err = PyErr_Occurred())) {
{
PyErr_SetString( PyErr_SetString(
err, err,
"Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__); "Error in put\n"); // %s:%s:%d!\n", __FILE__, __FUNCTION__, __LINE__);
@ -43,7 +41,8 @@ static int py_put(int sno, int ch)
} }
VFS_t pystream; VFS_t pystream;
static void *py_open(VFS_t *me, const char *name, const char *io_mode, int sno) { static void *py_open(VFS_t *me, const char *name, const char *io_mode,
int sno) {
#if HAVE_STRCASESTR #if HAVE_STRCASESTR
if (strcasestr(name, "/python/") == name) if (strcasestr(name, "/python/") == name)
name += strlen("/python/"); name += strlen("/python/");
@ -59,14 +58,17 @@ VFS_t pystream;
} }
StreamDesc *st = YAP_RepStreamFromId(sno); StreamDesc *st = YAP_RepStreamFromId(sno);
st->name = YAP_LookupAtom(name); st->name = YAP_LookupAtom(name);
if (strcmp(name,"sys.stdout") == 0) { if (strcmp(name, "sys.stdout") == 0) {
st->user_name = TermOutStream; st->user_name = TermOutStream;
} else if(strcmp(name,"sys.stderr") == 0) { } else if (strcmp(name, "sys.stderr") == 0) {
st->user_name = TermErrStream; st->user_name = TermErrStream;
} else { } else {
st->user_name = YAP_MkAtomTerm(st->name); st->user_name = YAP_MkAtomTerm(st->name);
} }
// we assume object is already open, so there is no need to open it. // we assume object is already open, so there is no need to open it.
if (PyCallable_Check(pystream))
st->u.private_data = PyObject_Call(pystream, PyTuple_New(0), NULL);
else
st->u.private_data = pystream; st->u.private_data = pystream;
st->vfs = me; st->vfs = me;
python_release_GIL(ctk); python_release_GIL(ctk);
@ -75,8 +77,7 @@ VFS_t pystream;
static bool py_close(int sno) { static bool py_close(int sno) {
StreamDesc *st = YAP_RepStreamFromId(sno); StreamDesc *st = YAP_RepStreamFromId(sno);
if (strcmp(st->name,"sys.stdout") && if (strcmp(st->name, "sys.stdout") && strcmp(st->name, "sys.stderr")) {
strcmp(st->name,"sys.stderr")) {
Py_XDECREF(st->u.private_data); Py_XDECREF(st->u.private_data);
} }
st->u.private_data = NULL; st->u.private_data = NULL;
@ -89,18 +90,19 @@ static bool getLine(int inp) {
char *myrl_line = NULL; char *myrl_line = NULL;
StreamDesc *rl_instream = YAP_RepStreamFromId(inp); StreamDesc *rl_instream = YAP_RepStreamFromId(inp);
term_t ctk = python_acquire_GIL(); term_t ctk = python_acquire_GIL();
fprintf(stderr,"in"); fprintf(stderr, "in");
PyObject*prompt = PyUnicode_FromString( "?- "), PyObject *prompt = PyUnicode_FromString("?- "),
*msg = PyUnicode_FromString(" **input** "); *msg = PyUnicode_FromString(" **input** ");
/* window of vulnerability opened */ /* window of vulnerability opened */
myrl_line = PyUnicode_AsUTF8(PyObject_CallFunctionObjArgs(rl_instream->u.private_data,msg,prompt,NULL)); myrl_line = PyUnicode_AsUTF8(PyObject_CallFunctionObjArgs(
rl_instream->u.private_data, msg, prompt, NULL));
python_release_GIL(ctk); python_release_GIL(ctk);
rl_instream->u.irl.ptr = rl_instream->u.irl.buf = (const unsigned char*)myrl_line; rl_instream->u.irl.ptr = rl_instream->u.irl.buf =
(const unsigned char *)myrl_line;
myrl_line = NULL; myrl_line = NULL;
return true; return true;
} }
static int py_getc(int sno) { static int py_getc(int sno) {
StreamDesc *s = YAP_RepStreamFromId(sno); StreamDesc *s = YAP_RepStreamFromId(sno);
int ch; int ch;
@ -117,7 +119,7 @@ static int py_getc(int sno) {
} else { } else {
return EOF; return EOF;
} }
return ch; return ch;
} }
/** /**
@ -151,7 +153,6 @@ static int py_peek(int sno) {
return ch; return ch;
} }
static int64_t py_seek(int sno, int64_t where, int how) { static int64_t py_seek(int sno, int64_t where, int how) {
StreamDesc *g0 = YAP_RepStreamFromId(sno); StreamDesc *g0 = YAP_RepStreamFromId(sno);
term_t s0 = python_acquire_GIL(); term_t s0 = python_acquire_GIL();
@ -159,7 +160,7 @@ static int64_t py_seek(int sno, int64_t where, int how) {
PyObject *pyr = PyObject_CallFunctionObjArgs(fseek, PyLong_FromLong(where), PyObject *pyr = PyObject_CallFunctionObjArgs(fseek, PyLong_FromLong(where),
PyLong_FromLong(how), NULL); PyLong_FromLong(how), NULL);
python_release_GIL(s0); python_release_GIL(s0);
return PyLong_AsLong(pyr); return PyLong_AsLong(pyr);
} }
static void py_flush(int sno) { static void py_flush(int sno) {

View File

@ -20,7 +20,6 @@
% ] % ]
%% ). %% ).
:- [library(hacks)]. :- [library(hacks)].
:- reexport(library(yapi)). :- reexport(library(yapi)).
:- use_module(library(lists)). :- use_module(library(lists)).
:- use_module(library(maplist)). :- use_module(library(maplist)).
@ -274,4 +273,21 @@ close_events( Self ) :-
fail. fail.
close_events( _ ). close_events( _ ).
:- if( current_prolog_flag(apple, true) ).
:- putenv( 'LC_ALL', 'en_us:UTF-8').
plot_inline :-
X := self.inline_plotting,
nb_setval(inline, X ),
X = true,
!,
:= (
import( matplotlib ),
matplotlib.use( `nbagg` )
).
:- endif.
%:- ( start_low_level_trace ). %:- ( start_low_level_trace ).

View File

@ -19,231 +19,24 @@
# #
# Variable search order: # Variable search order:
# 1. Attempt to locate and set R_COMMAND # 1. Attempt to locate and set R_COMMAND
# - If unsuccessful, generate error and prompt user to manually set R_COMMAND # If unsuccessful, generate error and prompt user to manually set R_COMMAND
# 2. Use R_COMMAND to set R_HOME # 2. Use R_COMMAND to set R_HOME
# 3. Locate other libraries in the priority: # 3. Locate other libraries in the priority:
# 1. Within a user-built instance of R at R_HOME # 1. Within a user-built instance of R at R_HOME
# 2. Within an installed instance of R # 2. Within an installed instance of R
# 3. Within external system libraries # 3. Within external system libraries
# #
if (R_LIBRARIES AND R_INCLUDE_DIR)
set_package_properties(R PROPERTIES set_package_properties(R PROPERTIES
DESCRIPTION "The R Project for Statistical Computing." DESCRIPTION "The R Project for Statistical Computing."
URL "https://www.r-project.org/") URL "https://www.r-project.org/")
add_lib(real ${REAL_SOURCES})
find_program ( target_link_libraries (real ${R_LIBRARIES} libYap)
R_COMMAND
NAMES R r
)
if (R_COMMAND)
# find the R binary
MESSAGE(STATUS "Looking for R executable")
IF(NOT R_EXECUTABLE)
FIND_PROGRAM(R_EXECUTABLE R)
IF(R_EXECUTABLE-NOTFOUND)
MESSAGE(FATAL_ERROR "Could NOT find R (TODO: name option)")
ELSE(R_EXECUTABLE-NOTFOUND)
MESSAGE(STATUS "Using R at ${R_EXECUTABLE}")
ENDIF(R_EXECUTABLE-NOTFOUND)
ENDIF(NOT R_EXECUTABLE)
# find R_HOME
MESSAGE(STATUS "Looking for R_HOME")
IF(NOT R_HOME)
EXECUTE_PROCESS(
COMMAND ${R_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home())"
OUTPUT_VARIABLE R_HOME)
ENDIF(NOT R_HOME)
IF(NOT R_HOME)
MESSAGE(FATAL_ERROR "Could NOT determine R_HOME (probably you misspecified the location of R)")
ELSE(NOT R_HOME)
MESSAGE(STATUS "R_HOME is ${R_HOME}")
ENDIF(NOT R_HOME)
# find R include dir
MESSAGE(STATUS "Looking for R include files")
IF(NOT R_INCLUDEDIR)
IF(WIN32 OR APPLE) # This version of the test will not work with R < 2.9.0, but the other version (in the else part) will not work on windows or apple (but we do not really need to support ancient versions of R, there).
EXECUTE_PROCESS(
COMMAND ${R_EXECUTABLE} "--slave" "--no-save" "-e" "cat(R.home('include'))"
OUTPUT_VARIABLE R_INCLUDEDIR)
ELSE(WIN32 OR APPLE)
EXECUTE_PROCESS(
COMMAND ${R_EXECUTABLE} CMD sh -c "echo -n $R_INCLUDE_DIR"
OUTPUT_VARIABLE R_INCLUDEDIR)
ENDIF(WIN32 OR APPLE)
ELSE(NOT R_INCLUDEDIR)
MESSAGE(STATUS "Location specified by user")
ENDIF(NOT R_INCLUDEDIR)
IF(NOT R_INCLUDEDIR)
SET(R_INCLUDEDIR ${R_HOME}/include)
MESSAGE(STATUS "Not findable via R. Guessing")
ENDIF(NOT R_INCLUDEDIR)
MESSAGE(STATUS "Include files should be at ${R_INCLUDEDIR}. Checking for R.h")
IF(NOT R_H)
FIND_FILE(R_H
R.h
PATHS ${R_INCLUDEDIR}
NO_DEFAULT_PATH)
ENDIF(NOT R_H)
IF(NOT R_H)
MESSAGE(FATAL_ERROR "Not found")
ELSE(NOT R_H)
MESSAGE(STATUS "Found at ${R_H}")
GET_FILENAME_COMPONENT(R_INCLUDEDIR ${R_H}
PATH)
ENDIF(NOT R_H)
# check for existence of libR.so
IF(NOT LIBR_SO)
MESSAGE(STATUS "Checking for existence of R shared library")
FIND_LIBRARY(LIBR_SO
R
PATHS ${R_HOME}/lib ${R_SHAREDLIBDIR} ${R_HOME}/bin
NO_DEFAULT_PATH)
endif(NOT LIBR_SO)
IF(NOT LIBR_SO)
MESSAGE(FATAL_ERROR "Not found. Make sure the location of R was detected correctly, above, and R was compiled with the --enable-shlib option")
ELSE(NOT LIBR_SO)
MESSAGE(STATUS "Exists at ${LIBR_SO}")
GET_FILENAME_COMPONENT(R_SHAREDLIBDIR ${LIBR_SO}
PATH)
SET(R_USED_LIBS R)
ENDIF(NOT LIBR_SO)
# for at least some versions of R, we seem to have to link against -lRlapack. Else loading some
# R packages will fail due to unresolved symbols, or we can't link against -lR.
# However, we can't do this unconditionally,
# as this is not available in some configurations of R
MESSAGE(STATUS "Checking whether we should link against Rlapack library")
FIND_LIBRARY(LIBR_LAPACK
Rlapack
PATHS ${R_SHAREDLIBDIR}
NO_DEFAULT_PATH)
IF(NOT LIBR_LAPACK)
MESSAGE(STATUS "No, it does not exist in ${R_SHAREDLIBDIR}")
ELSE(NOT LIBR_LAPACK)
MESSAGE(STATUS "Yes, ${LIBR_LAPACK} exists")
SET(R_USED_LIBS ${R_USED_LIBS} Rlapack)
IF(WIN32 OR APPLE)
ELSE(WIN32 OR APPLE)
# needed when linking to Rlapack on linux for some unknown reason.
# apparently not needed on windows (let's see, when it comes back to bite us, though)
# and compiling on windows is hard enough even without requiring libgfortran, too.
SET(R_USED_LIBS ${R_USED_LIBS} gfortran)
ENDIF(WIN32 OR APPLE)
ENDIF(NOT LIBR_LAPACK)
# for at least some versions of R, we seem to have to link against -lRlapack. Else loading some
# R packages will fail due to unresolved symbols, or we can't link against -lR.
# However, we can't do this unconditionally,
# as this is not available in some configurations of R
MESSAGE(STATUS "Checking whether we should link against Rblas library")
FIND_LIBRARY(LIBR_BLAS
Rblas
PATHS ${R_SHAREDLIBDIR}
NO_DEFAULT_PATH)
IF(NOT LIBR_BLAS)
MESSAGE(STATUS "No, it does not exist in ${R_SHAREDLIBDIR}")
ELSE(NOT LIBR_BLAS)
MESSAGE(STATUS "Yes, ${LIBR_BLAS} exists")
SET(R_USED_LIBS ${R_USED_LIBS} Rblas)
ENDIF(NOT LIBR_BLAS)
# find R package library location
IF(WIN32)
SET(PATH_SEP ";")
ELSE(WIN32)
SET(PATH_SEP ":")
ENDIF(WIN32)
MESSAGE(STATUS "Checking for R package library location to use")
IF(NOT R_LIBDIR)
EXECUTE_PROCESS(
COMMAND ${R_EXECUTABLE} "--slave" "--no-save" "-e" "cat(paste(unique (c(.Library.site, .Library)), collapse='${PATH_SEP}'))"
OUTPUT_VARIABLE R_LIBDIR)
ELSE(NOT R_LIBDIR)
MESSAGE(STATUS "Location specified by user")
ENDIF(NOT R_LIBDIR)
# strip whitespace
STRING(REGEX REPLACE "[ \n]+"
"" R_LIBDIR
"${R_LIBDIR}")
# strip leading colon(s)
STRING(REGEX REPLACE "^${PATH_SEP}+"
"" R_LIBDIR
"${R_LIBDIR}")
# strip trailing colon(s)
STRING(REGEX REPLACE "${PATH_SEP}+$"
"" R_LIBDIR
"${R_LIBDIR}")
# find first path
STRING(REGEX REPLACE "${PATH_SEP}"
" " R_LIBDIR
"${R_LIBDIR}")
IF(NOT R_LIBDIR)
MESSAGE(STATUS "Not reliably determined or specified. Guessing.")
SET(R_LIBDIR ${R_HOME}/library)
ENDIF(NOT R_LIBDIR)
SET(R_LIBDIRS ${R_LIBDIR})
SEPARATE_ARGUMENTS(R_LIBDIRS)
SET(R_LIBDIR)
FOREACH(CURRENTDIR ${R_LIBDIRS})
IF(NOT USE_R_LIBDIR)
IF(EXISTS ${CURRENTDIR})
SET(R_LIBDIR ${CURRENTDIR})
SET(USE_R_LIBDIR 1)
ELSE(EXISTS ${CURRENTDIR})
MESSAGE(STATUS "${CURRENTDIR} does not exist. Skipping")
ENDIF(EXISTS ${CURRENTDIR})
ENDIF(NOT USE_R_LIBDIR)
ENDFOREACH(CURRENTDIR ${R_LIBDIRS})
IF(NOT EXISTS ${R_LIBDIR})
MESSAGE(FATAL_ERROR "No existing library location found")
ELSE(NOT EXISTS ${R_LIBDIR})
MESSAGE(STATUS "Will use ${R_LIBDIR}")
ENDIF(NOT EXISTS ${R_LIBDIR})
endif()
#macro_optional_find_package (R ON)
if (R_INCLUDEDIR AND R_LIBDIR)
add_feature_info(R yes "Real")
set (REAL_SOURCES
real.c
)
set (REAL_PL
real.pl
)
add_to_group( REAL_PL pl_library)
include_directories ( include_directories (
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
${R_INCLUDEDIR} ${R_INCLUDE_DIR}
) )
list (APPEND CMAKE_REQUIRED_INCLUDES list (APPEND CMAKE_REQUIRED_INCLUDES
@ -251,12 +44,8 @@ include_directories (
${R_INCLUDE_DIR} ${R_INCLUDE_DIR}
) )
add_lib(real ${REAL_SOURCES})
link_directories(${R_LIBDIR})
target_link_libraries (real R libYap)
check_include_files( "stdio.h;R.h" HAVE_R_H ) check_include_files( "stdio.h;R.h" HAVE_R_H )
check_include_files( "R.h;Rembedded.h" HAVE_R_EMBEDDED_H ) check_include_files( "R.h,;Rembedded.h" HAVE_R_EMBEDDED_H )
check_include_files( "Rembedded.h;Rinterface.h" HAVE_R_INTERFACE_H ) check_include_files( "Rembedded.h;Rinterface.h" HAVE_R_INTERFACE_H )
configure_file ("rconfig.h.cmake" "rconfig.h" ) configure_file ("rconfig.h.cmake" "rconfig.h" )

View File

@ -63,8 +63,8 @@ Solver::Solver() :
Solver::~Solver() Solver::~Solver()
{ {
for (int i = 0; i < learnts.size(); i++) free(learnts[i]); for (int i = 0; i < learnts.size(); i++) std::free(learnts[i]);
for (int i = 0; i < clauses.size(); i++) free(clauses[i]); for (int i = 0; i < clauses.size(); i++) std::free(clauses[i]);
} }
@ -163,7 +163,7 @@ void Solver::detachClause(Clause& c) {
void Solver::removeClause(Clause& c) { void Solver::removeClause(Clause& c) {
detachClause(c); detachClause(c);
free(&c); } std::free(&c); }
bool Solver::satisfied(const Clause& c) const { bool Solver::satisfied(const Clause& c) const {

View File

@ -147,7 +147,7 @@ template<class V>
Clause* Clause_new(const V& ps, bool learnt) { Clause* Clause_new(const V& ps, bool learnt) {
assert(sizeof(Lit) == sizeof(uint32_t)); assert(sizeof(Lit) == sizeof(uint32_t));
assert(sizeof(float) == sizeof(uint32_t)); assert(sizeof(float) == sizeof(uint32_t));
void* mem = malloc(sizeof(Clause) + sizeof(uint32_t)*(ps.size())); void* mem = std::malloc(sizeof(Clause) + sizeof(uint32_t)*(ps.size()));
return new (mem) Clause(ps, learnt); } return new (mem) Clause(ps, learnt); }
/*_________________________________________________________________________________________________ /*_________________________________________________________________________________________________
| |

View File

@ -27,7 +27,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
//================================================================================================= //=================================================================================================
// Automatically resizable arrays // Automatically resizable arrays
// //
// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc) // NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with std::realloc)
template<class T> template<class T>
class vec { class vec {
@ -79,9 +79,9 @@ public:
// Stack interface: // Stack interface:
#if 1 #if 1
void push (void) { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)realloc(data, cap * sizeof(T)); } new (&data[sz]) T(); sz++; } void push (void) { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)std::realloc(data, cap * sizeof(T)); } new (&data[sz]) T(); sz++; }
//void push (const T& elem) { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)realloc(data, cap * sizeof(T)); } new (&data[sz]) T(elem); sz++; } //void push (const T& elem) { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)std::realloc(data, cap * sizeof(T)); } new (&data[sz]) T(elem); sz++; }
void push (const T& elem) { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)realloc(data, cap * sizeof(T)); } data[sz++] = elem; } void push (const T& elem) { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)std::realloc(data, cap * sizeof(T)); } data[sz++] = elem; }
void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; } void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; }
#else #else
void push (void) { if (sz == cap) grow(sz+1); new (&data[sz]) T() ; sz++; } void push (void) { if (sz == cap) grow(sz+1); new (&data[sz]) T() ; sz++; }
@ -106,7 +106,7 @@ void vec<T>::grow(int min_cap) {
if (min_cap <= cap) return; if (min_cap <= cap) return;
if (cap == 0) cap = (min_cap >= 2) ? min_cap : 2; if (cap == 0) cap = (min_cap >= 2) ? min_cap : 2;
else do cap = (cap*3+1) >> 1; while (cap < min_cap); else do cap = (cap*3+1) >> 1; while (cap < min_cap);
data = (T*)realloc(data, cap * sizeof(T)); } data = (T*)std::realloc(data, cap * sizeof(T)); }
template<class T> template<class T>
void vec<T>::growTo(int size, const T& pad) { void vec<T>::growTo(int size, const T& pad) {
@ -127,7 +127,7 @@ void vec<T>::clear(bool dealloc) {
if (data != NULL){ if (data != NULL){
for (int i = 0; i < sz; i++) data[i].~T(); for (int i = 0; i < sz; i++) data[i].~T();
sz = 0; sz = 0;
if (dealloc) free(data), data = NULL, cap = 0; } } if (dealloc) std::free(data), data = NULL, cap = 0; } }
#endif #endif

View File

@ -82,11 +82,12 @@
@addtogroup YAPControl @addtogroup YAPControl
@ingroup builtins
%% @{
*/ */
%% @{
/** @pred forall(: _Cond_,: _Action_) /** @pred forall(: _Cond_,: _Action_)