resultat = true;
} else if (IdPred.equals("maximalJoin") || IdPred.equals("generalize")
|| IdPred.equals("subsume")) {
// CGOper(G1, C1, G2, C2, G3, C3) or subsume(G1, C1, G2, C2)
// CGOper(G1, G2, G3) or subsume(G1, G2)
CG G1;
// CGOper(G1, C1, G2, C2, G3, C3) or subsume(G1, C1, G2, C2)
// CGOper(G1, G2, G3) or subsume(G1, G2)
CG G2;
// CGOper(G1, C1, G2, C2, G3, C3) or subsume(G1, C1, G2, C2)
// CGOper(G1, G2, G3) or subsume(G1, G2)
CG G3 = null;
int nivG1 = 0;
int nivG2 = 0;
Concept C1 = null;
Concept C2 = null;
PrologData DonRes = null;
PrologData DonResBis = null;
ASSERT(
((pTermRes.pTerm.size() == 7)
|| (pTermRes.pTerm.size() == 4)
|| ((pTermRes.pTerm.size() == 5) && IdPred
.equals("subsume")) || ((pTermRes.pTerm
.size() == 3) && IdPred.equals("subsume"))),
"Error: Wrong number of arguments for the CG operation.\n");
if ((pTermRes.pTerm.size() == 7) || (pTermRes.pTerm.size() == 5)) {
// presence des points d'entree
Arg1 = env.unification.valueFromUnifStack(pTermRes.pTerm
.getAt(1), pTermRes.index);
ASSERT(
((Arg1.pData != null) && (Arg1.pData.typeOfData == uCG)),
"Error: the first argument of the CG operation must be a CG.\n");
G1 = (CG) Arg1.pData.data;
nivG1 = Arg1.index;
Arg2 = env.unification.valueFromUnifStack(pTermRes.pTerm
.getAt(2), pTermRes.index);
if ((Arg2.pData != null) && (Arg2.pData.typeOfData == uConcept)) {
C1 = (Concept) Arg2.pData.data;
} else {
ASSERT(false,
"Error: The second argument of the CG operation should be a concept.\n");
}
PrologDataIndexPair Arg3 = env.unification.valueFromUnifStack(
pTermRes.pTerm.getAt(3), pTermRes.index);
ASSERT(
((Arg3.pData != null) && (Arg3.pData.typeOfData == uCG)),
"Error: the third argument of the CG operation must be a CG.\n");
G2 = (CG) Arg3.pData.data;
nivG2 = Arg3.index;
PrologDataIndexPair Arg4 = env.unification.valueFromUnifStack(
pTermRes.pTerm.getAt(4), pTermRes.index);
if ((Arg4.pData != null) && (Arg4.pData.typeOfData == uConcept)) {
C2 = (Concept) Arg4.pData.data;
} else {
ASSERT(false,
"Error: The fourth argument of the CG operation should be a concept.\n");
}
if (pTermRes.pTerm.size() == 7) {
PrologDataIndexPair Arg5 = env.unification
.valueFromUnifStack(pTermRes.pTerm.getAt(5),
pTermRes.index);
ASSERT((Arg5.pData == null),
"Error: the fifth argument of the CG operation must be a free variable.\n");
G3 = new CG();
DonRes = pTermRes.pTerm.getAt(5);
PrologDataIndexPair Arg6 = env.unification
.valueFromUnifStack(pTermRes.pTerm.getAt(6),
pTermRes.index);
ASSERT((Arg6.pData == null),
"Error: the sixth argument of the CG operation must be a free variable.\n");
DonResBis = pTermRes.pTerm.getAt(6);
}
} else { // les cas : CGOper(G1, G2, G3) or subsume(G1, G2)
Arg1 = env.unification.valueFromUnifStack(pTermRes.pTerm
.getAt(1), pTermRes.index);
ASSERT(
((Arg1.pData != null) && (Arg1.pData.typeOfData == uCG)),
"Error: the first argument of the CG operation must be a CG.\n");
G1 = (CG) Arg1.pData.data;
nivG1 = Arg1.index;
Arg2 = env.unification.valueFromUnifStack(pTermRes.pTerm
.getAt(2), pTermRes.index);
ASSERT(
((Arg2.pData != null) && (Arg2.pData.typeOfData == uCG)),
"Error: the second argument of the CG operation must be a CG.\n");
G2 = (CG) Arg2.pData.data;
nivG2 = Arg2.index;
if (pTermRes.pTerm.size() == 4) {
PrologDataIndexPair Arg3 = env.unification
.valueFromUnifStack(pTermRes.pTerm.getAt(3),
pTermRes.index);
ASSERT((Arg3.pData == null),
"Error: the third argument of the CG operation must be a free variable.\n");
G3 = new CG();
DonRes = pTermRes.pTerm.getAt(3);
}
}
// Les arguments sont a present prets, en tenant compte des
// differentes posibilites
// Appel de l'operation de matching matchCG
CGMatchResult resMatchCG = new CGMatchResult(G3, null);
CGOperation uneOperGC = new CGOperation(env);
resultat = uneOperGC.matchCG(CGOperation.convertToByte(IdPred, G3),
C1, G1, nivG1, C2, G2, nivG2, resMatchCG);
uneOperGC.corefMatchVec_MakeEmpty();
uneOperGC = null;
env.unification.Unif_Stack.pushEmptyRecord();
if (resultat && (DonRes != null)) {
PrologData donTmp = new PrologData(uCG, resMatchCG.G3);
resultat = env.unification.unify(DonRes, pTermRes.index,
donTmp, pTermRes.index);
}
if (resultat && (DonResBis != null)) {
resultat = env.unification
.unify(DonResBis, pTermRes.index, new PrologData(
uConcept, resMatchCG.E3), pTermRes.index);
}
if (resultat) {
pTermRes.pos = -1;
Return_Stack.push(Exec_Stack.pop());
} else {
if (resMatchCG.G3 != null) {
resMatchCG.G3.myDestroy();
}
if (resMatchCG.E3 != null) {
resMatchCG.E3 = null;
}
env.unification.Unif_Stack.pop();
}
resMatchCG = null;
} else if (IdPred.equals("length")) {
ASSERT((pTermRes.pTerm.size() == 3),
"Error: length takes two arguments.\n");
Arg1 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(1),
pTermRes.index);
ASSERT(((Arg1.pData != null) && (Arg1.pData.typeOfData == uList)),
"Error: The first argument of length must be a list.\n");
Arg2 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(2),
pTermRes.index);
ASSERT(
((Arg2.pData == null) || (Arg2.pData.typeOfData == uNumber)),
"Error: The second argument of length must be an integer or a free variable.\n");
pLstPrlg = (PrologList) Arg1.pData.data;
int taille = 0;
if (pLstPrlg != null) {
taille = pLstPrlg.size();
PrologDataIndexPair ValVarList = null;
PrologData uneDonTmp = null;
boolean finished = false;
int Arg1Niv = Arg1.index;
while (!finished) {
try {
uneDonTmp = (PrologData) pLstPrlg.lastElement();
} catch (NoSuchElementException nsex) {
// This could possibly happen
}
if (uneDonTmp.typeOfData == uVarList) {
ValVarList = env.unification.valueFromUnifStack(
uneDonTmp, Arg1Niv);
Arg1Niv = ValVarList.index;
if ((ValVarList.pData != null)
&& (ValVarList.pData.typeOfData != uList)) {
throw new ExecException(
"The value of the variable after | should be a list.\n");
} else if (ValVarList.pData != null) {
pLstPrlg = (PrologList) ValVarList.pData.data;
taille--; // decremente la taille de -1 car |x ne
// doit pas etre compte
if (pLstPrlg == null) {
finished = true;
} else {
taille = taille + pLstPrlg.size();
}
} else {
throw new ExecException(
"Warning : The length of the list can not be determined since it is partially specified; the variable after | is free.\n");
}
} else {
finished = true;
}
}
}
env.unification.Unif_Stack.pushEmptyRecord();
resultat = env.unification.unify(new PrologData(uNumber,
new Long(taille)), pTermRes.index, pTermRes.pTerm
.getAt(2), pTermRes.index);
if (resultat) {
pTermRes.pos = -1;
Return_Stack.push(Exec_Stack.pop());
} else {
env.unification.Unif_Stack.pop();
}
} else if (IdPred.equals("stringToLetters")
|| IdPred.equals("identToLetters")) {
byte typeMot = 0;
if (IdPred.equals("stringToLetters")) {
typeMot = uString;
} else {
typeMot = uIdentifier;
}
ASSERT((pTermRes.pTerm.size() == 3), "Error: " + IdPred
+ " takes two arguments.\n");
Arg1 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(1),
pTermRes.index);
ASSERT(
((Arg1.pData == null) || (Arg1.pData.typeOfData == typeMot)),
"Error: The first argument of " + IdPred
+ " must be a string/ident or a free variable.\n");
Arg2 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(2),
pTermRes.index);
ASSERT(((Arg2.pData == null) || (Arg2.pData.typeOfData == uList)),
"Error: The second argument of " + IdPred
+ " must be a list or a free variable.\n");
ASSERT(((Arg1.pData != null) || (Arg2.pData != null)),
"Error: At least one of the two arguments of " + IdPred
+ " must be bound.\n");
if (Arg1.pData != null) { // le mot est fourni, passer au cars
String mot = (String) Arg1.pData.data;
// Construire la liste des lettres qui compose la chaine
// String.valueOf(char) ==> String
int tailleMot = mot.length();
int i = 0;
if (IdPred.equals("stringToLetters")) {
// Ignorer les doubles quotes du string
i++;
tailleMot--;
}
String carToString = null;
pLstPrlg = new PrologList();
PrologData uneDon;
for (; i < tailleMot; i++) {
carToString = "\"" + String.valueOf(mot.charAt(i)) + "\"";
uneDon = new PrologData(uString, carToString);
pLstPrlg.addData(uneDon);
}
env.unification.Unif_Stack.pushEmptyRecord();
uneDon = new PrologData(uList, pLstPrlg);
resultat = env.unification.unify(uneDon, pTermRes.index,
pTermRes.pTerm.getAt(2), pTermRes.index);
} else { // le mot n'est pas fourni, le composer
// La liste des cars est fournie
// 1. Former un vecteur de char ? partir de la liste des
// chaines/cars
// 2. Former le mot ? partir du vecteur form? pr?c?demment
pLstPrlg = (PrologList) Arg2.pData.data;
pLstPrlg = copyAllOfTheListWithUnification(pLstPrlg, Arg2.index);
int tailleVect = pLstPrlg.size();
int i = 0;
char[] vectCars = null;
if (IdPred.equals("stringToLetters")) {
tailleVect = tailleVect + 2;
vectCars = new char[tailleVect];
vectCars[0] = '\"';
vectCars[tailleVect - 1] = '\"';
i = 1;
} else {
vectCars = new char[tailleVect];
}
PrologData uneDon;
String s = null;
for (Enumeration<PrologData> e = pLstPrlg.elements(); e
.hasMoreElements(); i++) {
uneDon = (PrologData) e.nextElement();
s = (String) uneDon.data;
vectCars[i] = s.charAt(1);
}
String mot = new String(vectCars);
uneDon = new PrologData(typeMot, mot);
env.unification.Unif_Stack.pushEmptyRecord();
resultat = env.unification.unify(pTermRes.pTerm.getAt(1),
pTermRes.index, uneDon, pTermRes.index);
}
if (resultat) {
pTermRes.pos = -1;
Return_Stack.push(Exec_Stack.pop());
} else {
env.unification.Unif_Stack.pop();
}
} else if (IdPred.equals("concat")) {
ASSERT((pTermRes.pTerm.size() == 4), "Error: " + IdPred
+ " takes three arguments.\n");
Arg1 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(1),
pTermRes.index);
ASSERT(
((Arg1.pData == null) || (typeIsPrimitive(Arg1.pData.typeOfData))),
"Error: The first argument of " + IdPred
+ " must be a number, a boolean, an identifier, a string, or a free variable.\n");
int nNoOfFreeArguments = 0;
if (Arg1.pData == null) {
nNoOfFreeArguments++;
}
Arg2 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(2),
pTermRes.index);
ASSERT(
((Arg2.pData == null) || (typeIsPrimitive(Arg2.pData.typeOfData))),
"Error: The second argument of " + IdPred
+ " must be a number, a boolean, an identifier, a string, or a free variable.\n");
if (Arg2.pData == null) {
nNoOfFreeArguments++;
}
PrologDataIndexPair Arg3 = env.unification.valueFromUnifStack(
pTermRes.pTerm.getAt(3), pTermRes.index);
ASSERT(
((Arg3.pData == null) || (Arg3.pData.typeOfData == uString)),
"Error: The third argument of " + IdPred
+ " must be a string or a free variable.\n");
if (Arg3.pData == null) {
nNoOfFreeArguments++;
}
ASSERT(
(nNoOfFreeArguments == 1) || (nNoOfFreeArguments == 0),
"Error: "
+ IdPred
+ " must have either two or three bound arguments.\n");
if (Arg3.pData == null || nNoOfFreeArguments == 0) {
// We are concat'ing the easy case of Arg1 + Arg2
String s1 = primitiveTypeToString(Arg1.pData);
String s2 = primitiveTypeToString(Arg2.pData);
String s3 = "\"" + s1.substring(1, s1.length() - 1)
+ s2.substring(1, s2.length() - 1) + "\"";
PrologData uneDon = new PrologData(uString, s3);
env.unification.Unif_Stack.pushEmptyRecord();
resultat = env.unification.unify(uneDon, pTermRes.index,
pTermRes.pTerm.getAt(3), pTermRes.index);
} else if (Arg2.pData == null) {
// Arg3 is not null, and nNoOfArguments == 1
String s1 = primitiveTypeToString(Arg1.pData);
String s3 = primitiveTypeToString(Arg3.pData);
String s1stripped = s1.substring(1, s1.length() - 1);
String s3stripped = s3.substring(1, s3.length() - 1);
resultat = s3stripped.startsWith(s1stripped);
if (!resultat) {
env.unification.Unif_Stack.pushEmptyRecord();
} else {
int s1strippedLength = s1stripped.length();
String s2 = "\""
+ s3stripped.substring(s1strippedLength, s3stripped
.length()) + "\"";
PrologData uneDon = new PrologData(uString, s2);
env.unification.Unif_Stack.pushEmptyRecord();
resultat = env.unification.unify(uneDon, pTermRes.index,
pTermRes.pTerm.getAt(2), pTermRes.index);
}
} else {
// Arg1.pDonnee is null, and nNoOfFreeArguments == 1
String s2 = primitiveTypeToString(Arg2.pData);
String s3 = primitiveTypeToString(Arg3.pData);
String s2stripped = s2.substring(1, s2.length() - 1);
String s3stripped = s3.substring(1, s3.length() - 1);
resultat = s3stripped.endsWith(s2stripped);
if (!resultat) {
env.unification.Unif_Stack.pushEmptyRecord();
} else {
int s2strippedLength = s2stripped.length();
String s1 = "\""
+ s3stripped.substring(0, s3stripped.length()
- s2strippedLength) + "\"";
PrologData uneDon = new PrologData(uString, s1);
env.unification.Unif_Stack.pushEmptyRecord();
resultat = env.unification.unify(uneDon, pTermRes.index,
pTermRes.pTerm.getAt(1), pTermRes.index);
}
}
if (resultat) {
pTermRes.pos = -1;
Return_Stack.push(Exec_Stack.pop());
} else {
env.unification.Unif_Stack.pop();
}
} else if (IdPred.equals("branchOfCG")) { // branchOfCG(CG_Branch, CG)
// on le traitera de la meme maniere que member : on parcourt le CG,
// similaire en cela a une liste de branchs
// et on tentera d'unifier notre branch arg1 avec la branch courante
// dans CG
// branchOfCG must have two arguments
ASSERT((pTermRes.pTerm.size() == 3),
"Error: branchOfCG takes two arguments.\n");
Arg2 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(2),
pTermRes.index);
ASSERT(((Arg2.pData != null) && (Arg2.pData.typeOfData == uCG)),
"Error: The second argument of branchOfCG must be a CG.\n");
CG unGC = (CG) Arg2.pData.data;
Vector<Relation> vctRels = unGC.m_vctRelations;
int nbreBranch = vctRels.size();
while ((pTermRes.pos < nbreBranch) && !resultat) {
env.unification.Unif_Stack.pushEmptyRecord();
// Creer un CG a partir de la branche/relation courante dans le
// CG arg2
// Remplir branchCadre
CG unGCBranch = createCGBranch((Relation) vctRels
.elementAt(pTermRes.pos));
// Inverser les arg de unifier comme pour la primitive "eq"
resultat = env.unification.unify(
new PrologData(uCG, unGCBranch), Arg2.index,
pTermRes.pTerm.getAt(1), pTermRes.index);
pTermRes.pos++;
if (resultat) {
Return_Stack.push(Exec_Stack.pop());
} else {
env.unification.Unif_Stack.pop();
}
}
} else if (IdPred.equals("concOfCG")) { // concOfCG(ConceptOUVar, CG)
ASSERT((pTermRes.pTerm.size() == 3),
"Error: concOfCG takes two arguments.\n");
Arg2 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(2),
pTermRes.index);
ASSERT(((Arg2.pData != null) && (Arg2.pData.typeOfData == uCG)),
"Error: The second argument of concOfCG must be a CG.\n");
CG unGC = (CG) Arg2.pData.data;
Vector<Concept> vctConcepts = unGC.m_vctConcepts;
int nbreConcs = vctConcepts.size();
resultat = false;
Arg1 = env.unification.valueFromUnifStack(pTermRes.pTerm.getAt(1),
pTermRes.index);
while ((pTermRes.pos < nbreConcs) && !resultat) {
env.unification.Unif_Stack.pushEmptyRecord();
Concept concCour = (Concept) vctConcepts
.elementAt(pTermRes.pos);
// Is Arg1 a free variable?
if (Arg1.pData == null) {
// Yes, it was a free variable.
// Therefore, we don't transform it to a CG,
// since otherwise, we will unify the whole CG.
// Inverser les arg de unifier comme pour la primitive "eq"
resultat = env.unification.unify(new PrologData(uConcept,
concCour), Arg2.index, pTermRes.pTerm.getAt(1),
pTermRes.index);
} else {
// No, it was not a free variable.
// Therefore, there is no harm done in making it a CG.
// Make a CG out of the concept.
// This is because env.unification.unifier does not do the
// special variable-substitution magic on uConcept.
CG gTmp = new CG();
gTmp.addConcept(concCour);
// Inverser les arg de unifier comme pour la primitive "eq"
resultat = env.unification
.unify(new PrologData(uCG, gTmp), Arg2.index,
pTermRes.pTerm.getAt(1), pTermRes.index);