Package PrologPlusCG.prolog

Source Code of PrologPlusCG.prolog.UnifyCG

/**********************************************************************
*
* Prolog+CG : Prolog with conceptual graphs
*
* Copyright (C) 2000-2005  Adil Kabbaj
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*
* Website
* =======
*
* Prolog+CG has a website here:
*
* http://prologpluscg.sourceforge.net/
*
*
* Contact
* =======
*
* Please DO NOT send email to Prof. Kabbaj.  Instead, all
* correspondence regarding Prolog+CG should be sent to the current
* maintainter:
*
* Ulrik Petersen  <ulrikp{t-a}users{dot}sourceforge{|dot|}net
*
* (Email obfuscated to foil spammers).
*
*
* NO SUPPORT
* ==========
*
* Note that NEITHER Prof. KABBAJ NOR ULRIK PETERSEN WILL GIVE
* SUPPORT!  No support is available.
*
* If you need help in using Prolog+CG, please check out the resources
* available at:
*
* http://prologpluscg.sourceforge.net/docs.html
*
* That page points to ample resources for learning Prolog+CG.
*
*
* Bugreports
* ==========
*
* Notwithstanding the lack of support, the maintainer will gladly
* receive bugreports and bugfixes.  Please feel free to send such
* bulletins to the address given above.
*
*
*/


package PrologPlusCG.prolog;

import java.util.Enumeration;
import java.util.Vector;

import PrologPlusCG.cg.CG;
import PrologPlusCG.cg.Concept;
import PrologPlusCG.cg.Relation;
import PrologPlusCG.prolog.PPCGEnv;


public class UnifyCG implements DataTypes {
    final byte e_inComeBranch = 0;
    final byte e_outComeBranch = 1;
    Vector<ConceptUnification> CMatchL;
    Vector<RelationUnification> RMatchL;

    private PPCGEnv env = null;
   
    public UnifyCG(PPCGEnv myenv) {
      env = myenv;
        CMatchL = new Vector<ConceptUnification>();
        RMatchL = new Vector<RelationUnification>();
    }

    void CMatchL_MakeEmpty() {
        ConceptUnification aCMatch;

        for (Enumeration<ConceptUnification> e = CMatchL.elements(); e.hasMoreElements();) {
            aCMatch = (ConceptUnification) e.nextElement();
            aCMatch.myDestroy();
        }
    CMatchL.removeAllElements();
    }

    void RMatchL_MakeEmpty() {
        RelationUnification aRMatch;

        for (Enumeration<RelationUnification> e = RMatchL.elements(); e.hasMoreElements();) {
            aRMatch = (RelationUnification) e.nextElement();
            aRMatch.myDestroy();
        }
    RMatchL.removeAllElements();
    }

    // ------------------------------------------------------------------
    boolean sameNameRel(PrologData pDataLeft, PrologData pDataRight,
        int indexLeft, int indexRight) throws ExecException {
        // Traitement similaire a UnifyType
        // Considerer en premier le cas ou un des types est une variable
        PrologDataIndexPair valIndexLeft = env.unification.valueFromUnifStack(pDataLeft, indexLeft);
        PrologDataIndexPair valIndexRight = env.unification.valueFromUnifStack(pDataRight, indexRight);
        boolean bResult = true;

        if ((valIndexLeft.pData == null) && (valIndexRight.pData != null)) {
      // pDataLeft is a free variable and pDataRight is a value
            env.unification.addConstraint2(valIndexRight.pData, valIndexRight.index,
                (String) pDataLeft.data, indexLeft);
        } else if ((valIndexLeft.pData != null) && (valIndexRight.pData == null)) {
      // pDataLeft is a value and pDataRight is a free variable
            env.unification.addConstraint2(valIndexLeft.pData, valIndexLeft.index,
                (String) pDataRight.data, indexRight);
        } else if ((valIndexLeft.pData == null) && (valIndexRight.pData == null)) {
      // Both are free variables
            env.unification.addConstraint3((String) pDataLeft.data, indexLeft,
                (String) pDataRight.data, indexRight);
        } else {
      // Both data objects are particular types (values)

            Object pData1Left;
            Object pData1Right;
            pData1Left = valIndexLeft.pData.data;
            pData1Right = valIndexRight.pData.data;

            String strData1 = (String) pData1Left;
            String strData2 = (String) pData1Right;
            bResult = strData1.equals(strData2);
        }
        return bResult;
    }

