Beispiel #1
0
 def reduce(self, function):
     f = Function(("reduce", self), returns=self.element_type)
     f.code(
         """
             {{itype}} iterator;
             {{reset_fn}}(iterator);
             if (!({{is_valid_fn}}(iterator))) {
                 fprintf(stderr, "Reduce on empty iterator\\n");
                 exit(1);
             }
             {{type}} value = {{value_fn}}(iterator);
             {{next_fn}}(iterator);
             while({{is_valid_fn}}(iterator)) {
                 value = {{function}}(value, {{value_fn}}(iterator));
                 {{next_fn}}(iterator);
             }
             return value;
         """,
         function=function,
         itype=self.itype,
         type=self.element_type,
         value_fn=self.value_fn,
         next_fn=self.next_fn,
         reset_fn=self.reset_fn,
         is_valid_fn=self.is_valid_fn)
     return f()
Beispiel #2
0
    def __init__(self, domain, size):
        vector = Vector(domain.type)
        size = Int().value(size)

        if domain.iterator is not None:
            iterator = SequenceIterator(domain.iterator, size)
        else:
            iterator = None

        if domain.generator is not None:
            generator_fn = Function(("generator", self.name))
            generator_fn.returns(vector).code("""
                {{type}} result;
                size_t size = {{size}};
                result.reserve(size);
                for(size_t i = 0; i < size; i++) {
                    result.push_back({{generator}});
                }
                return result;
            """, generator=domain.generator, size=size, type=vector)
            generator = generator_fn()
        else:
            generator = None

        if domain.size is not None:
            size = Int().value(size)
            domain_size = power(domain.size, size)
        else:
            domain_size = None

        super().__init__(vector, iterator, generator, domain_size)
Beispiel #3
0
    def __init__(self, start, end=None, step=1):
        if end is None:
            end = start
            start = 0

        start = Int().value(start)
        end = Int().value(end)
        step = Int().value(step)

        iterator = RangeIterator(start, end, step)
        generator = rand_int(start, end)

        if (start.is_constructor() and start.value == 0 and
                step.is_constructor() and step.value == 1):
            size = end
            indexer = identity
        else:
            size = range_size(start, end, step)
            indexer = Function().returns(Int())
            indexer.takes(Int(), "_v")
            indexer.code("return (_v - {{start}}) / {{step}};",
                         start=start, step=step)

        super().__init__(Int(),
                         iterator,
                         generator,
                         size,
                         indexer)
Beispiel #4
0
 def first(self, if_empty_value=None):
     f = Function(("iterator_first", self), returns=self.element_type)
     if if_empty_value is None:
         f.code(
             """
                 {{itype}} iterator;
                 {{reset_fn}}(iterator);
                 assert ({{is_valid_fn}}(iterator));
                 return {{value_fn}}(iterator);
             """,
             itype=self.itype,
             reset_fn=self.reset_fn,
             is_valid_fn=self.is_valid_fn,
             value_fn=self.value_fn)
     else:
         f.code(
             """
                 {{itype}} iterator;
                 {{reset_fn}}(iterator);
                 if ({{is_valid_fn}}(iterator)) {
                     return {{value_fn}}(iterator);
                 } else {
                     return {{if_empty_value}};
                 }
             """,
             itype=self.itype,
             reset_fn=self.reset_fn,
             is_valid_fn=self.is_valid_fn,
             value_fn=self.value_fn,
             if_empty_value=self.element_type.value(if_empty_value))
     return f()
Beispiel #5
0
def addition_n(size):
     f = Function("add").returns(Int())
     for i in range(size):
        f.takes(Int())
     code = "+".join(p.name for p in f.params)
     f.code("return {};".format(code))
     return f
Beispiel #6
0
def multiplication_n(size):
     f = Function("mul").returns(Int())
     for i in range(size):
        f.takes(Int())
     code = "*".join(p.name for p in f.params)
     f.code("return {};".format(code))
     return f
Beispiel #7
0
 def is_nonempty(self):
     f = Function(("is_iterator_nonempty", self), returns=Bool())
     f.code(
         """
             {{itype}} iterator;
             {{reset_fn}}(iterator);
             return {{is_valid_fn}}(iterator);
         """,
         itype=self.itype,
         reset_fn=self.reset_fn,
         is_valid_fn=self.is_valid_fn)
     return f()
