Merge branch 'master' of ssh://yap.git.sourceforge.net/gitroot/yap/yap-6.3

This commit is contained in:
Tiago Gomes 2012-12-13 23:48:16 +00:00
commit 971b8b7487
14 changed files with 100 additions and 101 deletions

View File

@ -2252,7 +2252,7 @@ Yap_absmi(int inp)
PREG = NEXTOP(NEXTOP(NEXTOP(PREG, s),Osbpp),l);
/* assume cut is always in stack */
saveregs();
prune((choiceptr)YREG[E_CB]);
prune((choiceptr)YREG[E_CB] PASS_REGS);
setregs();
GONext();
ENDOp();
@ -2271,7 +2271,7 @@ Yap_absmi(int inp)
SET_ASP(YREG, PREG->u.s.s);
/* assume cut is always in stack */
saveregs();
prune((choiceptr)YREG[E_CB]);
prune((choiceptr)YREG[E_CB] PASS_REGS);
setregs();
PREG = NEXTOP(NEXTOP(NEXTOP(PREG, s),Osbpp),l);
GONext();
@ -2290,7 +2290,7 @@ Yap_absmi(int inp)
SET_ASP(YREG, PREG->u.s.s);
PREG = NEXTOP(NEXTOP(NEXTOP(PREG, s),Osbpp),l);
saveregs();
prune((choiceptr)SREG[E_CB]);
prune((choiceptr)SREG[E_CB] PASS_REGS);
setregs();
GONext();
ENDOp();
@ -2343,7 +2343,7 @@ Yap_absmi(int inp)
pt0 = (choiceptr)(LCL0-IntegerOfTerm(d0));
#endif /* YAPOR_SBA && FROZEN_STACKS */
saveregs();
prune(pt0);
prune(pt0 PASS_REGS);
setregs();
}
GONext();
@ -2379,7 +2379,7 @@ Yap_absmi(int inp)
pt0 = (choiceptr)(LCL0-IntegerOfTerm(d0));
#endif
saveregs();
prune(pt0);
prune(pt0 PASS_REGS);
setregs();
}
GONext();
@ -13080,7 +13080,7 @@ Yap_absmi(int inp)
if (pen->FunctorOfPred == (Functor)AtomCut) {
if (b_ptr != B) {
saveregs();
prune(b_ptr);
prune(b_ptr PASS_REGS);
setregs();
}
}

View File