    // --------------------------------------------------------------
    // G1 represente soit le but courant ou un arg du predicat-but courant
    // G2 represente soit la tete , soit un arg de la tete
    boolean UnifyGC(CG G1, int nivG1, CG G2, int nivG2)
        throws ExecException {
        boolean BRes = false;

        if ((G1.m_vctRelations.size() > G2.m_vctRelations.size()) ||
                !bagInclusion(G1.m_vctRelations, G2.m_vctRelations, nivG1, nivG2)) {
            BRes = false;
        } else {
            BRes = computeEntryPointsAndUnify(G1, nivG1, G2, nivG2);
        }

        env.unification.makeEmpty_vctContstraints();

        return BRes;
    }

    // ---------------------------------------------------------------
    boolean bagInclusion(Vector<Relation> lr1, Vector<Relation> lr2, int nivG1, int nivG2)
        throws ExecException {
        Vector<Relation> lst = new Vector<Relation>();
        Relation rla1 = null;
        Relation rla2 = null;
        boolean bFound;

        for (Enumeration<Relation> e = lr1.elements(); e.hasMoreElements();) {
            rla1 = (Relation) e.nextElement();
            bFound = false;

            for (Enumeration<Relation> e1 = lr2.elements();
                    e1.hasMoreElements() && !bFound;) {
                rla2 = (Relation) e1.nextElement();

                if (sameNameRel(rla1.m_pdRelationName, rla2.m_pdRelationName, nivG1, nivG2) &&
                        !lst.contains(rla2)) {
                    bFound = true;
                }
            }

            if (bFound) {
                lst.addElement(rla2);
            } else {
                lst.removeAllElements();
                lst = null;

                return false;
            }
        }

        lst.removeAllElements();
        lst = null;

        return true;
    }

    // ------------------------------------------------------------------
    boolean computeEntryPointsAndUnify(CG G1, int levelG1, CG G2, int levelG2)
        throws ExecException {
        boolean bResult = false;
        Concept C1;
        Concept C2;

        if ((G1.m_vctConcepts.size() == 1) && G1.m_vctRelations.isEmpty()) {
            C1 = (Concept) G1.m_vctConcepts.firstElement();

            for (Enumeration<Concept> e = G2.m_vctConcepts.elements();
                    e.hasMoreElements() && !bResult;) {
                C2 = (Concept) e.nextElement();
                bResult = UnifyConcept(C1, C2, levelG1, levelG2);

                if (!bResult) {
                    env.unification.removeConstraints();
                }
            }
        } else {
            Vector<Concept> vConcs = new Vector<Concept>(2);

            if (identRef(G1, levelG1, G2, levelG2, vConcs)) {
                C1 = (Concept) vConcs.firstElement();
                C2 = (Concept) vConcs.elementAt(1);
                bResult = unifyWithBack(C1, C2, null, null, G1, levelG1, levelG2);
                vConcs.removeAllElements();
                vConcs = null;
            } else {
                vConcs.removeAllElements(); // a cause de la creation inutile ici de vConcs

                Relation rl1 = (Relation) G1.m_vctRelations.firstElement();
                Relation rl2;

                for (Enumeration<Relation> e = G2.m_vctRelations.elements();
                        e.hasMoreElements() && !bResult;) {
                    rl2 = (Relation) e.nextElement();

                    if (sameNameRel(rl1.m_pdRelationName, rl2.m_pdRelationName, levelG1, levelG2)) {
                        bResult = unifyWithBack(rl1.m_concSource, rl2.m_concSource,
                                rl1.m_concDestination, rl2.m_concDestination,
                                G1, levelG1, levelG2);
                    }
                }
            }
        }

        CMatchL_MakeEmpty();
        RMatchL_MakeEmpty();

        return bResult;
    }