Beispiel #8
0
    def __init__(self, type, values):
        values = tuple(type.value(v) for v in values)
        iterator = ValuesIterator(type, values)

        generator = Function().returns(type)
        generator.code("""
            switch({{rand_int}}(0, {{_size}})) {
                {%- for i, v in _values %}
                case {{i}}: return {{b(v)}};
                {%- endfor %}
                default: assert(0);
            }
        """, _values=enumerate(values), _size=len(values), rand_int=rand_int)
        generator.uses(values)

        super().__init__(type, iterator, generator())
Beispiel #9
0
 def first_maybe(self):
     maybe = Maybe(self.element_type)
     f = Function(("iterator_first_maybe", self), returns=maybe)
     f.code(
         """
             {{itype}} iterator;
             {{reset_fn}}(iterator);
             if ({{is_valid_fn}}(iterator)) {
                 return {{maybe}}(Just, {{value_fn}}(iterator));
             } else {
                 return {{maybe}}(Nothing);
             }
         """,
         itype=self.itype,
         reset_fn=self.reset_fn,
         is_valid_fn=self.is_valid_fn,
         value_fn=self.value_fn,
         maybe=maybe)
     return f()
Beispiel #10
0
 def to_vector(self):
     vector = Vector(self.element_type)
     f = Function(returns=vector)
     f.code(
         """
             {{vector}} output;
             {{itype}} iterator;
             {{reset_fn}}(iterator);
             while({{is_valid_fn}}(iterator)) {
                 output.push_back({{value_fn}}(iterator));
                 {{next_fn}}(iterator);
             };
             return output;
         """,
         itype=self.itype,
         reset_fn=self.reset_fn,
         next_fn=self.next_fn,
         is_valid_fn=self.is_valid_fn,
         value_fn=self.value_fn,
         vector=vector)
     return f()
Beispiel #11
0
 def _make_generator(self, type, domains, ratios):
     generators = tuple(d.generator for d in domains)
     f = Function(returns=type)
     f.code("""
         qint s = 0;
         {%- for r in _ratios %}
         s += {{b(r)}};
         {%- if not loop.last %}
         qint r{{loop.index0}} = s;
         {%- endif %}
         {%- endfor %}
         qint r = {{rand_int}}(0, s);
         {%- for g in _generators %}
             {%- if not loop.last %}
             if (r < r{{loop.index0}})
             {% endif %}
             {
                 return {{b(g)}};
             }
         {%- endfor %}
     """, _generators=generators, _ratios=ratios, rand_int=rand_int)
     f.uses(generators + ratios)
     return f()
Beispiel #12
0
    def __init__(self, iterator, ascending=True, cmp_fn=None):
        itype = Int() * Vector(iterator.element_type)
        super().__init__(itype, iterator.element_type)

        if cmp_fn is None:
            cmp_fn = Function("compare").takes(iterator.element_type, "e1")\
                                        .takes(iterator.element_type, "e2")\
                                        .returns(Bool())
            cmp_fn.code("return e1 < e2;")

        # Since iter.v1 is never changed, we use it to detect
        # if reset_fn is called for the first time,
        # or if reset is used to restart existing iterator
        self.reset_fn.code("""
            iter.v0 = 0;
            if (iter.v1.size() == 0) {
                iter.v1 = {{vector}};
                std::sort(iter.v1.begin(), iter.v1.end(), {{compare}});
            }
        """, vector=iterator.to_vector(),
             compare=cmp_fn)
        self.next_fn.code("iter.v0++;");
        self.is_valid_fn.code("return iter.v0 < iter.v1.size();");
        self.value_fn.code("return iter.v1[iter.v0];");
Beispiel #13
0
 def prepare_write_function(self):
     from qit.base.function import Function
     from qit.base.file import File
     f = Function(("write", self.name))
     f.takes(File(), "output").takes(self, "value")
     return f
Beispiel #14
0
            indexer = identity
        else:
            size = range_size(start, end, step)
            indexer = Function().returns(Int())
            indexer.takes(Int(), "_v")
            indexer.code("return (_v - {{start}}) / {{step}};",
                         start=start, step=step)

        super().__init__(Int(),
                         iterator,
                         generator,
                         size,
                         indexer)


range_size = Function()
range_size.takes(Int(), "start")
range_size.takes(Int(), "end")
range_size.takes(Int(), "step")
range_size.returns(Int())
range_size.code("return (end - start) / step;")


class RangeIterator(Iterator):

    def __init__(self, start, end, step):
        itype = Int()
        super().__init__(itype, Int())
        self.reset_fn.code("iter = {{start}};", start=start)
        self.next_fn.code("iter+={{step}};", step=step)
        self.is_valid_fn.code("return iter < {{end}};", end=end)