@ -245,23 +245,24 @@ Yap_FreeAtomSpace(char *p)
/* If you need to dinamically allocate space from the heap, this is
* the macro you should use */
ADDR
Yap_InitPreAllocCodeSpace(void)
Yap_InitPreAllocCodeSpace(int wid)
{
CACHE_REGS
char *ptr;
UInt sz = LOCAL_ScratchPad.msz;
if (LOCAL_ScratchPad.ptr == NULL) {
UInt sz = REMOTE_ScratchPad(wid).msz;
if (REMOTE_ScratchPad(wid).ptr == NULL) {
#if USE_DL_MALLOC
LOCK(DLMallocLock);
#endif
LOCAL_PrologMode |= MallocMode;
REMOTE_PrologMode(wid) |= MallocMode;
#if INSTRUMENT_MALLOC
mallocs++;
tmalloc += sz;
sz += sizeof(CELL);
#endif
while (!(ptr = my_malloc(sz))) {
LOCAL_PrologMode &= ~MallocMode;
REMOTE_PrologMode(wid) &= ~MallocMode;
#if USE_DL_MALLOC
UNLOCK(DLMallocLock);
#endif
@ -277,18 +278,18 @@ Yap_InitPreAllocCodeSpace(void)
#if USE_DL_MALLOC
LOCK(DLMallocLock);
#endif
LOCAL_PrologMode |= MallocMode;
REMOTE_PrologMode(wid) |= MallocMode;
}
LOCAL_PrologMode &= ~MallocMode;
REMOTE_PrologMode(wid) &= ~MallocMode;
#if USE_DL_MALLOC
UNLOCK(DLMallocLock);
#endif
LOCAL_ScratchPad.ptr = ptr;
REMOTE_ScratchPad(wid).ptr = ptr;
} else {
ptr = LOCAL_ScratchPad.ptr;
ptr = REMOTE_ScratchPad(wid).ptr;
}
AuxBase = (ADDR)(ptr);
AuxSp = (CELL *)(AuxTop = AuxBase+LOCAL_ScratchPad.sz);
AuxSp = (CELL *)(AuxTop = AuxBase+REMOTE_ScratchPad(wid).sz);
return ptr;
}
@ -352,7 +353,7 @@ Yap_InitHeap(void *heap_addr)
}
static void
InitExStacks(int Trail, int Stack)
InitExStacks(int wid, int Trail, int Stack)
{
CACHE_REGS
UInt pm, sa;
@ -367,23 +368,24 @@ InitExStacks(int Trail, int Stack)
sa = Stack*K; /* stack area size */
#ifdef THREADS
if (worker_id)
LOCAL_GlobalBase = (ADDR)LOCAL_ThreadHandle.stack_address;
#endif
LOCAL_TrailTop = LOCAL_GlobalBase + pm;
LOCAL_LocalBase = LOCAL_GlobalBase + sa;
LOCAL_TrailBase = LOCAL_LocalBase + sizeof(CELL);
LOCAL_ScratchPad.ptr = NULL;
LOCAL_ScratchPad.sz = LOCAL_ScratchPad.msz = SCRATCH_START_SIZE;
if (wid)
REMOTE_GlobalBase(wid) = (ADDR)REMOTE_ThreadHandle(wid).stack_address;
else
AuxSp = NULL;
#endif
REMOTE_TrailTop(wid) = REMOTE_GlobalBase(wid) + pm;
REMOTE_LocalBase(wid) = REMOTE_GlobalBase(wid) + sa;
REMOTE_TrailBase(wid) = REMOTE_LocalBase(wid) + sizeof(CELL);
REMOTE_ScratchPad(wid).ptr = NULL;
REMOTE_ScratchPad(wid).sz = REMOTE_ScratchPad(wid).msz = SCRATCH_START_SIZE;
#ifdef DEBUG
if (Yap_output_msg) {
UInt ta;
fprintf(stderr, "HeapBase = %p GlobalBase = %p\n LocalBase = %p TrailTop = %p\n",
Yap_HeapBase, LOCAL_GlobalBase, LOCAL_LocalBase, LOCAL_TrailTop);
Yap_HeapBase, REMOTE_GlobalBase(wid), REMOTE_LocalBase(wid), REMOTE_TrailTop(wid));
ta = Trail*K; /* trail area size */
fprintf(stderr, "Heap+Aux: %lu\tLocal+Global: %lu\tTrail: %lu\n",
@ -393,9 +395,9 @@ InitExStacks(int Trail, int Stack)
}
void
Yap_InitExStacks(int Trail, int Stack)
Yap_InitExStacks(int wid, int Trail, int Stack)
{
InitExStacks(Trail, Stack);
InitExStacks(wid, Trail, Stack);
}
#if defined(THREADS)
@ -1557,11 +1559,11 @@ Yap_InitMemory(UInt Trail, UInt Heap, UInt Stack)
}
void
Yap_InitExStacks(int Trail, int Stack)
Yap_InitExStacks(int wid, int Trail, int Stack)
{
#if USE_DL_MALLOC
LOCAL_ScratchPad.ptr = NULL;
LOCAL_ScratchPad.sz = LOCAL_ScratchPad.msz = SCRATCH_START_SIZE;
REMOTE_ScratchPad(wid).ptr = NULL;
REMOTE_ScratchPad(wid).sz = REMOTE_ScratchPad(wid).msz = SCRATCH_START_SIZE;
AuxSp = NULL;
#endif
}

View File