    // ------------------------------------------------------------------
    // ---- determine points d'entree par identite des referents ////
    public boolean identRef(CG G1, int nivG1, CG G2, int nivG2, Vector<Concept> vConcs) {
        Concept C1 = null;
        Concept C2 = null;
        String sRef1;
        Object sRef2;
        boolean bResult = false;

        // Premiere passe pour identifier un referent de G1 avec un ref de G2 ou
        // ... comme elem appartenant a un ensemble
        for (Enumeration<Concept> e = G1.m_vctConcepts.elements();
                e.hasMoreElements() && !bResult;) {
            C1 = (Concept) e.nextElement();
            sRef1 = individu(C1.m_pdReferent, nivG1);

            if (sRef1 != null) {
                for (Enumeration<Concept> e1 = G2.m_vctConcepts.elements();
                        e1.hasMoreElements() && !bResult;) {
                    C2 = (Concept) e1.nextElement();
                    sRef2 = individu2(C2.m_pdReferent, nivG2);

                    if ((sRef2 != null) && (sRef2 instanceof String)) {
                        bResult = sRef1.equals(sRef2);
                    } else if (sRef2 != null && sRef2 instanceof PrologList) {
                        bResult = env.compile.hasString(sRef1, (PrologList) sRef2);
                    }
                }
            }
        }

        if (!bResult) {
            // Seconde passe : on tentera de cherchera un referent-ensemble qui pourrait
            // s'unifier avec un ensemble correspondant
            PrologList ensRef1;

            // Seconde passe : on tentera de cherchera un referent-ensemble qui pourrait
            // s'unifier avec un ensemble correspondant
            PrologList ensRef2 = null;

            for (Enumeration<Concept> e = G1.m_vctConcepts.elements();
                    e.hasMoreElements() && !bResult;) {
                C1 = (Concept) e.nextElement();

                // individu3 cherche uniquement les referents-ensemble
                ensRef1 = individu3(C1.m_pdReferent, nivG1);

                if (ensRef1 != null) {
                    for (Enumeration<Concept> e1 = G2.m_vctConcepts.elements();
                            e1.hasMoreElements() && !bResult;) {
                        C2 = (Concept) e1.nextElement();
                        ensRef2 = individu3(C2.m_pdReferent, nivG2);

                        if (ensRef2 != null) {
                            bResult = env.compile.setsAreEqual(ensRef1, ensRef2);
                        }
                    }
                }
            }
        }

        if (bResult) {
            vConcs.addElement(C1);
            vConcs.addElement(C2);
        }

        return bResult;
    }

    // elle ne considere pas le cas d'un referent comme ensemble
    String individu(PrologData Ref, int ind) {
        if (Ref == null) {
            return null;
        }

        PrologDataIndexPair ValRef = env.unification.valueFromUnifStack(Ref, ind);

        if (ValRef.pData == null) {
            return null;
        } else if (ValRef.pData.data instanceof String) {
            return (String) ValRef.pData.data;
        } else {
            return null;
        }
    }

    // Elle tient compte aussi du cas ou le referent est un ensemble
    Object individu2(PrologData Ref, int ind) {
        if (Ref == null) {
            return null;
        }

        PrologDataIndexPair ValRef = env.unification.valueFromUnifStack(Ref, ind);

        if (ValRef.pData == null) {
            return null;
        } else {
            return ValRef.pData.data;
        }
    }

