def weighted_axioms(self, x, y, xg):
        """
        return a tuple (sub,sup,equiv,other) indicating estimated prior probabilities for an interpretation of a mapping
        between x and y.

        See kboom paper
        """
        # TODO: allow additional weighting
        # weights are log odds w=log(p/(1-p))
        # (Sub,Sup,Eq,Other)
        scope_pairs = [
            ('label',   'label',   0.0, 0.0, 3.0,-0.8), 
            ('label',   'exact',   0.0, 0.0, 2.5,-0.5), 
            ('label',   'broad',  -1.0, 1.0, 0.0, 0.0), 
            ('label',   'narrow',  1.0,-1.0, 0.0, 0.0), 
            ('label',   'related', 0.0, 0.0, 0.0, 0.0), 
            ('exact',   'exact',   0.0, 0.0, 2.5,-0.5), 
            ('exact',   'broad',  -1.0, 1.0, 0.0, 0.0), 
            ('exact',   'narrow',  1.0,-1.0, 0.0, 0.0), 
            ('exact',   'related', 0.0, 0.0, 0.0, 0.0), 
            ('related', 'broad',  -0.5, 0.5, 0.0, 0.0), 
            ('related', 'narrow',  0.5,-0.5, 0.0, 0.0), 
            ('related', 'related', 0.0, 0.0, 0.0, 0.0), 
            ('broad',   'broad',   0.0, 0.0, 0.0, 1.0), 
            ('broad',   'narrow', -0.5, 0.5, 0.0, 0.2), 
            ('narrow',  'narrow',  0.0, 0.0, 0.0, 0.0)
        ]
        # populate symmetric lookup matrix
        scope_map = defaultdict(dict)
        for (l,r,w1,w2,w3,w4) in scope_pairs:
            l = l.upper()
            r = r.upper()
            scope_map[l][r] = np.array((w1,w2,w3,w4))
            scope_map[r][l] = np.array((w2,w1,w3,w4))

        # TODO: get prior based on ontology pair
        # cumulative sum of weights
        WS = None
        pfx1 = self._id_to_ontology(x)
        pfx2 = self._id_to_ontology(y)
        for mw in self.config.get('match_weights', []):
            mpfx1 = mw.get('prefix1','')
            mpfx2 = mw.get('prefix2','')
            X = np.array(mw['weights'])
            if mpfx1 == pfx1 and mpfx2 == pfx2:
                WS = X
            elif mpfx2 == pfx1 and mpfx1 == pfx2:
                WS = self._flipweights(X)
            elif mpfx1 == pfx1 and mpfx2 == '' and WS is None:
                WS = X
            elif mpfx2 == pfx1 and mpfx1 == '' and WS is None:
                WS = self._flipweights(X)

        if WS is None:
            WS = np.array((0.0, 0.0, 0.0, 0.0))
        # defaults
        WS += np.array(self.config.get('default_weights', [0.0, 0.0, 1.5, -0.1]))
        logging.info('WS defaults={}'.format(WS))

        for xw in self.config.get('xref_weights', []):
            left = xw.get('left','')
            right = xw.get('right','')
            X = np.array(xw['weights'])
            if x == left and y == right:
                WS += X
                logging.info('MATCH: {} for {}-{}'.format(X, x, y))
            elif y == left and x == right:
                WS += self._flipweights(X)
                logging.info('IMATCH: {}'.format(X))

        smap = self.smap
        # TODO: symmetrical
        WT = np.array((0.0, 0.0, 0.0, 0.0))
        WBESTMAX = np.array((0.0, 0.0, 0.0, 0.0))
        n = 0
        for sx in smap[x]:
            WBEST, _ = self._best_match_syn(sx, smap[y], scope_map)
            if WBEST is not None:
                WT += WBEST
                n += 1
                if max(abs(WBEST)) > max(abs(WBESTMAX)):
                    WBESTMAX = WBEST
        for sy in smap[y]:
            WBEST, _ = self._best_match_syn(sy, smap[x], scope_map)
            if WBEST is not None:
                WT += WBEST
                n += 1
        # average best match
        if n > 0:
            logging.info('Adding BESTMAX={}'.format(WBESTMAX))
            WS += WBESTMAX
                    
        # TODO: xref, many to many
        WS += self._graph_weights(x, y, xg)
        # TODO: include additional defined weights, eg ORDO
        logging.info('Adding WS, gw={}'.format(WS))

        # jaccard similarity
        (ss1,ss2) = xg[x][y][self.SIMSCORES]
        WS[3] += ((1-ss1) + (1-ss2)) / 2

        # reciprocal best hits are higher confidence of equiv
        rs = xg[x][y]['reciprocal_score']
        if rs == 4:
            WS[2] += 0.5
        if rs == 0:
            WS[2] -= 0.2
        
        #P = np.expit(WS)
        P = 1/(1+np.exp(-WS))
        logging.info('Final WS={}, init P={}'.format(WS, P))
        # probs should sum to 1.0
        P = P / np.sum(P)
        return P
return a tuple (sub,sup,equiv,other) indicating estimated prior probabilities for an interpretation of a mapping
        between x and y.

        See kboom paper