@ -2699,12 +2699,12 @@ X_API void
YAP_ClearExceptions(void)
{
CACHE_REGS
Yap_ResetExceptionTerm();
if (EX) {
LOCAL_BallTerm = EX;
}
EX = NULL;
Yap_ResetExceptionTerm();
Yap_ResetExceptionTerm( 0 );
LOCAL_UncaughtThrow = FALSE;
}
@ -3065,13 +3065,13 @@ YAP_Init(YAP_init_args *yap_init)
GLOBAL_AllowGlobalExpansion = TRUE;
GLOBAL_AllowLocalExpansion = TRUE;
GLOBAL_AllowTrailExpansion = TRUE;
Yap_InitExStacks (Trail, Stack);
Yap_InitExStacks (0, Trail, Stack);
if (yap_init->QuietMode) {
yap_flags[QUIET_MODE_FLAG] = TRUE;
}
{ BACKUP_MACHINE_REGS();
Yap_InitYaamRegs( 0);
Yap_InitYaamRegs( 0 );
#if HAVE_MPE
Yap_InitMPE ();
@ -3111,10 +3111,10 @@ YAP_Init(YAP_init_args *yap_init)
In the SBA we cannot just happily inherit registers
from the other workers
*/
Yap_InitYaamRegs( 0);
Yap_InitYaamRegs( 0 );
#endif /* YAPOR_COPY || YAPOR_SBA */
#ifndef YAPOR_THREADS
Yap_InitPreAllocCodeSpace();
Yap_InitPreAllocCodeSpace( 0 );
#endif /* YAPOR_THREADS */
/* slaves, waiting for work */
CurrentModule = USER_MODULE;

View File

@ -4,9 +4,9 @@
#include "cut_c.h"
#include <stdio.h>
void cut_c_initialize(void){
void cut_c_initialize(int wid){
CACHE_REGS
Yap_REGS.CUT_C_TOP=(cut_c_str_ptr)LOCAL_LocalBase;
Yap_REGS.CUT_C_TOP=(cut_c_str_ptr)REMOTE_LocalBase(wid);
}
/*Removes a choice_point from the stack*/

View File

@ -1723,25 +1723,22 @@ Yap_InitYaamRegs( int myworker_id )
machine registers */
#ifdef THREADS
CACHE_REGS
int wid = worker_id;
if (wid != myworker_id) {
if (myworker_id) {
pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(myworker_id).default_yaam_regs);
REFRESH_CACHE_REGS
REMOTE_ThreadHandle(myworker_id).current_yaam_regs = REMOTE_ThreadHandle(myworker_id).default_yaam_regs;
worker_id = myworker_id;
REFRESH_CACHE_REGS
}
/* may be run by worker_id on behalf on myworker_id */
#else
Yap_regp = &Yap_standard_regs;
#endif
#endif /* PUSH_REGS */
Yap_ResetExceptionTerm ();
Yap_ResetExceptionTerm ( myworker_id );
Yap_PutValue (AtomBreak, MkIntTerm (0));
TR = (tr_fr_ptr)LOCAL_TrailBase;
H = H0 = ((CELL *) REMOTE_GlobalBase(wid));
RESET_VARIABLE(H0-1);
LCL0 = ASP = (CELL *) REMOTE_LocalBase(wid);
CurrentTrailTop = (tr_fr_ptr)(REMOTE_TrailTop(wid)-MinTrailGap);
TR = (tr_fr_ptr)REMOTE_TrailBase(myworker_id);
H = H0 = ((CELL *) REMOTE_GlobalBase(myworker_id));
LCL0 = ASP = (CELL *) REMOTE_LocalBase(myworker_id);
CurrentTrailTop = (tr_fr_ptr)(REMOTE_TrailTop(myworker_id)-MinTrailGap);
/* notice that an initial choice-point and environment
*must* be created since for the garbage collector to work */
B = NULL;
@ -1756,49 +1753,46 @@ Yap_InitYaamRegs( int myworker_id )
#ifdef YAPOR_SBA
BSEG =
#endif /* YAPOR_SBA */
BBREG = B_FZ = (choiceptr) REMOTE_LocalBase(wid);
TR = TR_FZ = (tr_fr_ptr) REMOTE_TrailBase(wid);
BBREG = B_FZ = (choiceptr) REMOTE_LocalBase(myworker_id);
TR = TR_FZ = (tr_fr_ptr) REMOTE_TrailBase(myworker_id);
#endif /* FROZEN_STACKS */
LOCK(REMOTE_SignalLock(wid));
LOCK(REMOTE_SignalLock(myworker_id));
CreepFlag = CalculateStackGap();
UNLOCK(REMOTE_SignalLock(wid));
UNLOCK(REMOTE_SignalLock(myworker_id));
EX = NULL;
init_stack(0, NULL, TRUE, NULL PASS_REGS);
/* the first real choice-point will also have AP=FAIL */
/* always have an empty slots for people to use */
CurSlot = 0;
Yap_StartSlots( PASS_REGS1 );
REMOTE_GlobalArena(wid) = TermNil;
REMOTE_GlobalArena(myworker_id) = TermNil;
h0var = MkVarTerm();
#ifdef THREADS
LOCAL = REMOTE(myworker_id);
#endif /* THREADS */
#if COROUTINING
REMOTE_WokenGoals(wid) = Yap_NewTimedVar(TermNil);
REMOTE_AttsMutableList(wid) = Yap_NewTimedVar(h0var);
REMOTE_WokenGoals(myworker_id) = Yap_NewTimedVar(TermNil);
REMOTE_AttsMutableList(myworker_id) = Yap_NewTimedVar(h0var);
#endif
REMOTE_GcGeneration(wid) = Yap_NewTimedVar(h0var);
REMOTE_GcCurrentPhase(wid) = 0L;
REMOTE_GcPhase(wid) = Yap_NewTimedVar(MkIntTerm(REMOTE_GcCurrentPhase(wid)));
REMOTE_GcGeneration(myworker_id) = Yap_NewTimedVar(h0var);
REMOTE_GcCurrentPhase(myworker_id) = 0L;
REMOTE_GcPhase(myworker_id) = Yap_NewTimedVar(MkIntTerm(REMOTE_GcCurrentPhase(myworker_id)));
#if defined(YAPOR) || defined(THREADS)
PP = NULL;
PREG_ADDR = NULL;
#endif
Yap_AllocateDefaultArena(128*1024, 2);
Yap_InitPreAllocCodeSpace();
Yap_AllocateDefaultArena(128*1024, 2, myworker_id);
Yap_InitPreAllocCodeSpace( myworker_id );
#ifdef CUT_C
cut_c_initialize();
cut_c_initialize( myworker_id );
#endif
#if defined MYDDAS_MYSQL || defined MYDDAS_ODBC
Yap_REGS.MYDDAS_GLOBAL_POINTER = NULL;
#endif
#ifdef TABLING
/* ensure that LOCAL_top_dep_fr is always valid */
if (REMOTE_top_dep_fr(wid))
DepFr_cons_cp(REMOTE_top_dep_fr(wid)) = NORM_CP(B);
#endif
#ifdef THREADS
worker_id = wid;
if (myworker_id != worker_id) {
pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(worker_id).default_yaam_regs);
}
if (REMOTE_top_dep_fr(myworker_id))
DepFr_cons_cp(REMOTE_top_dep_fr(myworker_id)) = NORM_CP(B);
#endif
}
@ -1886,11 +1880,10 @@ p_reset_exception( USES_REGS1 )
}
void
Yap_ResetExceptionTerm(void)
Yap_ResetExceptionTerm(int wid)
{
CACHE_REGS
Yap_ReleaseTermFromDB(LOCAL_BallTerm);
LOCAL_BallTerm = NULL;
Yap_ReleaseTermFromDB(REMOTE_BallTerm(wid));
REMOTE_BallTerm(wid) = NULL;
}
static Int