Beispiel #15
0
 def key_fn(self):
     f = Function().takes(self, "keyval").returns(self.types[0])
     f.code("return keyval.key;")
     return f
Beispiel #16
0
 def value_fn(self):
     f = Function().takes(self, "keyval").returns(self.types[1])
     f.code("return keyval.value;")
     return f
Beispiel #17
0
 def min_fn(self):
     f = Function().takes(self, "keyval1").takes(self, "keyval2")
     f.returns(self)
     f.code("return keyval1.value > keyval2.value ? keyval2 : keyval1;")
     return f
Beispiel #18
0
from qit.base.function import Function
from qit.base.int import Int

rand_int = Function("rand_int")
rand_int.takes(Int(), "from").takes(Int(), "to")
rand_int.returns(Int())
rand_int.code("return std::uniform_int_distribution<qint>(from, to - 1)(QIT_GENERATOR);")
Beispiel #19
0
     return f

mul = multiplication_n(2)

def addition_n(size):
     f = Function("add").returns(Int())
     for i in range(size):
        f.takes(Int())
     code = "+".join(p.name for p in f.params)
     f.code("return {};".format(code))
     return f

add = addition_n(2)

# Naive way of making power, but it is sufficient for now
power = Function("power").takes(Int(), "base").takes(Int(), "power").returns(Int())
power.code("""
    int result = 1;
    int p = power;
    while(p > 0) {
        result *= base;
        p--;
    }
    return result;
""")

identity = Function("identity")
identity.takes(Int(), "a").returns(Int()).code("return a;")

