fix atomic_concat/3 to be backtrackable.
This commit is contained in:
parent
1a56819658
commit
a64c6772fc
100
C/atomic.c
100
C/atomic.c
@ -658,28 +658,101 @@ init_atom_concat3( USES_REGS1 )
|
|||||||
cut_fail();
|
cut_fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CastToAtom(x) CastToAtom__(x PASS_REGS)
|
||||||
|
|
||||||
|
static Term
|
||||||
|
CastToAtom__(Term t USES_REGS)
|
||||||
|
{
|
||||||
|
if (IsAtomTerm(t))
|
||||||
|
return t;
|
||||||
|
return MkAtomTerm(Yap_AtomicToAtom( t PASS_REGS));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CastToNumeric(x) CastToNumeric__(x PASS_REGS)
|
||||||
|
|
||||||
|
static Term
|
||||||
|
CastToNumeric__(Atom at USES_REGS)
|
||||||
|
{
|
||||||
|
Term t;
|
||||||
|
if ((t = Yap_AtomToNumber( MkAtomTerm( at ) PASS_REGS) ) )
|
||||||
|
return t;
|
||||||
|
return MkAtomTerm(at);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
p_atomic_concat3( USES_REGS1 )
|
cont_atomic_concat3( USES_REGS1 )
|
||||||
|
{
|
||||||
|
Term t3;
|
||||||
|
Atom ats[2];
|
||||||
|
size_t i, max;
|
||||||
|
restart_aux:
|
||||||
|
t3 = Deref(ARG3);
|
||||||
|
i = IntOfTerm(EXTRA_CBACK_ARG(3,1));
|
||||||
|
max = IntOfTerm(EXTRA_CBACK_ARG(3,2));
|
||||||
|
EXTRA_CBACK_ARG(3,1) = MkIntTerm(i+1);
|
||||||
|
if ( ! Yap_SpliceAtom( t3, ats, i, max PASS_REGS ) ) {
|
||||||
|
cut_fail();
|
||||||
|
} else {
|
||||||
|
Term t1 = CastToNumeric(ats[0]);
|
||||||
|
Term t2 = CastToNumeric(ats[1]);
|
||||||
|
if (i < max) return Yap_unify( ARG1, t1) &&
|
||||||
|
Yap_unify( ARG2, t2) ;
|
||||||
|
if (Yap_unify( ARG1, t1) &&
|
||||||
|
Yap_unify( ARG2, t2)) cut_succeed();
|
||||||
|
cut_fail();
|
||||||
|
}
|
||||||
|
/* Error handling */
|
||||||
|
if (LOCAL_Error_TYPE) {
|
||||||
|
if (Yap_HandleError( "string_concat/3" )) {
|
||||||
|
goto restart_aux;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cut_fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Int
|
||||||
|
init_atomic_concat3( USES_REGS1 )
|
||||||
{
|
{
|
||||||
Term t1;
|
Term t1;
|
||||||
Term t2;
|
Term t2, t3, ot;
|
||||||
Term t;
|
|
||||||
Atom at;
|
Atom at;
|
||||||
restart_aux:
|
restart_aux:
|
||||||
t1 = Deref(ARG1);
|
t1 = Deref(ARG1);
|
||||||
t2 = Deref(ARG2);
|
t2 = Deref(ARG2);
|
||||||
at = Yap_ConcatAtomics( t1, t2 PASS_REGS );
|
t3 = Deref(ARG3);
|
||||||
|
if (Yap_IsGroundTerm(t1) && Yap_IsGroundTerm(t2)) {
|
||||||
|
at = Yap_ConcatAtoms( CastToAtom(t1), CastToAtom(t2) PASS_REGS );
|
||||||
|
ot = ARG3;
|
||||||
|
} else if (Yap_IsGroundTerm(t1) && Yap_IsGroundTerm(t3) ) {
|
||||||
|
at = Yap_SubtractHeadAtom( t3, CastToAtom(t1) PASS_REGS );
|
||||||
|
ot = ARG2;
|
||||||
|
} else if (Yap_IsGroundTerm(t2) && Yap_IsGroundTerm(t3)) {
|
||||||
|
at = Yap_SubtractTailAtom( t3, CastToAtom(t2) PASS_REGS );
|
||||||
|
ot = ARG1;
|
||||||
|
} else {
|
||||||
|
EXTRA_CBACK_ARG(3,1) = MkIntTerm(0);
|
||||||
|
EXTRA_CBACK_ARG(3,2) = MkIntTerm(Yap_AtomicToLength(t3 PASS_REGS));
|
||||||
|
return cont_atomic_concat3( PASS_REGS1 );
|
||||||
|
}
|
||||||
if (at) {
|
if (at) {
|
||||||
t = MkAtomTerm(at);
|
if (Yap_unify(ot, CastToNumeric(at))) cut_succeed();
|
||||||
return Yap_unify(ARG3, t);
|
else cut_fail();
|
||||||
}
|
}
|
||||||
/* Error handling */
|
/* Error handling */
|
||||||
if (LOCAL_Error_TYPE && Yap_HandleError( "atomic_concat/3" )) {
|
if (LOCAL_Error_TYPE) {
|
||||||
goto restart_aux;
|
if (Yap_HandleError( "atomic_concat/3" )) {
|
||||||
|
goto restart_aux;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
cut_fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
cont_string_concat3( USES_REGS1 )
|
cont_string_concat3( USES_REGS1 )
|
||||||
{
|
{
|
||||||
@ -695,9 +768,9 @@ cont_string_concat3( USES_REGS1 )
|
|||||||
cut_fail();
|
cut_fail();
|
||||||
} else {
|
} else {
|
||||||
if (i < max) return Yap_unify( ARG1, ts[0]) &&
|
if (i < max) return Yap_unify( ARG1, ts[0]) &&
|
||||||
Yap_unify( ARG2, ts[1]) ;
|
Yap_unify( ARG2, ts[1]) ;
|
||||||
if (Yap_unify( ARG1, ts[0]) &&
|
if (Yap_unify( ARG1, ts[0]) &&
|
||||||
Yap_unify( ARG2, ts[1])) cut_succeed();
|
Yap_unify( ARG2, ts[1])) cut_succeed();
|
||||||
cut_fail();
|
cut_fail();
|
||||||
}
|
}
|
||||||
/* Error handling */
|
/* Error handling */
|
||||||
@ -712,7 +785,7 @@ cont_string_concat3( USES_REGS1 )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
init_string_concat3( USES_REGS1 )
|
init_string_concat3( USES_REGS1 )
|
||||||
{
|
{
|
||||||
Term t1;
|
Term t1;
|
||||||
@ -751,6 +824,7 @@ init_string_concat3( USES_REGS1 )
|
|||||||
cut_fail();
|
cut_fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
cont_string_code3( USES_REGS1 )
|
cont_string_code3( USES_REGS1 )
|
||||||
{
|
{
|
||||||
@ -2086,6 +2160,7 @@ Yap_InitBackAtoms(void)
|
|||||||
Yap_InitCPredBack("$current_atom", 1, 2, init_current_atom, cont_current_atom,SafePredFlag|SyncPredFlag);
|
Yap_InitCPredBack("$current_atom", 1, 2, init_current_atom, cont_current_atom,SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPredBack("$current_wide_atom", 1, 2, init_current_wide_atom,cont_current_wide_atom,SafePredFlag|SyncPredFlag);
|
Yap_InitCPredBack("$current_wide_atom", 1, 2, init_current_wide_atom,cont_current_wide_atom,SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPredBack("atom_concat", 3, 2, init_atom_concat3, cont_atom_concat3, 0);
|
Yap_InitCPredBack("atom_concat", 3, 2, init_atom_concat3, cont_atom_concat3, 0);
|
||||||
|
Yap_InitCPredBack("atomic_concat", 3, 2, init_atomic_concat3, cont_atomic_concat3, 0);
|
||||||
Yap_InitCPredBack("string_concat", 3, 2, init_string_concat3, cont_string_concat3, 0);
|
Yap_InitCPredBack("string_concat", 3, 2, init_string_concat3, cont_string_concat3, 0);
|
||||||
Yap_InitCPredBack("sub_atom", 5, 5, init_sub_atom, cont_sub_atomic, 0);
|
Yap_InitCPredBack("sub_atom", 5, 5, init_sub_atom, cont_sub_atomic, 0);
|
||||||
/** @pred sub_atom(+ _A_,? _Bef_, ? _Size_, ? _After_, ? _At_out_) is iso
|
/** @pred sub_atom(+ _A_,? _Bef_, ? _Size_, ? _After_, ? _At_out_) is iso
|
||||||
@ -2234,7 +2309,6 @@ atoms or numbers.
|
|||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Yap_InitCPred("atomic_concat", 3, p_atomic_concat3, 0);
|
|
||||||
Yap_InitCPred("atomics_to_string", 2, p_atomics_to_string2, 0);
|
Yap_InitCPred("atomics_to_string", 2, p_atomics_to_string2, 0);
|
||||||
Yap_InitCPred("atomics_to_string", 3, p_atomics_to_string3, 0);
|
Yap_InitCPred("atomics_to_string", 3, p_atomics_to_string3, 0);
|
||||||
Yap_InitCPred("get_string_code", 3, p_get_string_code3, 0);
|
Yap_InitCPred("get_string_code", 3, p_get_string_code3, 0);
|
||||||
|
12
H/YapText.h
12
H/YapText.h
@ -172,6 +172,18 @@ Yap_AtomicToListOfCodes(Term t0 USES_REGS)
|
|||||||
return out.val.t;
|
return out.val.t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Atom
|
||||||
|
Yap_AtomicToAtom(Term t0 USES_REGS)
|
||||||
|
{
|
||||||
|
seq_tv_t inp, out;
|
||||||
|
inp.val.t = t0;
|
||||||
|
inp.type = YAP_STRING_STRING|YAP_STRING_ATOM|YAP_STRING_INT|YAP_STRING_FLOAT|YAP_STRING_BIG|YAP_STRING_TERM;
|
||||||
|
out.type = YAP_STRING_ATOM;
|
||||||
|
if (!Yap_CVT_Text(&inp, &out PASS_REGS))
|
||||||
|
return 0L;
|
||||||
|
return out.val.a;
|
||||||
|
}
|
||||||
|
|
||||||
static inline size_t
|
static inline size_t
|
||||||
Yap_AtomToLength(Term t0 USES_REGS)
|
Yap_AtomToLength(Term t0 USES_REGS)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user