View File

@ -151,10 +151,10 @@ p_default_arena_size( USES_REGS1 )
void
Yap_AllocateDefaultArena(Int gsize, Int attsize)
Yap_AllocateDefaultArena(Int gsize, Int attsize, int wid)
{
CACHE_REGS
LOCAL_GlobalArena = NewArena(gsize, 2, NULL PASS_REGS);
REMOTE_GlobalArena(wid) = NewArena(gsize, 2, NULL PASS_REGS);
}
static void

View File

@ -1794,7 +1794,7 @@ Restore(char *s, char *lib_dir USES_REGS)
Yap_InitSysPath();
#if USE_DL_MALLOC || USE_SYSTEM_MALLOC
if (!AuxSp) {
Yap_InitPreAllocCodeSpace();
Yap_InitPreAllocCodeSpace( 0 );
}
#endif
CloseRestore();

View File

@ -230,15 +230,11 @@ setup_engine(int myworker_id, int init_thread)
regcache = standard_regs;
/* create the YAAM descriptor */
REMOTE_ThreadHandle(myworker_id).default_yaam_regs = standard_regs;
if (init_thread) {
pthread_setspecific(Yap_yaamregs_key, (void *)REMOTE_ThreadHandle(myworker_id).default_yaam_regs);
}
worker_id = myworker_id;
LOCAL = REMOTE(worker_id);
Yap_InitExStacks(REMOTE_ThreadHandle(myworker_id).tsize, REMOTE_ThreadHandle(myworker_id).ssize);
Yap_InitExStacks(myworker_id, REMOTE_ThreadHandle(myworker_id).tsize, REMOTE_ThreadHandle(myworker_id).ssize);
CurrentModule = REMOTE_ThreadHandle(myworker_id).cmod;
Yap_InitTime( myworker_id );
Yap_InitYaamRegs( myworker_id );
REFRESH_CACHE_REGS
Yap_ReleasePreAllocCodeSpace(Yap_PreAllocCodeSpace());
/* I exist */
GLOBAL_NOfThreadsCreated++;
@ -254,7 +250,11 @@ setup_engine(int myworker_id, int init_thread)
static void
start_thread(int myworker_id)
{
setup_engine(myworker_id, TRUE);
CACHE_REGS
pthread_setspecific(Yap_yaamregs_key, (void *)REMOTE_ThreadHandle(myworker_id).default_yaam_regs);
REFRESH_CACHE_REGS;
worker_id = myworker_id;
LOCAL = REMOTE(myworker_id);
}
static void *
@ -267,13 +267,14 @@ thread_run(void *widp)
#ifdef OUTPUT_THREADS_TABLING
char thread_name[25];
char filename[YAP_FILENAME_MAX];
sprintf(thread_name, "/thread_output_%d", myworker_id);
strcpy(filename, YAP_BINDIR);
strncat(filename, thread_name, 25);
LOCAL_thread_output = fopen(filename, "w");
REMOTE_thread_output(myworker_id) = fopen(filename, "w");
#endif /* OUTPUT_THREADS_TABLING */
start_thread(myworker_id);
regcache = ((REGSTORE *)pthread_getspecific(Yap_yaamregs_key));
REFRESH_CACHE_REGS;
do {
t = tgs[0] = Yap_PopTermFromDB(LOCAL_ThreadHandle.tgoal);
if (t == 0) {
@ -328,7 +329,8 @@ p_create_thread( USES_REGS1 )
Term x2 = Deref(ARG2);
Term x3 = Deref(ARG3);
Term x4 = Deref(ARG4);
int new_worker_id = IntegerOfTerm(Deref(ARG7));
int new_worker_id = IntegerOfTerm(Deref(ARG7)),
owid = worker_id;
// fprintf(stderr," %d --> %d\n", worker_id, new_worker_id);
if (IsBigIntTerm(x2))
@ -349,10 +351,13 @@ p_create_thread( USES_REGS1 )
//REMOTE_ThreadHandle(new_worker_id).pthread_handle = 0L;
REMOTE_ThreadHandle(new_worker_id).id = new_worker_id;
REMOTE_ThreadHandle(new_worker_id).ref_count = 1;
setup_engine(new_worker_id, FALSE);
if ((REMOTE_ThreadHandle(new_worker_id).ret = pthread_create(&REMOTE_ThreadHandle(new_worker_id).pthread_handle, NULL, thread_run, (void *)(&(REMOTE_ThreadHandle(new_worker_id).id)))) == 0) {
pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(owid).current_yaam_regs);
/* wait until the client is initialised */
return TRUE;
}
pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(owid).current_yaam_regs);
return FALSE;
}
@ -493,6 +498,7 @@ Yap_thread_create_engine(thread_attr *ops)
Int
Yap_thread_attach_engine(int wid)
{
CACHE_REGS
/*
already locked
pthread_mutex_lock(&(REMOTE_ThreadHandle(wid).tlock));
@ -506,9 +512,8 @@ Yap_thread_attach_engine(int wid)
}
REMOTE_ThreadHandle(wid).pthread_handle = pthread_self();
REMOTE_ThreadHandle(wid).ref_count++;
pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(wid).default_yaam_regs);
CACHE_REGS
worker_id = wid; /* ricroc: for what I understand, this shouldn't be necessary */
pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(wid).current_yaam_regs);
REFRESH_CACHE_REGS;
DEBUG_TLOCK_ACCESS(9, wid);
pthread_mutex_unlock(&(REMOTE_ThreadHandle(wid).tlock));
return TRUE;

