def propagate_semtypes(self):
        if not self._semtypes:
            self._loadsemtypes()
        if not self._ferel_idx:
            self._buildrelationindex()
        changed = True
        i = 0
        nPropagations = 0
        while changed:
            # make a pass and see if anything needs to be propagated
            i += 1
            changed = False
            for ferel in self.fe_relations():
                superST = ferel.superFE.semType
                subST = ferel.subFE.semType
                try:
                    if superST and superST is not subST:
                        # propagate downward
                        assert subST is None or self.semtype_inherits(subST, superST),(superST.name,ferel,subST.name)
                        if subST is None:
                            ferel.subFE.semType = subST = superST
                            changed = True
                            nPropagations += 1
                    if ferel.type.name in ['Perspective_on', 'Subframe', 'Precedes'] and subST \
                        and subST is not superST:
                        # propagate upward
                        assert superST is None,(superST.name,ferel,subST.name)
                        ferel.superFE.semType = superST = subST
                        changed = True
                        nPropagations += 1
                except AssertionError as ex:
                    # bug in the data! ignore
                    #print(ex, file=sys.stderr)
                    continue
            #print(i, nPropagations, file=sys.stderr)
Apply inference rules to distribute semtypes over relations between FEs.
dataset/ETHPy150Open nltk/nltk/nltk/corpus/reader/framenet.py/FramenetCorpusReader.propagate_semtypes