    PrologList individu3(PrologData Ref, int ind) {
        if (Ref == null) {
            return null;
        }

        PrologDataIndexPair ValRef = env.unification.valueFromUnifStack(Ref, ind);

        if (ValRef.pData == null) {
            return null;
        } else if (ValRef.pData.data instanceof PrologList) {
            return (PrologList) ValRef.pData.data;
        } else {
            return null;
        }
    }

    // ------------------------------------------------------------------
    boolean unifyWithBack(Concept Cs1, Concept Cs2, Concept Ct1, Concept Ct2,
        CG G1, int levelG1, int levelG2) throws ExecException {
        boolean bResult = UnifyConcept(Cs1, Cs2, levelG1, levelG2) &&
            ((Ct1 == null) || UnifyConcept(Ct1, Ct2, levelG1, levelG2)) &&
            propagateUnifyCG(G1, levelG1, levelG2);

        if (!bResult) {
            env.unification.removeConstraints();
        }

        CMatchL_MakeEmpty();
        RMatchL_MakeEmpty();

        return bResult;
    }

    // ------------------------------------------------------------------
    boolean propagateUnifyCG(CG G1, int nivG1, int nivG2)
        throws ExecException {
        boolean BRes = true;
        boolean trouve = true;

        while (BRes && trouve) {
            ConceptUnification E = null;
            trouve = false;

            /***  1. Trouver un couple de concepts dont l'unification locale
                             n'est pas encore effectuee      *****/
            for (Enumeration<ConceptUnification> e = CMatchL.elements();
                    e.hasMoreElements() && !trouve;) {
                E = (ConceptUnification) e.nextElement();
                trouve = (!E.m_MatchedLocally);
            }

            // Effectuer l'unification locale concernant le couple de concepts localise
            if (trouve) {
                BRes = UnifyBranchs(e_outComeBranch, E.m_ConcMatched1,
                        E.m_ConcMatched2, nivG1, nivG2) &&
                    UnifyBranchs(e_inComeBranch, E.m_ConcMatched1,
                        E.m_ConcMatched2, nivG1, nivG2);

                if (BRes) {
                    E.m_MatchedLocally = true;
                }
            }
        }

        return (BRes && postUnify(G1));
    }

    // ------------------------------------------------------------------
    boolean UnifyBranchs(byte BranchDirection, Concept C1, Concept C2,
        int nivG1, int nivG2) throws ExecException {
        boolean bResult = true;
        Relation rel1;
        boolean bAlreadyUnified;
        Vector<Relation> vRels1 = null;

        if (BranchDirection == e_inComeBranch) {
            vRels1 = C1.m_vctIncomingRelations;
        } else {
            vRels1 = C1.m_vctOutgoingRelations;
        }

        // Unifier toutes les branches de vRels1
        for (Enumeration<Relation> e = vRels1.elements(); e.hasMoreElements() && bResult;) {
            rel1 = (Relation) e.nextElement();
            bAlreadyUnified = false;

            RelationUnification E = null;

            for (Enumeration<RelationUnification> e1 = RMatchL.elements();
                    e1.hasMoreElements() && !bAlreadyUnified;) {
                E = (RelationUnification) e1.nextElement();
                bAlreadyUnified = (rel1 == E.m_RelMatched1);
            }

            if (!bAlreadyUnified) {
                bResult = UnifyTheBranch(BranchDirection, rel1, C2, nivG1,
                        nivG2);
            } else {
                bResult = unificationIsValid(BranchDirection, C2, E.m_RelMatched1,
                        E.m_RelMatched2);
            }
        }

        return bResult;
    }

    boolean unificationIsValid(byte BranchDirection, Concept C2,
        Relation rel1, Relation rel2) {
        Concept Ca1;
        Concept Ca2;
        boolean bResult = false;

        if (BranchDirection == e_inComeBranch) {
            Ca1 = rel1.m_concSource;
            Ca2 = rel2.m_concSource;
            bResult = (C2 == rel2.m_concDestination);
        } else {
            Ca1 = rel1.m_concDestination;
            Ca2 = rel2.m_concDestination;
            bResult = (C2 == rel2.m_concSource);
        }

        if (bResult) {
            ConceptUnification E = inCMatchL(Ca1, Ca2);

            /***  Verify that the pair (Ca1, Ca2) exists in concMatchVec *****/
            if (E != null) {
                bResult = ((E.m_ConcMatched1 == Ca1) && (E.m_ConcMatched2 == Ca2));
            } else {
                bResult = false;
            }
        }

        return bResult;
    }

