#include "defns.i" #include "extern.i" InitialiseTrainingSet(R) /* --------------------- */ Relation R; { int i, j, Size; Tuple Case, *Scan; if ( InitialTrainingSet ) Discard(InitialTrainingSet, true); if ( TrainingSet ) { Discard(TrainingSet, true); free(Bits); } MaxVar = R->Arity; Size = (MaxVar+1) * sizeof(Const); ForEach(i, 1, MaxVar) { VarType[i] = R->Type[i]; } if ( R->Neg ) { /* Simply copy pos and neg tuples */ Pos = Number(R->Pos); Tot = Number(R->Neg) + Pos; TrainingSet = (Tuple *) malloc((Tot+1) * sizeof(Tuple)); Tot = 0; for ( Scan = R->Pos ; *Scan ; Scan++ ) { TrainingSet[Tot] = (Tuple) malloc(Size); memcpy(TrainingSet[Tot], *Scan, Size); TrainingSet[Tot][0] = Tot | PosMark; Tot++; } for ( Scan = R->Neg ; *Scan ; Scan++ ) { TrainingSet[Tot] = (Tuple) malloc(Size); memcpy(TrainingSet[Tot], *Scan, Size); TrainingSet[Tot][0] = Tot; Tot++; } } else { Pos = Tot = 0; NewSize = 1000; TrainingSet = (Tuple *) malloc((NewSize+1) * sizeof(Tuple)); Case = Nil; while ( (Case = NextConstTuple(R, Case)) ) { CheckSize(Tot, 1, &TrainingSet); if ( Join(R->Pos, R->PosIndex, DefVars, Case, MaxVar, true) ) { *Case = Tot | PosMark; Pos++; } else { *Case = Tot; } TrainingSet[Tot] = (Tuple) malloc(Size); memcpy(TrainingSet[Tot], Case, Size); Tot++; } TrainingSet = (Tuples) Resize(TrainingSet, (Tot+1) * sizeof(Tuple)); } TrainingSet[InitialTot = Tot] = Nil; ForEach(i, 1, R->Arity) { VarDepth[i] = 0; } InitialBaseInfo = BaseInfo = Info(Pos, Tot); Bits = malloc(InitialTot); InitialTrainingSet = (Tuples) malloc((Tot+1) * sizeof(Tuple)); memcpy(InitialTrainingSet, TrainingSet, (Tot+1) * sizeof(Tuple)); } /* Filter and expand the training set on a condition. Update Tot, Pos, and BaseInfo */ /* This routine has now been split into two: form the new training set, and accept it (i.e. update all counts, partial orderings etc */ Tuple *NewTS; int NewMaxVar, NewPos, NewPosCovered, NewTot, NewTotCovered; float OldBaseInfo; Boolean AllCovered; NewTrainingSet(R, RSign, A) /* -------------- */ Relation R; Boolean RSign; Vars A; { FormNewTrainingSet(R, RSign, A); AcceptNewTrainingSet(); } FormNewTrainingSet(R, RSign, A) /* ------------------ */ Relation R; Boolean RSign; Vars A; { Tuple *TSP, Case, *Bindings, Instance, Extend(); int i, j, N, MaxDepth = 0; AllCovered = true; OldBaseInfo = BaseInfo; N = R->Arity; NewMaxVar = MaxVar; if ( RSign ) { ForEach(i, 1, N) { if ( A[i] > MaxVar ) { VarType[A[i]] = R->Type[i]; NewMaxVar = Max(A[i], NewMaxVar); } else { MaxDepth = Max(MaxDepth, VarDepth[A[i]]); } } } MaxDepth++; ForEach(i, 1, N) { if ( A[i] > MaxVar ) { VarDepth[A[i]] = MaxDepth; } } if ( ! NewSize ) { NewSize = NewTot; } NewTS = (Tuple *) malloc((NewSize+1) * sizeof(Tuple)); NewTot = NewPos = NewTotCovered = NewPosCovered = 0; ClearBits; for ( TSP = TrainingSet ; Case = *TSP++ ; ) { if ( RSign ) { /* Add tuples from R->Pos */ if ( Join(R->Pos, R->PosIndex, A, Case, N, false) ) { CheckSize(NewTot, NFound, &NewTS); Bindings = Found; while ( Instance = *Bindings++ ) { NewTS[NewTot] = Extend(Case, Instance, A, N, NewMaxVar); NewTot++; if ( Positive(Case) ) NewPos++; } CheckCover(Case); } else AllCovered = false; /* Check for tuples from R->Opt */ if ( USEOPT && R->Opt ) { if ( Join(R->Opt, R->OptIndex, A, Case, N, false) ) { CheckSize(NewTot, NFound, &NewTS); Bindings = Found; while ( Instance = *Bindings++ ) { NewTS[NewTot] = Extend(Case, Instance, A, N, NewMaxVar); NewTot++; if ( Positive(Case) ) NewPos++; } CheckCover(Case); } } } else if ( ! Join(R->Pos, R->PosIndex, A, Case, N, true) ) { CheckSize(NewTot, 1, &NewTS); NewTS[NewTot] = (Tuple) malloc((MaxVar+1) * sizeof(int)); memcpy(NewTS[NewTot], Case, (MaxVar+1) * sizeof(int)); NewTot++; if ( Positive(Case) ) NewPos++; CheckCover(Case); } else AllCovered = false; } NewTS[NewTot] = Nil; } AcceptNewTrainingSet() /* -------------------- */ { Pos = NewPos; Tot = NewTot; PosCovered = NewPosCovered; TotCovered = NewTotCovered; if ( TrainingSet != CopyTrainingSet ) Discard(TrainingSet, true); MaxVar = NewMaxVar; TrainingSet = NewTS; if ( Tot < NewSize ) { TrainingSet = (Tuple *) Resize(NewTS, (Tot+1) * sizeof(Tuple)); } BaseInfo = Info(Pos, Tot); if ( AllCovered || BaseInfo >= OldBaseInfo ) { WeakLiterals++; VERBOSE(3) printf("\tNow %d weak literals in sequence\n", WeakLiterals); } else { WeakLiterals = 0; } DiscoverPartialOrders(); } CheckCover(Case) /* ---------- */ Tuple Case; { if ( ! TestBit(Case[0]&Mask, TrueBit) ) { SetBit(Case[0]&Mask, TrueBit); NewTotCovered++; if ( Positive(Case) ) NewPosCovered++; } } CheckSize(SoFar, Extra, TSAddr) /* --------- */ int SoFar, Extra; Tuples *TSAddr; { if ( SoFar+Extra > NewSize ) { NewSize += Max(Extra, 1000); *TSAddr = (Tuple *) Resize(*TSAddr, (NewSize+1) * sizeof(Tuple)); } } /* Tack extra variables on a tuple */ Tuple Extend(Case, Binding, A, N, NewMaxVar) /* ------ */ Tuple Case, Binding; Vars A; int N, NewMaxVar; { Tuple New; int i; New = (Tuple) malloc((NewMaxVar+1) * sizeof(int)); memcpy(New, Case, (MaxVar+1) * sizeof(int)); ForEach(i, 1, N) { New[A[i]] = Binding[i]; } return New; } /* Discover relevant partial orders in training set */ DiscoverPartialOrders() /* --------------------- */ { short *Seq, RHSSeq; Var LHSVar, RHSVar; Boolean OK; Tuple *Scan; ForEach(LHSVar, 1, Target->Arity) { Seq = Type[Target->Type[LHSVar]]->CollSeq; ForEach(RHSVar, Target->Arity+1, MaxVar) { if ( ! PartialOrder[RHSVar][LHSVar] ) { OK = true; for ( Scan = TrainingSet ; OK && *Scan ; Scan++ ) { OK = (RHSSeq = Seq[(*Scan)[RHSVar]]) && RHSSeq < Seq[(*Scan)[LHSVar]]; } if ( OK ) { PartialOrder[RHSVar][LHSVar] = AnyPartialOrder = true; VERBOSE(2) printf("\tNote %c<%c\n", Variable[RHSVar], Variable[LHSVar]); } } } } } /* Rebuild a training set by applying the literals in a clause to the copy of the training set */ RecoverTrainingSet(C) /* ------------------ */ Clause C; { Discard(TrainingSet, true); TrainingSet = CopyTrainingSet; BaseInfo = InitialBaseInfo; MaxVar = Target->Arity; WeakLiterals = 0; memset(PartialOrder, false, (MAXARITY+1)*(MAXARITY+1)); AnyPartialOrder = false; while ( *C ) { NewSize = 0; NewTrainingSet((*C)->Rel, (*C)->Sign, (*C)->Args); /*ExtractPartialOrders((*C)->Rel, (*C)->Sign, (*C)->Args);*/ C++; } } /* Generate in Case the next constant tuple (taking note of type constraints if TYPEFILTER is in effect */ Tuple NextConstTuple(R, Case) /* -------------- */ Relation R; Tuple Case; { int i, v; TypeInfo T; if ( TYPEFILTER ) { if ( ! Case ) { Case = (Tuple) malloc((R->Arity+1) * sizeof(Const)); ForEach(i, 1, R->Arity) { Case[i] = Type[R->Type[i]]->Value[0]; } } else { i = R->Arity; T = Type[R->Type[i]]; while ( Case[i] >= T->Value[T->NValues-1] ) { if ( i <= 1 ) { free(Case); return Nil; } Case[i] = T->Value[0]; T = Type[R->Type[--i]]; } for ( v = 1; Case[i] >= T->Value[v] ; v++ ) ; Case[i] = T->Value[v]; } } else { if ( ! Case ) { Case = (Tuple) malloc((R->Arity+1) * sizeof(Const)); ForEach(i, 1, R->Arity) { Case[i] = 1; } } else { i = R->Arity; while ( Case[i] >= MaxConst ) { if ( i <= 1 ) { free(Case); return Nil; } Case[i--] = 1; } Case[i]++; } } return Case; }