git @ Cat's Eye Technologies Samovar / master src / samovar / generators / stochastic.py
master

Tree @master (Download .tar.gz)

stochastic.py @masterraw · history · blame

# encoding: UTF-8

import sys

from samovar.database import Database

from .base import xrange, Event, BaseGenerator


class StochasticGenerator(BaseGenerator):
    def __init__(self, world, scenario, verbosity=0, sorted_search=True, randomness=None):
        self.world = world
        self.scenario = scenario
        self.verbosity = verbosity
        self.sorted_search = sorted_search
        self.random = randomness
        self.reset_state()

    def reset_state(self):
        self.state = Database(self.scenario.propositions, sorted_search=self.sorted_search)

    def generate_events(self, min_count=0, max_count=100, lengthen_factor=1.5):
        acceptable = False
        count = min_count
        while not acceptable:
            if self.verbosity >= 1:
                sys.stderr.write("Generating {} events\n".format(count))
            self.reset_state()
            if self.verbosity >= 2:
                self.debug_state(self.state, "Initial")
            events = []
            for i in xrange(0, count):
                event = self.generate_event()
                if event is None:
                    break
                events.append(event)
            if self.verbosity >= 2:
                self.debug_state(self.state, "Final")
            acceptable = self.goal_is_met(self.state)
            if not acceptable:
                count = int(float(count) * lengthen_factor)
            if count > max_count:
                raise ValueError("{}: count exceeds maximum".format(self.scenario.name))
        return events

    def generate_event(self):
        candidates = list(self.candidate_rules(self.state))

        if self.verbosity >= 3:
            sys.stderr.write("Candidate rules:\n")
            for rule, unifiers in candidates:
                sys.stderr.write("-> " + rule.to_json() + "\n")
                sys.stderr.write("---> {}\n".format(unifiers))
            sys.stderr.write("")

        if not candidates:
            return None
        rule, unifier = self.random.choice(candidates)
        self.update_state(self.state, unifier, rule)
        if self.verbosity >= 3:
            self.debug_state(self.state, "Intermediate")
        return Event(rule, unifier)