subtract = Function("subtract")
subtract.takes(Int(), "a").takes(Int(), "b").returns(Int())
Beispiel #20
0
    def __init__(self, system, depth, return_depth):
        state_type = system.state_type
        sas_type = system.sas_type
        if return_depth:
            element_type = system.sas_depth_type
        else:
            element_type = sas_type

        eq_states_fn = system.eq_states_fn
        if eq_states_fn is None:
            eq_states_fn = Function("eq_states").takes(state_type, "s1")\
                                                .takes(state_type, "s2")\
                                                .returns(Bool())
            eq_states_fn.code("return s1 == s2;")

        cmp_states_fn = system.cmp_states_fn
        if cmp_states_fn is None:
            cmp_states_fn = Function("compare_states").takes(state_type, "s1")\
                                                      .takes(state_type, "s2")\
                                                      .returns(Bool())
            cmp_states_fn.code("return s1 < s2;")

        depth = Int().value(depth)
        state_ids_type = Map(state_type, Int(), cmp_states_fn)
        itype = Struct((state_ids_type,     "state_ids"),
                       (Vector(state_type), "current"),
                       (Vector(state_type), "next"),
                       (Vector(sas_type),   "buff_values"),
                       (sas_type,           "value"),
                       (Int(),              "rule"),
                       (Int(),              "depth"),
                       (Int(),              "gen_state_id"))
        super().__init__(itype, element_type)

        functions = tuple(rule.function for rule in system.rules)

        action_type1  = None
        action_type2  = None
        new_value_fn  = None
        new_values_fn = None

        if functions:
            action_type1 = Functor("atype1", state_type, (state_type, "s"))
            new_value_fn = Function("compute_new_value")\
                            .takes(itype, "iter", const=False)\
                            .takes(state_type, "current")\
                            .takes(system.action_names, "action_name")\
                            .takes(action_type1, "action_fn")\
                            .returns(Vector(sas_type))
            new_value_fn.code("""
                {{state}} new_state = action_fn(current);
                auto it = iter.state_ids.find(new_state);
                if (it == iter.state_ids.end()) {
                    iter.state_ids[new_state] = ++iter.gen_state_id;
                    iter.next.push_back(new_state);
                }
                return { {{sas}}(iter.state_ids[current], action_name, iter.state_ids[new_state]) };
            """, state=state_type,
                 sas=sas_type)

            action_type2 = Functor(
                    "atype1", Vector(state_type), (state_type, "s"))
            new_values_fn = Function("compute_new_values")\
                            .takes(itype, "iter", const=False)\
                            .takes(state_type, "current")\
                            .takes(system.action_names, "action_name")\
                            .takes(action_type2, "action_fn")\
                            .returns(Vector(sas_type))
            new_values_fn.code("""
                std::vector<{{sas}} > buff;
                std::vector<{{state}} > new_states = action_fn(current);
                for ({{state}} &s : new_states) {
                    auto s_it = iter.state_ids.find(s);
                    if (s_it == iter.state_ids.end()) {
                        iter.state_ids[s] = ++iter.gen_state_id;
                        iter.next.push_back(s);
                    }

                    {{sas}} value(iter.state_ids[current], action_name, iter.state_ids[s]);
                    auto sas_it = std::find(buff.begin(), buff.end(), value);
                    if (sas_it == buff.end()) {
                        buff.push_back(value);
                    }
                }

                std::reverse(buff.begin(), buff.end());
                return buff;
            """, state=state_type,
                 sas=sas_type)

            functions += (new_value_fn, new_values_fn)

        self.reset_fn.code("""
            iter.gen_state_id = 0;
            iter.rule = 0;
            iter.depth = 0;
            iter.state_ids = {{states_empty_map}};
            iter.current = {{vector}};
            if (iter.current.size() > 1) {
                std::sort(iter.current.begin(), iter.current.end());
                // same initial states are reducet to only one
                auto it = std::unique(iter.current.begin(), iter.current.end(), {{eq_states}});
                iter.current.resize(std::distance( iter.current.begin(), it));
            }
            for (auto &e : iter.current) {
                iter.state_ids[e] = ++iter.gen_state_id;
            }
            iter.next.clear();

            {# first call of the next function fills first values, if there are some #}
            {{next_fn}}(iter);
            if (iter.buff_values.size() == 0) {
                iter.current.clear();
            }
        """, vector=system.state_iterator.to_vector(),
             states_empty_map=state_ids_type.value( {} ),
             eq_states=eq_states_fn,
             next_fn=self.next_fn)

        self.next_fn.code("""
            {%- if _new_value is not none %}
            if (iter.buff_values.size() > 0) {
                iter.buff_values.pop_back(); // remove the previous one
                // set value if there is some
                if (iter.buff_values.size() > 0) {
                    iter.value = iter.buff_values[iter.buff_values.size()-1];
                    return;
                }
            }

            for (;;) {
                if (iter.current.size() == 0) {
                    if (iter.next.size() == 0 || iter.depth >= {{depth}}) {
                        iter.next.clear();
                        return;
                    }
                    iter.depth++;
                    std::swap(iter.current, iter.next);
                }

                switch(iter.rule) {
                {%- for rule in _rules %}
                case {{loop.index0}}: {
                    {# different functions for types one value and more values #}

                    {%- if rule.rule_type == 0 %}
                    iter.buff_values = {{b(_new_value)}}(
                        iter, iter.current[iter.current.size()-1],
                        {{action}}(iter.rule), {{b(rule.function)}});
                    {%- endif %}

                    {%- if rule.rule_type == 1 %}
                    iter.buff_values = {{b(_new_values)}}(
                        iter, iter.current[iter.current.size()-1],
                        {{action}}(iter.rule), {{b(rule.function)}});
                    {%- endif %}

                    iter.rule++;
                    if (iter.buff_values.size() > 0) {
                        iter.value = iter.buff_values[iter.buff_values.size()-1];
                        return;
                    }
                }
                {%- endfor %}
                default:
                    iter.rule = 0;
                    iter.current.pop_back();
                }
            }
            {%- endif %}
        """, _rules=system.rules,
             _new_value=new_value_fn,
             _new_values=new_values_fn,
             action=system.action_names,
             depth=depth).uses(functions)

        self.is_valid_fn.code("""
            return !(iter.current.size() == 0 && iter.next.size() == 0 && iter.buff_values.size() == 0);
        """)

        if return_depth:
            self.value_fn.code(
                "return { iter.value, iter.depth };")
        else:
            self.value_fn.code(
                "return iter.value;")
Beispiel #21
0
from qit.base.function import Function
from qit.base.int import Int

def multiplication_n(size):
     f = Function().returns(Int())
     for i in range(size):
        f.takes(Int())
     code = "*".join(p.name for p in f.params)
     f.code("return {};".format(code))
     return f

# Naive way of making power, but it is sufficient for now
power = Function().takes(Int(), "base").takes(Int(), "power").returns(Int())
power.code("""
    int result = 1;
    int p = power;
    while(p > 0) {
        result *= base;
        p--;
    }
    return result;
""")

identity = Function().takes(Int(), "a").returns(Int()).code("return a;")

subtract = Function().takes(Int(), "a").takes(Int(), "b").returns(Int())
subtract.code("return a - b;")

add = Function().takes(Int(), "a").takes(Int(), "b").returns(Int())
add.code("return a + b;")