def popen(self, cmd, result): """Runs a shell command and get the (text) result back.""" if not cmd.is_array(): return Failure(self) # TODO error claims cmd = list(unicode(x) for x in cmd.get_args()) try: shell_res = subprocess.check_output(cmd) return Substitutions(self, [{result: terms.StringConst(shell_res)}]) except subprocess.CalledProcessError as e: return Failure(self) # TODO error claims
def popen_at(self, cmd, timestamp, result): """Runs a shell command and get the (text) result back. The timestamp can be anything, its purpose is to repeat an action that would otherwise be cached (like several printf of the same string) """ if not cmd.is_array(): return Failure(self) # TODO error claims cmd = list(unicode(x) for x in cmd.get_args()) try: shell_res = subprocess.check_output(cmd) return Substitutions(self, [{result: terms.StringConst(shell_res)}]) except subprocess.CalledProcessError as e: return Failure(self) # TODO error claims
def equal(self, a, b): """Unify the two terms""" if b.is_var(): if a.is_var(): return Failure(self) subst = a.unify(b) return Failure(self) if subst is None else Substitutions(self, [subst]) if a.is_var(): subst = b.unify(a) return Failure(self) if subst is None else Substitutions(self, [subst]) elif a.val == b.val: return Success(self) else: return Failure(self)
def in_range(self, low, up, result): """Result in [low, up] range.""" low = int(low.val) up = int(up.val) if low > up: return Failure(self) if result.is_var(): return Substitutions( self, [self.bindResult(result, i) for i in range(low, up + 1)]) #return Substitutions(self, [{result : etb.terms.mk_const(i)} for i in range(low, up+1)]) else: result = int(result.val) if low <= result <= up: return Success(self) else: return Failure(self)
def times(self, a, b, prod): """Like Prolog times; at most one argument may be a variable, if none are checks whether prod=a+b, else binds the variable accordingly. """ if (a.is_var() and (b.is_var() or prod.is_var())) or (b.is_var() and prod.is_var()): return Errors(self, ["Only one variable allowed in times."]) if ((not (a.is_var() or a.is_numconst())) or (not (b.is_var() or b.is_numconst())) or (not (prod.is_var() or prod.is_numconst()))): return Errors(self, ["times expects numbers"]) if a.is_var(): if b.num == 0: return Errors(self, ["times: divide by 0 not allowed"]) else: return Substitutions(self, [self.bindResult(a, prod.num / b.num)]) elif b.is_var(): if a.num == 0: return Errors(self, ["times: divide by 0 not allowed"]) else: return Substitutions(self, [self.bindResult(b, prod.num / a.num)]) elif prod.is_var(): return Substitutions(self, [self.bindResult(prod, a.num * b.num)]) else: res = prod.num == a.num * b.num return Success(self) if res else Failure(self)
def now(self, tok): """Binds the argument to the current unix timestamp (of this computer)""" if tok.is_var(): return Substitutions(self, [{tok: terms.StringConst(time.time())}]) else: return Failure(self)
def match_facts(self, goal, facts): """Put in facts the sorted list of facts that match goal.""" # get the actual list of facts (sorted) print goal, facts _, goal = goal.negative_rename() # avoid collisions with self._etb.logic_state: found_facts = list(subst(goal) for subst in \ self._etb.logic_state.match_facts_against(goal)) print found_facts found_facts.sort() found_facts = terms.Array(found_facts) # bind/check if facts.is_var(): return Substitutions(self, [{ facts: found_facts}]) elif facts == found_facts: return Success(self) else: return Failure(self)
def plus(self, a, b, sum): """Like Prolog sum; at most one argument may be a variable, if none are checks whether sum=a+b, else binds the variable accordingly. """ if (a.is_var() and (b.is_var() or sum.is_var())) or (b.is_var() and sum.is_var()): return Errors(self, ["Only one variable allowed in plus."]) if ((not (a.is_var() or a.is_numconst())) or (not (b.is_var() or b.is_numconst())) or (not (sum.is_var() or sum.is_numconst()))): return Errors(self, ["plus expects numbers"]) if a.is_var(): return Substitutions(self, [self.bindResult(a, sum.num - b.num)]) elif b.is_var(): return Substitutions(self, [self.bindResult(b, sum.num - a.num)]) elif sum.is_var(): return Substitutions(self, [self.bindResult(sum, a.num + b.num)]) else: res = sum.num == a.num + b.num return Success(self) if res else Failure(self)
def yices(self, formula, result, model): with tempfile.NamedTemporaryFile(delete=False, dir='.') as oc: new_file = os.path.basename(oc.name) print >> oc, '(include "%s")' % formula['file'] print >> oc, '(check)' (ret, out, err) = self.callTool('yices', '-e', new_file) if ret != 0: self.log.error(err) return Errors(self, ['error("yices", "%s")' % err]) output = out.split('\n') if output[0] == 'sat': s = self.bindResult(result, output[0]) s = self.bindResult(model, ''.join(output[1:]), current=s) else: s = self.bindResult(result, output[0]) s = self.bindResult(model, [], current=s) if s == []: return Failure(self) else: return Substitutions(self, [s])
def bad_dummy(self, n): n = int(n.val) if n == 0: return Failure(self) else: return Lemmata(self, [{}], ['bad_dummy(%s)' % str(n - 1)])
def equal(self, left, right): if left == right: return Success(self) else: return Failure(self)
def different(self, a, b): """Are the two terms different?""" if a != b: return Success(self) else: return Failure(self)
def new(self, tok): """Bind the argument to a fresh, unique symbol.""" if tok.is_var(): return Substitutions(self, [{tok: terms.StringConst(uuid.uuid4())}]) else: return Failure(self) # always fails with a const argument
def composite(self, n): n = abs(int(n.val)) if isPrime(n): return Failure(self) else: return Success(self)