    /***  Verify that the pair (Ca1, Ca2) exists in concMatchVec *****/
    ConceptUnification inCMatchL(Concept Ca1, Concept Ca2) {
        boolean BRes = false;
        ConceptUnification E = null;

        for (Enumeration<ConceptUnification> e = CMatchL.elements(); e.hasMoreElements() && !BRes;) {
            E = (ConceptUnification) e.nextElement();

            if ((E.m_ConcMatched1 == Ca1) || (E.m_ConcMatched2 == Ca2)) {
                BRes = true;
            }

            /*{
                  BRes = E.m_ConcMatched1 == Ca1 && E.m_ConcMatched2 == Ca2;
                  break;
            }; ***/
        }

        if (BRes) {
            return E;
        } else {
            return null;
        }
    }

    // ------------------------------------------------------------------
    boolean UnifyTheBranch(byte BranchDirection, Relation rel1, Concept C2,
        int nivG1, int nivG2) throws ExecException {
        // Chercher une branche de G2 ayant meme ident de relation
        boolean BRes = false;
        Relation rel2 = null;
        Vector<Relation> vRels;

        if (BranchDirection == e_inComeBranch) {
            vRels = C2.m_vctIncomingRelations;
        } else {
            vRels = C2.m_vctOutgoingRelations;
        }

        for (Enumeration<Relation> e = vRels.elements(); !BRes && e.hasMoreElements();) {
            rel2 = (Relation) e.nextElement();

            if (sameNameRel(rel1.m_pdRelationName, rel2.m_pdRelationName, nivG1, nivG2)) {
                BRes = true;
            }
        }

        if (BRes) {
            // Tester que rel2 n'a pas encore ete unifiee
            boolean bAlreadyUnified = false;
            RelationUnification Er;

            for (Enumeration<RelationUnification> e1 = RMatchL.elements();
                    e1.hasMoreElements() && !bAlreadyUnified;) {
                Er = (RelationUnification) e1.nextElement();
                bAlreadyUnified = (rel2 == Er.m_RelMatched2);
            }

            /** Already unified with another branch.  Situation is
             * impossible for functional CGs.  Therefore, return
             * false. **/
            if (bAlreadyUnified) {
                return false;
            }

            // On a localise une branche qu'on pourrait considerer pour l'unification
            Concept Ca1;

            // On a localise une branche qu'on pourrait considerer pour l'unification
            Concept Ca2;
            Ca1 = Ca2 = null;

            if (BranchDirection == e_inComeBranch) {
                Ca1 = rel1.m_concSource;
                Ca2 = rel2.m_concSource;
            } else {
                Ca1 = rel1.m_concDestination;
                Ca2 = rel2.m_concDestination;
            }

            ConceptUnification E = inCMatchL(Ca1, Ca2);

            /***  Verify that the pair (Ca1, Ca2) exists in concMatchVec *****/
            if (E != null) {
                BRes = ((E.m_ConcMatched1 == Ca1) && (E.m_ConcMatched2 == Ca2));
            } else {
                BRes = UnifyConcept(Ca1, Ca2, nivG1, nivG2);
            }

            if (BRes) {
                RMatchL.addElement(new RelationUnification(rel1, rel2));
            }
        }

        return BRes;
    }