View File

@ -4694,7 +4694,7 @@ static Int numbervars_in_complex_term(register CELL *pt0, register CELL *pt0_end
goto loop;
}
prune(B);
prune(B PASS_REGS);
Yap_ReleasePreAllocCodeSpace((ADDR)to_visit0);
return numbv;

View File

@ -220,7 +220,7 @@ UInt STD_PROTO(Yap_givemallinfo, (void));
ADDR STD_PROTO(Yap_ExpandPreAllocCodeSpace, (UInt, void *, int));
#define Yap_ReleasePreAllocCodeSpace(x)
ADDR STD_PROTO(Yap_InitPreAllocCodeSpace, (void));
ADDR STD_PROTO(Yap_InitPreAllocCodeSpace, (int));
#include "inline-only.h"
INLINE_ONLY EXTERN inline ADDR

View File

@ -91,7 +91,7 @@ int STD_PROTO(Yap_ExtendWorkSpace,(Int));
void STD_PROTO(Yap_FreeAtomSpace,(char *));
int STD_PROTO(Yap_FreeWorkSpace, (void));
void STD_PROTO(Yap_InitMemory,(UInt,UInt,UInt));
void STD_PROTO(Yap_InitExStacks,(int,int));
void STD_PROTO(Yap_InitExStacks,(int,int,int));
/* amasm.c */
OPCODE STD_PROTO(Yap_opcode,(op_numbers));
@ -177,7 +177,7 @@ Term STD_PROTO(Yap_ExecuteCallMetaCall,(Term));
void STD_PROTO(Yap_InitExecFs,(void));
Int STD_PROTO(Yap_JumpToEnv,(Term));
Term STD_PROTO(Yap_RunTopGoal,(Term));
void STD_PROTO(Yap_ResetExceptionTerm,(void));
void STD_PROTO(Yap_ResetExceptionTerm,(int));
Int STD_PROTO(Yap_execute_goal,(Term, int, Term));
Int STD_PROTO(Yap_exec_absmi,(int));
void STD_PROTO(Yap_trust_last,(void));
@ -200,7 +200,7 @@ void STD_PROTO(Yap_InitGlobals,(void));
Term STD_PROTO(Yap_SaveTerm, (Term));
Term STD_PROTO(Yap_SetGlobalVal, (Atom, Term));
Int STD_PROTO(Yap_DeleteGlobal, (Atom));
void STD_PROTO(Yap_AllocateDefaultArena, (Int, Int));
void STD_PROTO(Yap_AllocateDefaultArena, (Int, Int, int));
/* grow.c */
Int STD_PROTO(Yap_total_stack_shift_time,(void));

