def _findproof(self, con, *pres): '''Find proofs by showing the axiomatic premises.''' # when the conclusion is non-atomic if not isatomic(con): slash, left, right = bipart(con, noComma=True) if slash == '/': return self.findproof(left, *pres, right) elif slash == '\\': return self.findproof(right, left, *pres) # when the conclusion is atomic else: alts = set() hit_nonatomic = False for i in range(len(pres)): if not isatomic(pres[i]): hit_nonatomic = True slash, left, right = bipart(pres[i], noComma=True) if slash == '/': alts.update(self.find_diffTV(con, pres, i, left, right)) elif slash == '\\': alts.update(self.find_diffUT(con, pres, i, left, right)) if hit_nonatomic: return alts else: if len(pres) == 1 and atomicIden(pres[0], con): return {frozenset({tuple(sorted({pres[0], con}))})} else: return set()
def find_stack(self, con, base, expo): alts = set() if not expo: alts.update(self.findproof(con, *base)) if len(expo) == 1 and not isatomic(expo[0], conn=Conns): ec, el, er = bipart(expo[0], conn=Conns, noComma=True) if ec == '!': leftproof = self.findproof(el, *base) if leftproof: rightproof = self.findproof(con, er) alts.update({l | r for l in leftproof for r in rightproof}) if len(base) == 1 and not isatomic(base[0], conn=Conns): bc, bl, br = bipart(base[0], conn=Conns, noComma=True) if bc == '^': leftproof = self.findproof(br, *expo) if leftproof: rightproof = self.findproof(con, bl) alts.update({l | r for l in leftproof for r in rightproof}) return alts
def cat2cmll(s: str): '''product-free Lambek category -> CMLL formula''' if isatomic(s): return s else: slash, left, right = bipart(s, noComma=True) if slash == '/': return (cat2cmll(left), Par, Neg(cat2cmll(right))) else: return (Neg(cat2cmll(left)), Par, cat2cmll(right))
def zoomin(s): if isatomic(s, conn=conn): for opt in abbr.get(s, [s]): if opt == s: yield opt else: for opt1 in zoomin(opt): yield opt1 else: slash, smod, l, r = bipart(s, conn=conn, noComma=True, withMod=True) for lopt in zoomin(l): for ropt in zoomin(r): if not isatomic(lopt, conn=conn): lopt = '(%s)' % lopt if not isatomic(ropt, conn=conn): ropt = '(%s)' % ropt yield lopt + slash + smod + ropt
def _findproof(self, con, *pres): pres = list(pres) alts = set() atomicCon = isatomic(con, conn=Conns) # when the conclusion is non-atomic if not atomicCon: conn, left, right = bipart(con, conn=Conns, noComma=True) if conn == '/': alts = self.findproof(left, *pres, right) elif conn == '\\': alts = self.findproof(right, left, *pres) elif conn == '!': alts = self.find_stack(right, [left], pres) elif conn == '^': ngaps = pres.count(Gap) if ngaps == 0: for i in range(len(pres) + 1): alts.update( self.findproof(con, *pres[:i], Gap, *pres[i:])) alts.update(self.find_stack(left, pres, [right])) elif ngaps <= self._gapLimit: for i in range(len(pres)): if pres[i] == Gap: alts.update( self.findproof(left, *pres[:i], right, *pres[i + 1:])) if alts or self._rruleFirst: return alts # when the conclusion is atomic if not alts: nonatomPlain = [] nonatomIsland = [] for i in range(len(pres)): if not isatomic(pres[i], conn=Conns): conn, left, right = bipart(pres[i], conn=Conns, noComma=True) if islandDiv(conn, left, right): nonatomIsland.append((i, conn, left, right)) else: nonatomPlain.append((i, conn, left, right)) for i, conn, left, right in nonatomIsland: if conn == '/': alts.update(self.find_diffTV(con, pres, i, left, right)) elif conn == '\\': alts.update(self.find_diffUT(con, pres, i, left, right)) if not (self._islandFirst and nonatomIsland): for i, conn, left, right in nonatomPlain: if conn == '/': alts.update(self.find_diffTV(con, pres, i, left, right)) elif conn == '\\': alts.update(self.find_diffUT(con, pres, i, left, right)) elif conn == '!': alts.update( self.find_extract(con, pres, i, left, right)) elif conn == '^': pass if nonatomIsland or nonatomPlain: return alts else: if len(pres) == 1 and atomicCon and atomicIden(pres[0], con): return {frozenset({tuple(sorted({pres[0], con}))})} else: return set()