def recur(t, fi): if isinstance(t, c.That): if isinstance(t.that, c.FVar): # special #rp = [x[1] for x in f if x[0] == t.that][0] if t.that == f[0]: newname = star(str(t.const)) newcons = c.Const(newname, c.n0) allargs = t.terms + fi[0] + vars out = c.Appl(newcons, allargs[0]) for i in allargs[1:]: out = c.Appl(out, i) return out else: return t elif isinstance(t, c.Const) or isinstance(t, c.RVar) or isinstance( t, c.PVar): return t elif isinstance(t, c.Appl): return c.Appl(recur(t.func, fi), recur(t.arg, fi)) elif isinstance(t, c.Lambda): return c.Lambda(c.var, recur(t.body, fi)) elif isinstance(t, c.Where): lst = [c.Assignment(i.left, recur(i.right, fi)) for i in t.set] return c.Where(recur(t.body, fi), lst) else: return t
def fint(t): allsteps = cf(t) cfm = allsteps while isinstance(cfm, Reduce): cfm = cfm.b[0] #get to Canonical Form #cfm = cf(t) # no renaming fi = fint_repl(cfm) fi0 = fi[0] if not isinstance(fi0, c.Where): fi0 = c.Where(fi0, set()) # A = A where {} vars = [x[1] for x in fi[1]] + [x[1] for x in fi[2] ] # variables to be abstracted over def lmb(x, st): #construct a lambda term with all variables in st out = x for i in st: if isinstance(i, c.RVar): v = newvar(i.letter.lower(), i.typ) else: v = i out = c.Lambda(v, out) return out lst = [[x[0] for x in fi[2]], [lmb(fi0.body, vars)]] # all free variables, and the body for i in fi0.set: #now add all the terms in the where-construct lst[1].append(lmb(i.right, vars)) return lst + [allsteps] #return the whole list and reduction steps
def reduce_recap(t): if isinstance(t, c.Appl) and isinstance(t.func, c.Where): out = c.Where(c.Appl(t.func.body, t.arg), t.func.set) return out else: return t
def func_to_term(f): global names global pronouns if isinstance(f, str): # string if re.fullmatch('[a-z][0-9]*', f): n = (None if f[1:] == '' else int(f[1:])) return c.PVar(f[0], n) elif re.fullmatch('[A-Z][0-9]*', f): n = (None if f[1:] == '' else int(f[1:])) return c.RVar(f[0], n) elif f in pronouns: return c.Const(f, c.Type('s', 'e'), True) else: try: out = names[f] if isinstance(out, c.Term): return out else: raise c.Error('Not a term: ' + f) except KeyError: raise c.Error('No such object: ' + f) m = f.func # function part a = f.args # argument part j = [(isinstance(x, c.Func) and x.func == c.Keyword('that')) for x in a] if any(j[:-1]): raise c.Error('Non-final that') else: if j[-1]: # that-clause try: return c.That(names[m], func_to_term(a[-1].args[0]), *[func_to_term(x) for x in a[:-1]]) except KeyError: raise c.Error('No such attitudinal constant: ' + str(m)) if isinstance(m, str) or isinstance(m, c.Func): try: out = func_to_term(m) # recursive call on function part for i in a: out = c.Appl( out, func_to_term(i)) # recursive call on each argument result = out except KeyError: raise c.Error('No such object: ' + str(m)) elif m == c.Keyword('lambda'): try: result = c.Lambda(func_to_term(a[0]), func_to_term( a[1])) # recursive call for lambda term except KeyError: raise c.Error('No such object: ' + str(a[0])) elif m == c.Keyword('where'): result = c.Where(func_to_term(a[0]), {func_to_term(i) for i in a[1]}) # recursive call for wh construct elif m == c.Keyword('assign'): result = c.Assignment(func_to_term(a[0]), func_to_term( a[1])) # recursive call for assignments else: pass return result
def testRPL(): readfile('SETTINGS') readfile() j = c.That(names['knows'], c.FVar('w'), names['John']) j2 = c.Where(j, [c.Assignment(c.FVar('w'), c.Fint(fullparse('flat(earth)')))]) d = [[c.FVar('w'), fullparse('flat(earth)')]] return j2
def reduce_ap(t): if isinstance(t, c.Appl) and not immediate(t.arg): nv = newvar('P', c.n0) out = c.Where(c.Appl(t.func, nv), {c.Assignment(nv, t.arg)}) return out else: return t
def reduce_hr(t): # Head Rule if isinstance(t, c.Where) and isinstance(t.body, c.Where): k = t.set.union(t.body.set) # take the union of the two sets r = c.Where(t.body.body, k) return r else: # not the right form for this rule return t
def reduceR(r, ren=True): if isinstance(r, Reduce): t = r.b[0] return reduceR(t) else: t = r if isinstance(t, c.Where) and any([type(x.left) is c.FVar for x in t.set]): ri = reduce_intens(t) p = Reduce(t, [ri[0]], '(intensional)') p.lem = ri[1] return p elif isinstance(t, c.Where) and isinstance(t.body, c.Where): return Reduce(t, [reduce_hr(t)], '(hr)') elif isinstance(t, c.That): rd = reduce_that(t) p = Reduce(t, [rd[0]], '(that)') p.lem = rd[1] return p elif isinstance(t, c.Lambda) and isinstance(t.body, c.Where): return Reduce(t, [reduce_l(t)], '(lambda)') elif isinstance(t, c.Where) and any( [isinstance(i.right, c.Where) for i in t.set]): return Reduce(t, [reduce_bs(t)], '(BS)') elif isinstance(t, c.Appl) and isinstance(t.func, c.Where): return Reduce(t, [reduce_recap(t)], '(recap)') elif isinstance(t, c.Appl) and not immediate(t.arg): return Reduce(t, [reduce_ap(t)], '(ap)') elif isinstance(t, c.Appl): ff = reduceR(t.func) aa = reduceR(t.arg) out = c.Appl(help(ff), help(aa)) s = rmv([ff, aa]) if s: return Reduce(t, [out] + s, '(rep1)') else: return t elif isinstance(t, c.Lambda): bdy = reduceR(t.body) return Reduce(t, [c.Lambda(t.var, help(bdy)), bdy], '(rep2)') elif isinstance(t, c.Where): bdy = reduceR(t.body) lst = [bdy] nset = set() for i in t.set: r = reduceR(i.right) lst.append(r) nset.add(c.Assignment(i.left, help(r))) out = c.Where(help(bdy), nset) s = rmv(lst) if s: return Reduce(t, [out] + s, '(rep3)') else: return out else: #return Reduce(t,[t],'') return t
def reduce_bs(t): if isinstance(t, c.Where): newset = set() for i in t.set: if isinstance(i.right, c.Where): newset.add(c.Assignment(i.left, i.right.body)) newset.update(i.right.set) else: newset.add(i) #print(newset) return c.Where(t.body, newset) else: return t
def fint_repl(t, stack=None, bound=None): if stack is None: stack = [] if bound is None: bound = [] if isinstance(t, c.Appl): out = c.Appl( fint_repl(t.func, stack, bound)[0], fint_repl(t.arg, stack, bound)[0]) elif isinstance(t, c.Lambda): bound.append(t.var) out = c.Lambda(t.var, fint_repl(t.body, stack, bound)[0]) elif isinstance(t, c.Const): out = t elif isinstance(t, c.Where): bound.extend(t.vars()) newbody = fint_repl(t.body, stack, bound)[0] newset = set() for i in t.set: newset.add( c.Assignment(i.left, fint_repl(i.right, stack, bound)[0])) out = c.Where(newbody, newset) elif isinstance(t, c.RVar): if c.varin(t, [x[0] for x in stack]): out = [x[1] for x in stack if c.vareq(x[0], t)][0] else: nv = newvar(t.letter.lower(), t.typ) #create new PVar stack.append([t, nv]) out = nv elif isinstance(t, c.PVar): stack.append([t, t]) out = t elif isinstance(t, c.That): newlst = [] for i in t.terms: newlst.append(fint_repl(i, stack, bound)[0]) out = c.That(t.const, fint_repl(t.that, stack, bound)[0], *newlst) free_vars = [x for x in stack if not c.varin(x[0], bound)] stack2 = [ x for x in stack if c.varin(x[0], bound) and isinstance(x[0], c.RVar) ] return [out, stack2, free_vars]
def repl_fvars(f, trm): fin = fint(f[1]) lm = fin[2] vars = [newvar('P', c.n0) for x in range(len(fin[1]))] def recur(t, fi): if isinstance(t, c.That): if isinstance(t.that, c.FVar): # special #rp = [x[1] for x in f if x[0] == t.that][0] if t.that == f[0]: newname = star(str(t.const)) newcons = c.Const(newname, c.n0) allargs = t.terms + fi[0] + vars out = c.Appl(newcons, allargs[0]) for i in allargs[1:]: out = c.Appl(out, i) return out else: return t elif isinstance(t, c.Const) or isinstance(t, c.RVar) or isinstance( t, c.PVar): return t elif isinstance(t, c.Appl): return c.Appl(recur(t.func, fi), recur(t.arg, fi)) elif isinstance(t, c.Lambda): return c.Lambda(c.var, recur(t.body, fi)) elif isinstance(t, c.Where): lst = [c.Assignment(i.left, recur(i.right, fi)) for i in t.set] return c.Where(recur(t.body, fi), lst) else: return t final = [c.Assignment(vars[i], fin[1][i]) for i in range(len(vars))] n = recur(trm, fin) removal = set([x for x in n.set if x.left == f[0]]) newset = n.set.difference(removal) if newset == set(): n = n.body else: n.set = newset where = c.Where(n, final) return [where, lm]
def reduce_l(t): if isinstance(t, c.Lambda) and isinstance(t.body, c.Where): replacements = [[x, c.Appl(newvar(x.letter, c.n0), t.var)] for x in t.body.vars()] #print(replacements) newbody = replace_free_RVs(replacements, t.body.body) newset = set() for i in t.body.set: var = [x for x in replacements if c.vareq(x[0], i.left)][0] # [P1, P2(u)] new = c.Assignment( var[1].func, c.Lambda(t.var, replace_free_RVs(replacements, i.right))) newset.add(new) return c.Where(c.Lambda(t.var, newbody), newset) else: return t
def replace_free_RVs(reps, form, bound=None): if bound is None: bound = [] if isinstance(form, c.Appl): return c.Appl(replace_free_RVs(reps, form.func), replace_free_RVs(reps, form.arg, bound)) elif isinstance(form, c.Lambda): # free vars in lambda body return c.Lambda(form.var, replace_free_RVs(reps, form.body, bound)) elif isinstance(form, c.Where): vs = form.vars() bound.extend(vs) newbody = replace_free_RVs(reps, form.body, bound) # free vars in the where body temp = set() for i in form.set: temp.add( c.Assignment(i.left, replace_free_RVs( reps, i.right, bound))) # free vars in each assignment bound = [x for x in bound if x not in vs] return c.Where(newbody, temp) elif isinstance(form, c.That): temp = [] for i in form.terms: temp.append(replace_free_RVs(reps, i, bound)) return c.That(form.const, form.that, *temp) elif isinstance(form, c.RVar): if c.varin(form, [x[0] for x in reps]): if not c.varin(form, bound): r = [x[1] for x in reps if c.vareq(x[0], form)][0] return r else: #bound var return form else: return form else: # const or pvar return form
def rename(term, stack=None): if stack is None: stack = dict() if isinstance(term, c.PVar) or isinstance(term, c.RVar): if str(term) in stack: s = stack[str(term)] out = s else: s = str(term) nv = newvar(s[0], term.typ) stack.update({s: nv}) out = nv elif isinstance(term, c.Lambda): s = str(term.var) old = [] if s in stack: old = [s, stack.pop(s)] # store old one nv = newvar(s[0], term.var.typ) stack.update({s: nv}) out1 = rename(term.body, stack) stack.pop(s) if old: stack.update({old[0]: old[1]}) #restore old one out = c.Lambda(nv, out1) elif isinstance(term, c.Appl): out = c.Appl(rename(term.func, stack), rename(term.arg, stack)) elif isinstance(term, c.Const) or isinstance(term, c.FVar): out = term elif isinstance(term, c.Fint): out = c.Fint(rename(term.term, stack)) elif isinstance(term, c.Where): old = [] vars = term.vars() for i in vars: # store old stack s = str(i) if s in stack: #already a free var old.append([s, stack.pop(s)]) for i in vars: # update stack with new bound vars nv = newvar(i.letter, i.typ) stack.update({str(i): nv}) out2 = rename(term.body, stack) #recursive call on body st = set() for i in {x for x in term.set}: #recursive call on set st.add(c.Assignment(rename(i.left, stack), rename(i.right, stack))) for i in vars: #remove bound vars stack.pop(str(i)) for i in old: #restore old stack stack.update({i[0]: i[1]}) out = c.Where(out2, st) elif isinstance(term, c.That): lst = [rename(x, stack) for x in term.terms] out = c.That(term.const, rename(term.that, stack), *lst) return out