dap4/d4core/src/main/java/dap4/core/ce/CEConstraint.java
protected boolean
    contractR(DapStructure dstruct, Set<DapStructure> contracted)
    {
        if(contracted.contains(dstruct))
            return true;
        int processed = 0;
        List<DapVariable> fields = dstruct.getFields();
        for(DapVariable field : fields) {
            if(findVariableIndex(field) < 0)
                break; // this compound cannot be contracted
            DapType base = field.getBaseType();
            if(base.getTypeSort().isCompound()
                    && !contracted.contains((field))) {
                if(!contractR((DapStructure)base, contracted))
                    break; // this compound cannot be contracted
            }
            processed++;
        }
        if(processed < fields.size())
            return false;
        contracted.add(dstruct); // all compound fields were successfully contracted.
        return true;
    }
protected boolean
    contractR(DapStructure dstruct, Set<DapStructure> contracted)
    {
        if(contracted.contains(dstruct))
            return true;
        int processed = 0;
        List<DapVariable> fields = dstruct.getFields();
        for(DapVariable field : fields) {
            if(findVariableIndex(field) < 0)
                break; // this compound cannot be contracted
            DapType base = field.getBaseType();
            if(base.getTypeSort().isCompound()
                    && !contracted.contains((field))) {
                if(!contractR((DapStructure)base, contracted))
                    break; // this compound cannot be contracted
            }
            processed++;
        }
        if(processed < fields.size())
            return false;
        contracted.add(dstruct); // all compound fields were successfully contracted.
        return true;
    }
Recursive helper

@param dstruct    to contract
@param contracted set of already contracted compounds
@return true if this structure was contracted, false otherwise