View File

@ -1546,9 +1546,8 @@ Yap_regtoregno(wamreg reg)
#endif
static inline void
prune(choiceptr cp)
prune(choiceptr cp USES_REGS)
{
CACHE_REGS
#ifdef YAPOR
CUT_prune_to(cp);
#endif /* YAPOR */

View File

@ -46,7 +46,7 @@ struct cut_c_str{
/*Initializes CUT_C_TOP*/
void cut_c_initialize(void);
void cut_c_initialize(int wid );
/*Removes a choice_point from the stack*/
void cut_c_pop(void);

View File

@ -109,7 +109,7 @@ collect(Keys, Factors) :-
queue_in(K) :-
queue(K), !.
queue_in(K) :-
%writeln(+K),
% writeln(q+K),
assert(queue(K)),
fail.
queue_in(_).
@ -139,7 +139,7 @@ do_propagate(_K) :-
propagate.
add_factor(factor(Type, Id, Ks, _, _Phi, Constraints), NKs) :-
%writeln(+Ks),
% writeln(+Ks),
( Ks = [K,Els], var(Els)
->
% aggregate factor
@ -147,7 +147,7 @@ add_factor(factor(Type, Id, Ks, _, _Phi, Constraints), NKs) :-
avg_factors(K, Els, 0.0, NewKeys, NewId),
NKs = [K|NewKeys]
;
once(run(Constraints)),
run(Constraints),
NKs = Ks,
Id = NewId
),