from contextlib import contextmanager from cozy.syntax import Stm, Exp, Type from cozy.common import declare_case, Visitor INDENT = " " SEscape = declare_case(Stm, "SEscape", ["body_string", "arg_names", "args"]) EEscape = declare_case(Exp, "EEscape", ["body_string", "arg_names", "args"]) def indent_lines(s, indent): """ Prepends the given indentation string to the beginning of each line of the given string. """ return '\n'.join(indent + line for line in s.splitlines()) class CodeGenerator(Visitor): def __init__(self, out): self.out = out self.indent = 0 def get_indent(self): return INDENT * self.indent def write(self, *parts): for p in parts: self.out.write(p)
"""Abstract syntax for Cozy specifications.""" from enum import Enum from cozy.common import ADT, declare_case, typechecked, partition, make_random_access Spec = declare_case(ADT, "Spec", [ "name", "types", "extern_funcs", "statevars", "assumptions", "methods", "header", "footer", "docstring" ]) ExternFunc = declare_case(ADT, "ExternFunc", ["name", "args", "out_type", "body_string"]) class Visibility(Enum): """Visibilities for queries in Cozy specifications.""" Public = "public" # usable by clients Private = "private" # private helper used by other methods Internal = "internal" # helper added by Cozy, not by a human programmer class Method(ADT): pass Op = declare_case(Method, "Op", ["name", "args", "assumptions", "body", "docstring"]) Query = declare_case( Method, "Query", ["name", "visibility", "args", "assumptions", "ret", "docstring"])
""" While the syntax module declares the core _input_ language, this module declares additional syntax extensions that can appear in the _target_ language: the primitives the tool can output and use during synthesis. """ from cozy.syntax import * from cozy.common import declare_case, typechecked, fresh_name from cozy.opts import Option enforce_estatevar_wf = Option("enforce-well-formed-state-var-boundaries", bool, False) # Misc TRef = declare_case(Type, "TRef", ["t"]) EEnumToInt = declare_case(Exp, "EEnumToInt", ["e"]) EBoolToInt = declare_case(Exp, "EBoolToInt", ["e"]) EStm = declare_case(Exp, "EStm", ["stm", "e"]) # State var barrier: sub-expression should be maintained as a fresh state var EStateVar = declare_case(Exp, "EStateVar", ["e"]) class IllegalStateVarBoundary(Exception): pass old = EStateVar.__init__ def f(self, e):
from cozy.common import fresh_name, declare_case from cozy.syntax import * from cozy.target_syntax import SWhile, SSwap, SSwitch, SEscapableBlock, SEscapeBlock, EMap, EFilter from cozy.syntax_tools import fresh_var, pprint, shallow_copy, mk_lambda, alpha_equivalent from cozy.pools import RUNTIME_POOL from .arrays import TArray, EArrayGet, EArrayIndexOf, SArrayAlloc, SEnsureCapacity, EArrayLen TMinHeap = declare_case(Type, "TMinHeap", ["elem_type", "key_type"]) TMaxHeap = declare_case(Type, "TMaxHeap", ["elem_type", "key_type"]) # Like EArgMin: bag, keyfunc EMakeMinHeap = declare_case(Exp, "EMakeMinHeap", ["e", "f"]) EMakeMaxHeap = declare_case(Exp, "EMakeMaxHeap", ["e", "f"]) EHeapElems = declare_case(Exp, "EHeapElems", ["e"]) # all elements EHeapPeek = declare_case(Exp, "EHeapPeek", ["e", "n"]) # look at min EHeapPeek2 = declare_case(Exp, "EHeapPeek2", ["e", "n"]) # look at 2nd min def to_heap(e : Exp) -> Exp: if isinstance(e, EArgMin): elem_type = e.type key_type = e.f.body.type return EMakeMinHeap(e.e, e.f).with_type(TMinHeap(elem_type, key_type)) if isinstance(e, EArgMax): elem_type = e.type key_type = e.f.body.type return EMakeMaxHeap(e.e, e.f).with_type(TMaxHeap(elem_type, key_type)) raise ValueError(e) # Binary heap utilities
from cozy.syntax import Stm, Exp, Type from cozy.common import declare_case INDENT = " " SEscape = declare_case(Stm, "SEscape", ["body_string", "arg_names", "args"]) EEscape = declare_case(Exp, "EEscape", ["body_string", "arg_names", "args"]) TArray = declare_case(Type, "TArray", ["t"]) def indent_lines(s, indent): """ Prepends the given indentation string to the beginning of each line of the given string. """ return '\n'.join(indent + line for line in s.splitlines())
from contextlib import contextmanager from cozy.syntax import Stm, Exp from cozy.common import declare_case, Visitor INDENT = " " SEscape = declare_case(Stm, "SEscape", ["body_string", "arg_names", "args"]) EEscape = declare_case(Exp, "EEscape", ["body_string", "arg_names", "args"]) EMove = declare_case(Exp, "EMove", ["e"]) SScoped = declare_case(Stm, "SScoped", ["s"]) def indent_lines(s, indent): """ Prepends the given indentation string to the beginning of each line of the given string. """ return '\n'.join(indent + line for line in s.splitlines()) class CodeGenerator(Visitor): def __init__(self, out): self.out = out self.indent = 0 def get_indent(self): return INDENT * self.indent def write(self, *parts): for p in parts:
from collections import OrderedDict import json import itertools from cozy import common, library, evaluation from cozy.common import fresh_name, declare_case from cozy.target_syntax import * from cozy.syntax_tools import all_types, fresh_var, subst, free_vars, is_scalar, mk_lambda, alpha_equivalent, all_exps from cozy.typecheck import is_collection, is_numeric from .misc import * EMove = declare_case(Exp, "EMove", ["e"]) SScoped = declare_case(Stm, "SScoped", ["s"]) class CxxPrinter(common.Visitor): def __init__(self, use_qhash: bool = False): self.types = OrderedDict() self.funcs = {} self.queries = {} self.use_qhash = use_qhash self.vars = set() # set of strings def fn(self, hint="var"): n = common.fresh_name(hint, omit=self.vars) self.vars.add(n) return n def fv(self, t, hint="var"): n = fresh_var(t, hint=hint, omit=self.vars)
"""Additional internal syntax. While the syntax module declares the core _input_ language, this module declares additional syntax extensions that can appear in the _target_ language: the primitives the tool can output and use during synthesis. """ from cozy.syntax import * from cozy.common import declare_case, fresh_name # Misc TRef = declare_case(Type, "TRef", ["elem_type"]) EEnumToInt = declare_case(Exp, "EEnumToInt", ["e"]) # Execute a statement and then "return" the value of `out_var`. The statement # must declare `out_var` in its body. EStm = declare_case(Exp, "EStm", ["stm", "out_var"]) # State var barrier: sub-expression should be maintained as a fresh state var EStateVar = declare_case(Exp, "EStateVar", ["e"]) def EIsSingleton(e): arg = EVar(fresh_name()).with_type(e.type.elem_type) return EBinOp(EUnaryOp(UOp.Sum, EMap(e, ELambda(arg, ONE)).with_type(TBag(INT))).with_type(INT), "<=", ONE).with_type(BOOL) def EDeepEq(e1, e2): return EBinOp(e1, "===", e2).with_type(BOOL) def EDeepIn(e1, e2): from cozy.syntax_tools import free_vars, fresh_var arg = fresh_var(e1.type, omit=free_vars(e1))
from cozy.common import declare_case from cozy.syntax import Type, Exp, Stm TArray = declare_case(Type, "TArray", ["t"]) EArrayCapacity = declare_case(Exp, "EArrayCapacity", ["e"]) EArrayLen = declare_case(Exp, "EArrayLen", ["e"]) EArrayGet = declare_case(Exp, "EArrayGet", ["a", "i"]) EArrayIndexOf = declare_case(Exp, "EArrayIndexOf", ["a", "x"]) SArrayAlloc = declare_case(Stm, "SArrayAlloc", ["a", "capacity"]) SArrayReAlloc = declare_case(Stm, "SArrayReAlloc", ["a", "new_capacity"]) SEnsureCapacity = declare_case(Stm, "SEnsureCapacity", ["a", "capacity"])
from cozy.common import fresh_name, declare_case, No, pick_to_sum from cozy.syntax import * from cozy.target_syntax import ( SWhile, SSwap, SSwitch, SEscapableBlock, SEscapeBlock, EMap, EFilter, EStateVar, TArray, EArrayGet, EArrayIndexOf, SArrayAlloc, SEnsureCapacity) from cozy.syntax_tools import fresh_var, pprint, mk_lambda, alpha_equivalent from cozy.pools import Pool, RUNTIME_POOL, STATE_POOL TMinHeap = declare_case(Type, "TMinHeap", ["elem_type", "key_type"]) TMaxHeap = declare_case(Type, "TMaxHeap", ["elem_type", "key_type"]) # Like EArgMin: bag, keyfunc EMakeMinHeap = declare_case(Exp, "EMakeMinHeap", ["e", "key_function"]) EMakeMaxHeap = declare_case(Exp, "EMakeMaxHeap", ["e", "key_function"]) EHeapElems = declare_case(Exp, "EHeapElems", ["e"]) # all elements EHeapPeek = declare_case(Exp, "EHeapPeek", ["e"]) # look at min EHeapPeek2 = declare_case(Exp, "EHeapPeek2", ["e"]) # look at 2nd min def to_heap(e : Exp) -> Exp: """Construct a heap that would be useful for evaluating `e`. Given an EArgMin or EArgMax expression, this function produces a new expression that constructs a heap. Peeking the top value of the constructed heap is semantically equivalent to evaluating `e`. """ if isinstance(e, EArgMin): elem_type = e.type key_type = e.key_function.body.type return EMakeMinHeap(e.e, e.key_function).with_type(TMinHeap(elem_type, key_type)) if isinstance(e, EArgMax):
"""Additional internal syntax. While the syntax module declares the core _input_ language, this module declares additional syntax extensions that can appear in the _target_ language: the primitives the tool can output and use during synthesis. """ from cozy.syntax import * from cozy.common import declare_case, fresh_name # Misc TRef = declare_case(Type, "TRef", ["elem_type"]) EEnumToInt = declare_case(Exp, "EEnumToInt", ["e"]) # Execute a statement and then "return" the value of `out_var`. The statement # must declare `out_var` in its body. EStm = declare_case(Exp, "EStm", ["stm", "out_var"]) # State var barrier: sub-expression should be maintained as a fresh state var EStateVar = declare_case(Exp, "EStateVar", ["e"]) def statevar(e, ty): return EStateVar(e.with_type(ty)).with_type(ty) def EIsSingleton(e): arg = EVar(fresh_name()).with_type(e.type.elem_type) return EBinOp( EUnaryOp(UOp.Sum, EMap(e, ELambda(arg,