    // ------------------------------------------------------------------
    boolean postUnify(CG G1) {
        boolean BRes = true;
        Relation R;

        for (Enumeration<Relation> e = G1.m_vctRelations.elements();
                e.hasMoreElements() && BRes;) {
            R = (Relation) e.nextElement();
            BRes = false;

            RelationUnification er;

            for (Enumeration<RelationUnification> e1 = RMatchL.elements();
                    e1.hasMoreElements() && !BRes;) {
                er = (RelationUnification) e1.nextElement();
                BRes = (R == er.m_RelMatched1);
            }
        }
        return BRes;
    }

    // ------------------------------------------------------------------
    boolean UnifyConcept(Concept C1, Concept C2, int nivG1, int nivG2)
        throws ExecException {
        boolean BRes = false;

        if (UnifyConc(C1, C2, nivG1, nivG2)) {
            CMatchL.addElement(new ConceptUnification(C1, C2, false));
            BRes = true;
        }
        return BRes;
    }

    // ------------------------------------------------------------------
    boolean UnifyConc(Concept C1, Concept C2, int nivG1, int nivG2)
        throws ExecException {
        boolean BRes = true;

        if ((C1.m_pdType == null) || (C2.m_pdType == null)) {
            PrologData Don1 = null;
            PrologData Don2 = null;

            if (C1.m_pdType == null) {
                Don1 = C1.m_pdReferent;
            } else {
                Don1 = new PrologData(uConcept, C1);
            }

            if (C2.m_pdType == null) {
                Don2 = C2.m_pdReferent;
            } else {
                Don2 = new PrologData(uConcept, C2);
            }

            BRes = env.unification.unify(Don1, nivG1, Don2, nivG2);
        } else {
            String Type3 = UnifyTyp(C1.m_pdType, C2.m_pdType, nivG1, nivG2);
            BRes = !Type3.equals("Absurd") &&
                UnifyRef(C1.m_pdReferent, C2.m_pdReferent, nivG1, nivG2) &&
                conform(C2.m_pdReferent, nivG2, Type3) &&
                UnifyValue(C1.m_pdValue, C2.m_pdValue, nivG1, nivG2);
        }
        return BRes;
    }

    // ------------------------------------------------------------------
    String UnifyTyp(PrologData pDonGch, PrologData pDonDrt,
        int indGch, int indDrt) throws ExecException {
        // Considerer en premier le cas ou un des types est une variable
        PrologDataIndexPair ValIndGch = env.unification.valueFromUnifStack(pDonGch, indGch);
        PrologDataIndexPair ValIndDrt = env.unification.valueFromUnifStack(pDonDrt, indDrt);
        String Type3 = null;

        if ((ValIndGch.pData == null) && (ValIndDrt.pData != null)) {
            // pDonGch une variable_free et pDonDrt une valeur
            env.unification.addConstraint2(ValIndDrt.pData, ValIndDrt.index,
                (String) pDonGch.data, indGch);
            Type3 = (String) ValIndDrt.pData.data;
        } else if ((ValIndGch.pData != null) && (ValIndDrt.pData == null)) {
            // pDonGch une valeur et pDonDrt une variable_free
            env.unification.addConstraint2(ValIndGch.pData, ValIndGch.index,
                (String) pDonDrt.data, indDrt);
            Type3 = (String) ValIndGch.pData.data;
        } else if ((ValIndGch.pData == null) && (ValIndDrt.pData == null)) {
            // les deux sont des variable_free
            env.unification.addConstraint3((String) pDonGch.data, indGch,
                (String) pDonDrt.data, indDrt);
        } else { // Les deux donn?es sont des types particuliers

            Object pDon1Gch;
            Object pDon1Drt;
            pDon1Gch = ValIndGch.pData.data;
            pDon1Drt = ValIndDrt.pData.data;

            String sDon1 = (String) pDon1Gch;
            String sDon2 = (String) pDon1Drt;

            if (env.typeHierarchy == null) {
                throw new ExecException(
                    "Error : No type hierarchy is specified (a CG operation needs it).");
            }

            if (sDon1.equals(sDon2)) {
                Type3 = sDon1;
            } else {
                Type3 = env.typeHierarchy.maxComSubType(sDon1,
                        sDon2);
            }
        }

        if (Type3 == null) {
            System.out.println(
                "Warning: At least one of the types should be a specific type.");
            Type3 = "Absurd";
        }
        return Type3;
    }

