#####################################################################
#####################################################################
## Copyright 2005 Steven R. Newcomb                                ##
##                                                                 ##
## This software is licensed under the Apache License, Version 2.0 ##
## (the "License"); you may not use this file except in compliance ##
## with the License.  Copies of the License are available at       ##
##        http://www.apache.org/licenses/LICENSE-2.0               ##
##                                                                 ##
## Unless required by applicable law or agreed to in writing,      ##
## software distributed under the License is distributed on an "AS ##
## IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either ##
## express or implied.  See the License for the specific language  ##
## governing permissions and limitations under the License.        ##
##                                                                 ##
## Copies of the source code and the license are available at      ##
##        http://www.versavant.org                                 ##
#####################################################################
#####################################################################

####################################
cvsRevision = "$Revision: 1.8 $" ##
####################################


import sys, traceback


#################################################################
## a_sip PC implementation                                     ##
## (mostly it's in ${VSVEXECDIR}/Lib/PCsetOfProxyRefTuples.py) ##
#################################################################

#######################################################
def ValueIsInvalidFor_a_sip_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):

    r_proxy_allowed_properties = args[ 'r_proxy_allowed_properties']
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    if len( propertyValue) < 2:
        if propertyInstance:
            vsv.errMsg( 'Value of %s property contains %d tuples; should have at least two tuples.  A relationship must have at least two roles, even if some of them are unplayed.' % ( propertyInstance.propertyInstanceKey, len( propertyValue)))
        else:
            vsv.errMsg( 'Value of %s presumptive property contains %d tuples; should have at least two tuples.  A relationship must have at least two roles, even if some of them are unplayed.' % ( vsv.catKey( TMAName, propertyClass), len( propertyValue)))
        return True

    rProxyDict = {}
    foundDuple = False
    for tuple in propertyValue:
        memberCount = len( tuple)
        if memberCount == 2:
            foundDuple = True
        elif memberCount == 1:
            pass
        else:
            if propertyInstance:
                vsv.errMsg( 'Tuple in %s property\'s value has %d members; should have 1 (an unplayed role) or 2 (a role and a role player).' % ( propertyInstance.propertyInstanceKey, memberCount))
            else:
                vsv.errMsg( 'Tuple in presumptive %s property\'s value has %d members; should have 1 (an unplayed role) or 2 (a role and a role player).' % ( vsv.catKey( TMAName, propertyClass.propertyClassName), memberCount))
            return True
        memberNumber = 0
        for proxyId in tuple:
            memberNumber += 1
            if not vsv.nowImporting:
                proxy = vsv.isProxyId( proxyId, topicMap)
                if not proxy:
                    if propertyInstance:
                        vsv.errMsg( 'Tuple in value of %s property has a member (%s) that is not a proxyId.' % ( propertyInstance.propertyInstanceKey, proxyId))
                    else:
                        vsv.errMsg( 'Tuple in value of presumptive %s property has a member (%s) that is not a proxyId.' % ( vsv.catKey( TMAName, propertyClass.propertyClassName), proxyId))
                    return True
                if proxy.forwardTo:
                    if propertyInstance:
                        vsv.errMsg( 'Tuple in value of %s property has a member (%s) that is a proxyId of a dead proxy.' % ( propertyInstance.propertyInstanceKey, proxyId))
                    else:
                        vsv.errMsg( 'Tuple in value of presumptive %s property has a member (%s) that is a proxyId of a dead proxy.' % ( vsv.catKey( TMAName, propertyClass.propertyClassName), proxyId))
                    return True
                if memberNumber == 1:  ## this should be a reference to an r-proxy

                    if rProxyDict.has_key( proxyId):
                        if propertyInstance:
                            vsv.errMsg( 'multiple references to the same r-proxy (%s) in property %s.  No role can be used more than once in any given assertion.' % ( proxyId, propertyInstance.propertyInstanceKey))
                        else:
                            vsv.errMsg( 'multiple references to the same r-proxy (%s) in presumptive property %s.  No role can be used more than once in any given assertion.' % ( proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                        return True
                    rProxyDict[ proxyId] = None

                    for propertyInstanceKey2 in proxy.propertyInstances:
                        tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                        if TMAName == tmaName:
                            if propertyClassName not in r_proxy_allowed_properties:
                                if propertyInstance:
                                    vsv.errMsg( 'Proxy referenced as first member of tuple "%s" in value of %s property value has a "%s" property, which, as an r-proxy, it should not have.' % ( tuple, propertyInstance.propertyInstanceKey, propertyClassName))
                                else:
                                    vsv.errMsg( 'Proxy referenced as first member of tuple "%s" in value of presumptive %s property value has a "%s" property, which, as an r-proxy, it should not have.' % ( tuple, vsv.catKey( TMAName, propertyClass.propertyClassName), propertyClassName))
                                return True
                ## else:                  ## memberNumber == 2; this should be a reference to an x-proxy

    if not foundDuple:
        if propertyInstance:
            vsv.errMsg( 'No tuple in value of %s property has 2 members.  There must be at least one tuple that has two members; a relationship between nothing and nothing is not a relationship.' % ( propertyInstance.propertyInstanceKey))
        else:
            vsv.errMsg( 'No tuple in value of presumptive %s property has 2 members.  There must be at least one tuple that has two members; a relationship between nothing and nothing is not a relationship.' % ( vsv.catKey( TMAName, propertyClass.propertyClassName)))
        return True

    return False



###########################################
## t_sip PC implementation               ##
## (mostly re-uses Lib/PCproxyIdSet.py) ##
###########################################

#######################################################
def ValueIsInvalidFor_t_sip_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    r_proxy_allowed_properties = args[ 'r_proxy_allowed_properties']
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    rProxyDict = {}
    for item in propertyValue:
        rProxyDict[ item] = None
    propertyValue = rProxyDict.keys()

    if len( propertyValue) < 2:
        traceback.print_stack()
        if propertyInstance:
            vsv.errMsg( 'Value of property %s references only %d different proxy/ies; it must refer to at least two.  A relationship must have at least two roles, even if one of them is unplayed.' % ( propertyInstance.propertyInstanceKey, len( propertyValue)))
        else:
            vsv.errMsg( 'Value of presumptive %s property references only %d different proxies; it must refer to at least two.  A relationship must have at least two roles, even if one of them is unplayed.' % ( vsv.catKey( TMAName, propertyClass.propertyClassName), len( propertyValue)))
###
        vsv.inspect( propertyInstanceKey = propertyInstance.propertyInstanceKey)
###
        return True

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    for proxyId in propertyValue:
        proxy = vsv.isProxyId( proxyId, topicMap)
        if not proxy:
            if propertyInstance:
                vsv.errMsg( 'Value of %s property includes something (%s) that is not a proxyId.' % ( propertyInstance.propertyInstanceKey, proxyId))
            else:
                vsv.errMsg( 'Value of presumptive %s property includes something (%s) that is not a proxyId.' % ( vsv.catKey( TMAName, propertyClass.propertyClassName), proxyId))
            return True
        if proxy.forwardTo:  ## only living proxies are valid
            if propertyInstance:
                vsv.errMsg( 'Tuple in value of %s property has a member (%s) that is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( propertyInstance.propertyInstanceKey, proxyId))
            else:
                vsv.errMsg( 'Tuple in value of presumptive %s property has a member (%s) that is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( vsv.catKey( TMAName, propertyClass.propertyClassName), proxyId))
            return True

        for propertyInstanceKey2 in proxy.propertyInstances:
            tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
            if TMAName == tmaName:
                if propertyClassName not in r_proxy_allowed_properties:
                    if propertyInstance:
                        vsv.errMsg( 'Proxy %s, referenced in %s property value, has a "%s" property, which, as an r-proxy, it should not have.' % ( proxy.proxyId, propertyInstance.propertyInstanceKey, propertyClassName))
                    else:
                        vsv.errMsg( 'Proxy %s, referenced in presumptive %s property value, has a "%s" property, which, as an r-proxy, it should not have.' % ( proxy.proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName), propertyClassName))
                    return True

    return False


###########################################
## c_sip PC implementation               ##
## (mostly re-uses Lib/PCproxyIdList.py) ##
###########################################

#######################################################
def ValueIsInvalidFor_c_sip_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    itemCount = len( propertyValue)
    if itemCount < 2 or itemCount > 3:
        if propertyInstance:
            vsv.errMsg( 'Value of c_sip property (%s) is a list containing %d item(s); should be 2 or 3: (1) a reference to an r-proxy, (2) a reference to an a-proxy, and, optionally, (3) a reference to an x-proxy.' % ( propertyInstance.propertyInstanceKey, itemCount))
        else:
            vsv.errMsg( 'Presumptive c_sip property value is a list containing %d item(s); should be 2 or 3: (1) a reference to an r-proxy, (2) a reference to an a-proxy, and, optionally, (3) a reference to an x-proxy.' % ( itemCount))
        return True

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    itemNumber = 0
    for proxyId in propertyValue:
        ordinalItemNumberString = [ 'First', 'Second', 'Third'][ itemNumber]
        itemNumber += 1
        proxy = vsv.isProxyId( proxyId, topicMap)
        if itemNumber == 1:  ## this should be a reference to an r-proxy
            found_r_type_property = False
            found_r_castings_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName not in [ 'r_type', 'r_castings', 'x_castings']:
                        if propertyInstance:
                            vsv.errMsg( 'Proxy referenced as first item in list "%s" in value of %s property has a "%s" property, which, as an r-proxy, it should not have.' % ( propertyValue, propertyInstance.propertyInstanceKey, vsv.catKey( TMAName, propertyClassName)))
                        else:
                            vsv.errMsg( 'Proxy referenced as first item in list "%s" in presumptive %s property value has a "%s" property, which, as an r-proxy, it should not have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName), vsv.catKey( TMAName, propertyClassName)))
                        return True
                    if propertyClassName == 'r_type':
                        found_r_type_property = True
                    if propertyClassName == 'r_castings':
                        found_r_castings_property = True
            if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of building something
                if not found_r_type_property:
                    if propertyInstance:
                        vsv.errMsg( 'Proxy referenced as first item in list "%s" in value of %s property has no r_type property, which, as an r-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                    else:
                        vsv.errMsg( 'Proxy referenced as first item in list "%s" in presumptive %s property value has no r_type property, which, as an r-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                    return True
                if not found_r_castings_property:
                    if propertyInstance:
                        vsv.errMsg( 'Proxy referenced as first item in list "%s" in value of %s property has no r_castings property, which, as an r-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                    else:
                        vsv.errMsg( 'Proxy referenced as first item in list "%s" in presumptive %s property value has no r_castings property, which, as an r-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                    return True
        elif itemNumber == 2:  ## this should be a reference to an a-proxy
            found_a_sip_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName not in [ 'a_sip', 'a_type', 'a_castings', 'x_castings']:
                        if propertyInstance:
                            vsv.errMsg( 'Proxy referenced as second item in list "%s" in value of %s property has a "%s" property, which, as an a-proxy, it should not have.' % ( propertyValue, propertyInstance.propertyInstanceKey, vsv.catKey( TMAName, propertyClassName)))
                        else:
                            vsv.errMsg( 'Proxy referenced as second item in list "%s" in presumptive %s property value has a "%s" property, which, as an a-proxy, it should not have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName), vsv.catKey( TMAName, propertyClassName)))
                        return True
                    if propertyClassName == 'a_sip':
                        found_a_sip_property = True

            if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of building something
                if not found_a_sip_property:
                    if propertyInstance:
                        vsv.errMsg( 'Proxy referenced as first item in list "%s" in value of %s property has no a_sip property, which, as an r-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                    else:
                        vsv.errMsg( 'Proxy referenced as first item in list "%s" in presumptive %s property value has no a_sip property, which, as an r-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                    return True

    return False

###########################################
## r_type PC implementation               ##
## (mostly re-uses Lib/PCproxyIdSet.py) ##
###########################################

#######################################################
def ValueIsInvalidFor_r_type_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    itemCount = len( propertyValue)
    if itemCount != 1:
        if propertyInstance:
            vsv.errMsg( 'Value of r_type property (%s) is a list containing %d item(s); should be only 1.  If a single role were to appear in more than one assertion type, its proxy would have multiple subjects, which would break the cardinal rule of the subject maps paradigm.' % ( propertyInstance.propertyInstanceKey, itemCount))
        else:
            vsv.errMsg( 'Presumptive r_type property value is a list containing %d item(s); should be only 1.  If a single role were to appear in more than one assertion type, its proxy would have multiple subjects, which would break the cardinal rule of the subject maps paradigm.' % ( itemCount))
        return True

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    for proxyId in propertyValue:
        proxy = vsv.isProxyId( proxyId, topicMap)
        if not proxy:
            if propertyInstance:
                vsv.errMsg( 'item (%s) in list that is the value of the %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyInstance.propertyInstanceKey)))
            else:
                vsv.errMsg( 'item (%s) in list that is the proposed value of a %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True
        if proxy.forwardTo:  ## only living proxies are valid
            if propertyInstance:
                vsv.errMsg( 'Item (%s) in value of %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'Item (%s) in value of presumptive %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True

        if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of building something
            found_t_sip_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName == 't_sip':
                        found_t_sip_property = True
                        break
            if not found_t_sip_property:
                if propertyInstance:
                    vsv.errMsg( 'Proxy referenced in list "%s" in value of %s property has no t_sip property, which, as a t-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'Proxy referenced in list "%s" in presumptive %s property value has no t_sip property, which, as a t-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                return True

    return False


###########################################
## a_type PC implementation               ##
## (mostly re-uses Lib/PCproxyIdSet.py) ##
###########################################

#######################################################
def ValueIsInvalidFor_a_type_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of populating, conferring, or merging something
        itemCount = len( propertyValue)
        if itemCount != 1:
            if propertyInstance:
                vsv.errMsg( 'Value of a_type property (%s) is a list containing %d item(s); should be only 1.  An assertion can have only one type.' % ( propertyInstance.propertyInstanceKey, itemCount))
            else:
                vsv.errMsg( 'Presumptive a_type property value is a list containing %d item(s); should be only 1.  An assertion can have only one type.' % ( itemCount))
            return True

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    for proxyId in propertyValue:
        proxy = vsv.isProxyId( proxyId, topicMap)
        if not proxy:
            if propertyInstance:
                vsv.errMsg( 'item (%s) in list that is the value of the %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyInstance.propertyInstanceKey)))
            else:
                vsv.errMsg( 'item (%s) in list that is the proposed value of a %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True
        if proxy.forwardTo:  ## only living proxies are valid
            if propertyInstance:
                vsv.errMsg( 'Item (%s) in value of %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'Item (%s) in value of presumptive %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True

        if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of populating, conferring, or merging something

            found_t_sip_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName == 't_sip':
                        found_t_sip_property = True
                        break
            if not found_t_sip_property:
                if propertyInstance:
                    vsv.errMsg( 'Proxy referenced in list "%s" in value of %s property has no t_sip property, which, as a t-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'Proxy referenced in list "%s" in presumptive %s property value has no t_sip property, which, as a t-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                return True



    return False


###########################################
## r_castings PC implementation               ##
## (mostly re-uses Lib/PCproxyIdSet.py) ##
###########################################

#######################################################
def ValueIsInvalidFor_r_castings_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    for proxyId in propertyValue:
        proxy = vsv.isProxyId( proxyId, topicMap)
        if not proxy:
            if propertyInstance:
                vsv.errMsg( 'item (%s) in list that is the value of the %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyInstance.propertyInstanceKey)))
            else:
                vsv.errMsg( 'item (%s) in list that is the proposed value of a %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True
        if proxy.forwardTo:  ## only living proxies are valid
            if propertyInstance:
                vsv.errMsg( 'Item (%s) in value of %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'Item (%s) in value of presumptive %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True

        if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of building something
            found_c_sip_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName == 'c_sip':
                        found_c_sip_property = True
                        break
            if not found_c_sip_property:
                if propertyInstance:
                    vsv.errMsg( 'Proxy referenced in list "%s" in value of %s property has no c_sip property, which, as a c-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'Proxy referenced in list "%s" in presumptive %s property value has no c_sip property, which, as a c-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                return True

    return False


###########################################
## a_castings PC implementation          ##
## (mostly re-uses Lib/PCproxyIdSet.py)  ##
###########################################

#######################################################
def ValueIsInvalidFor_a_castings_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    for proxyId in propertyValue:
        proxy = vsv.isProxyId( proxyId, topicMap)
        if not proxy:
            if propertyInstance:
                vsv.errMsg( 'item (%s) in list that is the value of the %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyInstance.propertyInstanceKey)))
            else:
                vsv.errMsg( 'item (%s) in list that is the proposed value of a %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True
        if proxy.forwardTo:  ## only living proxies are valid
            if propertyInstance:
                vsv.errMsg( 'Item (%s) in value of %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'Item (%s) in value of presumptive %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True

        if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of building something
            found_c_sip_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName == 'c_sip':
                        found_c_sip_property = True
                        break
            if not found_c_sip_property:
                if propertyInstance:
                    vsv.errMsg( 'Proxy referenced in list "%s" in value of %s property has no c_sip property, which, as a c-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'Proxy referenced in list "%s" in presumptive %s property value has no c_sip property, which, as a c-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                return True

    return False


###########################################
## x_castings PC implementation               ##
## (mostly re-uses Lib/PCproxyIdSet.py) ##
###########################################

#######################################################
def ValueIsInvalidFor_x_castings_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    for proxyId in propertyValue:
        proxy = vsv.isProxyId( proxyId, topicMap)
        if not proxy:
            if propertyInstance:
                vsv.errMsg( 'item (%s) in list that is the value of the %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyInstance.propertyInstanceKey)))
            else:
                vsv.errMsg( 'item (%s) in list that is the proposed value of a %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True
        if proxy.forwardTo:  ## only living proxies are valid
            if propertyInstance:
                vsv.errMsg( 'Item (%s) in value of %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'Item (%s) in value of presumptive %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True

        if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of building something
            found_c_sip_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName == 'c_sip':
                        found_c_sip_property = True
                        break
            if not found_c_sip_property:
                if propertyInstance:
                    vsv.errMsg( 'Proxy referenced in list "%s" in value of %s property has no c_sip property, which, as a c-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'Proxy referenced in list "%s" in presumptive %s property value has no c_sip property, which, as a c-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                return True

    return False


###########################################
## t_assertions PC implementation               ##
## (mostly re-uses Lib/PCproxyIdSet.py) ##
###########################################

#######################################################
def ValueIsInvalidFor_t_assertions_Property( vsv, propertyValue, propertyClass, propertyInstance = None, **args):
    TMAName = propertyClass.TMA.TMAName
    topicMap = propertyClass.topicMap

    if vsv.nowImporting:
        return False  ## can't make the rest of these checks yet
    
    for proxyId in propertyValue:
        proxy = vsv.isProxyId( proxyId, topicMap)
        if not proxy:
            if propertyInstance:
                vsv.errMsg( 'item (%s) in list that is the value of the %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyInstance.propertyInstanceKey)))
            else:
                vsv.errMsg( 'item (%s) in list that is the proposed value of a %s property is not a proxyId.' % (
                    proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True
        if proxy.forwardTo:  ## only living proxies are valid
            if propertyInstance:
                vsv.errMsg( 'Item (%s) in value of %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, propertyInstance.propertyInstanceKey))
            else:
                vsv.errMsg( 'Item (%s) in value of presumptive %s property is the proxyId of a dead proxy.  Only living proxies are allowed to be referenced.' % ( proxyId, vsv.catKey( TMAName, propertyClass.propertyClassName)))
            return True

        if not vsv.currentProcOperation:  ## if this is a full check, and we're not in the middle of building something
            found_a_sip_property = False
            for propertyInstanceKey2 in proxy.propertyInstances:
                tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
                if TMAName == tmaName:
                    if propertyClassName == 'a_sip':
                        found_a_sip_property = True
                        break
            if not found_a_sip_property:
                if propertyInstance:
                    vsv.errMsg( 'Proxy referenced in list "%s" in value of %s property has no a_sip property, which, as a a-proxy, it should have.' % ( propertyValue, propertyInstance.propertyInstanceKey))
                else:
                    vsv.errMsg( 'Proxy referenced in list "%s" in presumptive %s property value has no a_sip property, which, as a a-proxy, it should have.' % ( propertyValue, vsv.catKey( TMAName, propertyClass.propertyClassName)))
                return True

    return False





################################################################################################################
## Context check function for all BIGASSERT property classes except x_castings, which needs no such function. ##
################################################################################################################

#######################################################
def ContextOf_BIGASSERT_PropertyIsInvalid( vsv, propertyInstance, thisPropertyClassName):
    proxy = propertyInstance.proxy
    TMAName = propertyInstance.propertyClass.TMA.TMAName
    if thisPropertyClassName in [ 'a_sip', 'a_type', 'a_castings']:
        allowedPropertiesInSameProxy = [ 'a_sip', 'a_type', 'a_castings', 'x_castings']
    elif thisPropertyClassName in [ 't_sip', 't_assertions']:
        allowedPropertiesInSameProxy = [ 't_sip', 't_assertions', 'x_castings']
    elif thisPropertyClassName in ['c_sip']:
        allowedPropertiesInSameProxy = [ 'c_sip', 'x_castings']
    elif thisPropertyClassName in [ 'r_type', 'r_castings']:
        allowedPropertiesInSameProxy = [ 'r_type', 'r_castings', 'x_castings']
    else:
        vsv.errMsg( 'unrecognized "thisPropertyClassName": %s' % ( thisPropertyClassName))
        return True
    for propertyInstanceKey2 in proxy.propertyInstances:
        tmaName, propertyClassName = vsv.parsePropertyKey2( propertyInstanceKey2)
        if tmaName == TMAName:
            if propertyClassName not in allowedPropertiesInSameProxy:
                vsv.errMsg( 'Proxy %s has a "%s" property, so it should not also have a "%s" property, but it does.' % ( proxy.proxyId, thisPropertyClassName, vsv.catKey( TMAName, propertyClassName)))
                return True
    return False