    // ------------------------------------------------------------------
    boolean UnifyRef(PrologData Ref1, PrologData Ref2, int nivG1,
        int nivG2) throws ExecException {
        if ((Ref1 == null) || (Ref2 == null)) {
            return true;
        }

        PrologDataIndexPair ValIndGch = env.unification.valueFromUnifStack(Ref1, nivG1);
        PrologDataIndexPair ValIndDrt = env.unification.valueFromUnifStack(Ref2, nivG2);

        if ((ValIndGch.pData != null) &&
                (ValIndGch.pData.typeOfData != uIdentifier) &&
                (ValIndGch.pData.typeOfData != uString) &&
                (ValIndGch.pData.typeOfData != uSet)) {
            throw new ExecException("Error: the referent " +
                Ref1.data.toString() +
                "is not a variable, an identifier, a string or a set.");
        }

        if ((ValIndDrt.pData != null) &&
                (ValIndDrt.pData.typeOfData != uIdentifier) &&
                (ValIndDrt.pData.typeOfData != uString) &&
                (ValIndDrt.pData.typeOfData != uSet)) {
            throw new ExecException("Error: the referent " +
                Ref1.data.toString() +
                "is not a variable, an identifier, a string or a set.");
        }

        if ((ValIndGch.pData != null) && (ValIndDrt.pData != null) &&
                ((ValIndGch.pData.typeOfData == uIdentifier) ||
                (ValIndGch.pData.typeOfData == uString)) &&
                (ValIndDrt.pData.typeOfData == uSet)) {
            return env.compile.hasString((String) ValIndGch.pData.data,
                (PrologList) ValIndDrt.pData.data);
        } else {
            return env.unification.unify(Ref2, nivG2, Ref1, nivG1); // unifier prend l'inverse : unifier(Tete, nivT, But, nivB)
        }
    }

    // ------------------------------------------------------------------
    boolean UnifyValue(PrologData Val1, PrologData Val2, int nivG1,
        int nivG2) throws ExecException {
        if ((Val1 == null) || (Val2 == null)) {
            return true;
        } else {
            return env.unification.unify(Val2, nivG2, Val1, nivG1); // unifier prend l'inverse : unifier(Tete, nivT, But, nivB)
        }
    }

    // ------------------------------------------------------------------
    public boolean conform(PrologData Ref, int niv, String Typ)
        throws ExecException {
        if (Ref == null) {
            return true;
        }

        boolean bResult = false;
        PrologDataIndexPair contr = env.unification.valueFromUnifStack(Ref, niv);

        if (env.typeHierarchy == null) {
            throw new ExecException(
                "Error : No type hierarchy is specified (a CG operation needs it).");
        }

        if (contr.pData == null) {
            bResult = true; // le cas d'une variable libre
        } else if (contr.pData.data instanceof String) {
            String st = (String) contr.pData.data;

            if (st.equals("super")) {
                bResult = true;
            } else {
                bResult = env.typeHierarchy.isInstanceOf((String) contr.pData.data,
                        Typ);
            }
        } else { // Traiter le cas d'un referent-ensemble

            PrologList refEns = (PrologList) contr.pData.data;

            // tester que chaque elem est conforme au type
            bResult = true;

            PrologData tmpData = null;

            for (Enumeration<PrologData> e = refEns.elements(); e.hasMoreElements() && bResult;) {
                tmpData = (PrologData) e.nextElement();
                bResult = env.typeHierarchy.isInstanceOf((String) tmpData.data,
                        Typ);
            }
        }
        return bResult;
    }
}
TOP

Related Classes of PrologPlusCG.prolog.UnifyCG

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.