Esempio n. 1
0
	def __init__(self, head, body):
		self.__head = head
		self.__body = body
		
		# relations between variables like < <= = !=
		# also for relations between variables and constants
		# self.__var_rels = {}
	
		# a list  (body_index1,pos1,body_index2,pos2,comparison operator)
		self.__var_constraints = []

		# explicitly add all equality constraints between variables
		for bi1, b1 in enumerate(self.__body):
			positions1 = PositionIndex.get_all_positions(b1)
			for p1 in positions1:
				v1 = p1.fetch(b1)
				if isinstance(v1, Variable):
					# can't use enumerate here, have to preserve correct indexing
					# for bi2
					for bi2, b2 in zip(range(bi1, len(self.__body)), self.__body[bi1:]):
						positions2 = PositionIndex.get_all_positions(b2)
						for p2 in positions2:
							v2 = p2.fetch(b2)
							if isinstance(v2, Variable):
								if (p1 != p2 or bi1 != bi2) and v1 == v2:
									self.__var_constraints.append((bi1, p1, bi2, p2, Comparison('==')))

		# a mapping head_pos -> [(body_index, body_pos)]
		self.__headvar_bindings = {}

		hpositions = PositionIndex.get_all_positions(head)
		for hp in hpositions:
			hv = hp.fetch(head)
			if not isinstance(hv, Variable):
				continue
			bound = False
			for bi, b in enumerate(self.__body):
				bpositions = PositionIndex.get_all_positions(b)
				for bp in bpositions:
					bv = bp.fetch(b)
					if isinstance(bv, Variable):
						if (hv == bv):
							self.__headvar_bindings.setdefault(hp, []).append((bi, bp))
							bound = True

			#assert bound, "Head variable %s not bound to any body variables" % hv
			if not bound:
				print >> sys.stderr, "Head variable %s not bound to any body variables" % hv

		# equality constraints on head
		self.__headvar_constraints = []
		for i, p1 in enumerate(hpositions):
			t1 = p1.fetch(head)
			if isinstance(t1, Variable):
				for p2 in hpositions[i+1:]:
					t2 = p2.fetch(head)
					if t1 == t2:
						self.__headvar_constraints.append((p1, p2))

		CacheHash.__init__(self)
Esempio n. 2
0
    def add_condition(self, cond):
        self.__body.append(cond)
        nbi = len(self.__body) - 1

        # add variable equality comparisons
        for bi1, b1 in enumerate(self.__body):
            positions1 = PositionIndex.get_all_positions(b1)
            for p1 in positions1:
                v1 = p1.fetch(b1)
                if isinstance(v1, Variable):
                    positions2 = PositionIndex.get_all_positions(cond)
                    for p2 in positions2:
                        v2 = p2.fetch(cond)
                        if isinstance(v2, Variable):
                            if (p1 != p2 or bi1 != nbi) and v1 == v2:
                                self.__var_constraints.append(
                                    (bi1, p1, nbi, p2, Comparison('==')))

        # add head bindings
        hpositions = PositionIndex.get_all_positions(self.__head)
        for hp in hpositions:
            hv = hp.fetch(self.__head)
            if not isinstance(hv, Variable):
                continue
            bpositions = PositionIndex.get_all_positions(cond)
            for bp in bpositions:
                bv = bp.fetch(cond)
                if isinstance(bv, Variable):
                    if (hv == bv):
                        self.__headvar_bindings.setdefault(hp, []).append(
                            (nbi, bp))

        self.recalc_hash()
Esempio n. 3
0
	def add_condition(self, cond):
		self.__body.append(cond)
		nbi = len(self.__body) - 1

		# add variable equality comparisons
		for bi1, b1 in enumerate(self.__body):
			positions1 = PositionIndex.get_all_positions(b1)
			for p1 in positions1:
				v1 = p1.fetch(b1)
				if isinstance(v1, Variable):
					positions2 = PositionIndex.get_all_positions(cond)
					for p2 in positions2:
						v2 = p2.fetch(cond)
						if isinstance(v2, Variable):
							if (p1 != p2 or bi1 != nbi) and v1 == v2:
								self.__var_constraints.append((bi1, p1, nbi, p2, Comparison('==')))

		# add head bindings
		hpositions = PositionIndex.get_all_positions(self.__head)
		for hp in hpositions:
			hv = hp.fetch(self.__head)
			if not isinstance(hv, Variable):
				continue
			bpositions = PositionIndex.get_all_positions(cond)
			for bp in bpositions:
				bv = bp.fetch(cond)
				if isinstance(bv, Variable):
					if (hv == bv):
						self.__headvar_bindings.setdefault(hp, []).append((nbi, bp))

		self.recalc_hash()
Esempio n. 4
0
    def __init__(self, head, body):
        self.__head = head
        self.__body = body

        # relations between variables like < <= = !=
        # also for relations between variables and constants
        # self.__var_rels = {}

        # a list  (body_index1,pos1,body_index2,pos2,comparison operator)
        self.__var_constraints = []

        # explicitly add all equality constraints between variables
        for bi1, b1 in enumerate(self.__body):
            positions1 = PositionIndex.get_all_positions(b1)
            for p1 in positions1:
                v1 = p1.fetch(b1)
                if isinstance(v1, Variable):
                    # can't use enumerate here, have to preserve correct indexing
                    # for bi2
                    for bi2, b2 in zip(range(bi1, len(self.__body)),
                                       self.__body[bi1:]):
                        positions2 = PositionIndex.get_all_positions(b2)
                        for p2 in positions2:
                            v2 = p2.fetch(b2)
                            if isinstance(v2, Variable):
                                if (p1 != p2 or bi1 != bi2) and v1 == v2:
                                    self.__var_constraints.append(
                                        (bi1, p1, bi2, p2, Comparison('==')))
Esempio n. 5
0
	def __init__(self, head, body):
		self.__head = head
		self.__body = body
		
		# relations between variables like < <= = !=
		# also for relations between variables and constants
		# self.__var_rels = {}
	
		# a list  (body_index1,pos1,body_index2,pos2,comparison operator)
		self.__var_constraints = []

		# explicitly add all equality constraints between variables
		for bi1, b1 in enumerate(self.__body):
			positions1 = PositionIndex.get_all_positions(b1)
			for p1 in positions1:
				v1 = p1.fetch(b1)
				if isinstance(v1, Variable):
					# can't use enumerate here, have to preserve correct indexing
					# for bi2
					for bi2, b2 in zip(range(bi1, len(self.__body)), self.__body[bi1:]):
						positions2 = PositionIndex.get_all_positions(b2)
						for p2 in positions2:
							v2 = p2.fetch(b2)
							if isinstance(v2, Variable):
								if (p1 != p2 or bi1 != bi2) and v1 == v2:
									self.__var_constraints.append((bi1, p1, bi2, p2, Comparison('==')))
Esempio n. 6
0
	def add_var_constraint(self, v1, v2, comparison):
		for bi1, b1 in enumerate(self.__body):
			pos1 = PositionIndex.get_positions(b1, v1)
			if len(pos1) > 0:
				for bi2, b2 in enumerate(self.__body):
					pos2 = PositionIndex.get_positions(b2, v2)
					for p1 in pos1:
						for p2 in pos2:
							if p1 != p2 or bi1 != bi2:
								self.__var_constraints.append((bi1, p1, bi2, p2, comparison))
Esempio n. 7
0
 def add_var_constraint(self, v1, v2, comparison):
     for bi1, b1 in enumerate(self.__body):
         pos1 = PositionIndex.get_positions(b1, v1)
         if len(pos1) > 0:
             for bi2, b2 in enumerate(self.__body):
                 pos2 = PositionIndex.get_positions(b2, v2)
                 for p1 in pos1:
                     for p2 in pos2:
                         if p1 != p2 or bi1 != bi2:
                             self.__var_constraints.append(
                                 (bi1, p1, bi2, p2, comparison))
Esempio n. 8
0
 def rbclicked(self):
     if self.bg1.checkedId() == 1:
         self.searchEngine = BooleanIndex
         VectorSpaceIndex.releaseSpace()
         PositionIndex.releasespace()
         bm25.releasespace()
         WildCardIndex.releasespace()
     elif self.bg1.checkedId() == 2:
         self.searchEngine = VectorSpaceIndex
         BooleanIndex.releaseSpace()
         PositionIndex.releasespace()
         bm25.releasespace()
         WildCardIndex.releasespace()
     elif self.bg1.checkedId() == 3:
         self.searchEngine = bm25
         VectorSpaceIndex.releaseSpace()
         BooleanIndex.releaseSpace()
         PositionIndex.releasespace()
         WildCardIndex.releasespace()
     elif self.bg1.checkedId() == 4:
         self.searchEngine = PositionIndex
         VectorSpaceIndex.releaseSpace()
         BooleanIndex.releaseSpace()
         bm25.releasespace()
         WildCardIndex.releasespace()
     elif self.bg1.checkedId() == 5:
         self.searchEngine = WildCardIndex
         PositionIndex.releasespace()
         VectorSpaceIndex.releaseSpace()
         BooleanIndex.releaseSpace()
         bm25.releasespace()
Esempio n. 9
0
def get_all_constants(grounds):
	consts = set()
	for g in grounds:
		poses = PositionIndex.get_all_positions(g)
		for p in poses:
			consts.add(p.fetch(g))
	return consts
Esempio n. 10
0
def get_all_constants(grounds):
    consts = set()
    for g in grounds:
        poses = PositionIndex.get_all_positions(g)
        for p in poses:
            consts.add(p.fetch(g))
    return consts
Esempio n. 11
0
 def get_var_terms(self):
     result = []
     positions = PositionIndex.get_all_positions(self)
     for p in positions:
         term = p.fetch(self)
         if isinstance(term, Variable):
             result.append(p, term)
     return result
Esempio n. 12
0
	def get_var_terms(self):
		result = []
		positions = PositionIndex.get_all_positions(self)
		for p in positions:
			term = p.fetch(self)
			if isinstance(term, Variable):
				result.append(p, term)
		return result
Esempio n. 13
0
def build_constant_relations(int_rep, map = {}):
	consts2rels = {} # const -> [(pos, rel)]
	for s in int_rep.get_statics():
		rel = s.get_relation()
		for p in PositionIndex.get_all_positions(s):
			term = p.fetch(s)
			if isinstance(term, Constant) and isinstance(term.get_name(), str) and term.get_name() not in exclude:
				if rel in map:
					rel = map[rel]
				consts2rels.setdefault(term.get_name(), []).append((p, rel))
	return consts2rels
Esempio n. 14
0
def build_constant_relations(int_rep, map={}):
    consts2rels = {}  # const -> [(pos, rel)]
    for s in int_rep.get_statics():
        rel = s.get_relation()
        for p in PositionIndex.get_all_positions(s):
            term = p.fetch(s)
            if isinstance(term, Constant) and isinstance(
                    term.get_name(), str) and term.get_name() not in exclude:
                if rel in map:
                    rel = map[rel]
                consts2rels.setdefault(term.get_name(), []).append((p, rel))
    return consts2rels
Esempio n. 15
0
def build_c2p(int_rep, map = {}):
	""" returns a map of constants to the predicates that they appear in """

	c2p = {} # const -> [(pos, pred)]
	for g in int_rep.get_statics() + int_rep.get_inits():
		pred = g.get_predicate()
		for p in PositionIndex.get_all_positions(g):
			term = p.fetch(g)
			if isinstance(term, Constant) and \
					isinstance(term.get_name(), str) and \
					term.get_name() not in exclude:
				c2p.setdefault(term.get_name(), []).append((p, pred))
	return c2p
Esempio n. 16
0
def build_c2p(int_rep, map={}):
    """ returns a map of constants to the predicates that they appear in """

    c2p = {}  # const -> [(pos, pred)]
    for g in int_rep.get_statics() + int_rep.get_inits():
        pred = g.get_predicate()
        for p in PositionIndex.get_all_positions(g):
            term = p.fetch(g)
            if isinstance(term, Constant) and \
              isinstance(term.get_name(), str) and \
              term.get_name() not in exclude:
                c2p.setdefault(term.get_name(), []).append((p, pred))
    return c2p
Esempio n. 17
0
def check_min_max(r, ec, score):
    "Find indications that a number is to be minimized, maximized"

    place_types = {}
    for b in r.get_body():
        pos = PositionIndex.get_all_positions(b)
        for p in pos:
            term = p.fetch(b)
            if isinstance(term, Constant) and term.get_name() == 0:
                c = ec.get_or_make_class((b.get_predicate(), p))
                if score == 100 ^ b.is_negated():
                    ec.set_class_type(c, placetype.NUM_MIN)
                else:
                    ec.set_class_type(c, placetype.NUM_MAX)

    return place_types
Esempio n. 18
0
def check_min_max(r, ec, score):
	"Find indications that a number is to be minimized, maximized"

	place_types = {}
	for b in r.get_body():
		pos = PositionIndex.get_all_positions(b)
		for p in pos:
			term = p.fetch(b)
			if isinstance(term, Constant) and term.get_name() == 0:
				c = ec.get_or_make_class((b.get_predicate(), p))
				if score == 100 ^ b.is_negated():
					ec.set_class_type(c, placetype.NUM_MIN)
				else:
					ec.set_class_type(c, placetype.NUM_MAX)

	return place_types
Esempio n. 19
0
	def expand(self, r, bi):
		expanded = []
		b = r.get_body()[bi]
		pred = b.get_predicate()
		assert pred in self.__g_elabs

		for elab in self.__g_elabs[pred]:
			ehead = elab.get_head()
			conflict = False
			for p in PositionIndex.get_all_positions(b):
				t1 = p.fetch(b)
				t2 = p.fetch(ehead)
				if isinstance(t1, Constant) and isinstance(t2, Constant) and t1 != t2:
					# this elab rule is incompatible
					conflict = True
					break
			if conflict:
				continue
			r_copy = r.copy()
			elab_copy = elab.copy()
			expanded.extend(self.expand_with_rule(r_copy, bi, elab_copy))
		
		return expanded
Esempio n. 20
0
    def expand(self, r, bi):
        expanded = []
        b = r.get_body()[bi]
        pred = b.get_predicate()
        assert pred in self.__g_elabs

        for elab in self.__g_elabs[pred]:
            ehead = elab.get_head()
            conflict = False
            for p in PositionIndex.get_all_positions(b):
                t1 = p.fetch(b)
                t2 = p.fetch(ehead)
                if isinstance(t1, Constant) and isinstance(
                        t2, Constant) and t1 != t2:
                    # this elab rule is incompatible
                    conflict = True
                    break
            if conflict:
                continue
            r_copy = r.copy()
            elab_copy = elab.copy()
            expanded.extend(self.expand_with_rule(r_copy, bi, elab_copy))

        return expanded
Esempio n. 21
0
from PositionIndex import PositionIndex

comp_rels = ['<', '>', '>=', 'lessThan', 'greaterThan', 'succ']
math_op_rels = ['+', '-', '*', '/', 'min', 'minus', 'plus']
obj_loc_place = set([('location', PositionIndex([0, 0]))])
coord_places = set([('location', PositionIndex([0, p])) for p in [1, 2]])

# an equivalence class that has one of these places as a member must
# be a number
num_places = set([(c, PositionIndex([0])) for c in comp_rels] + \
                 [(c, PositionIndex([1])) for c in comp_rels] + \
                 [(o, PositionIndex([0])) for o in math_op_rels] + \
                 [(o, PositionIndex([1])) for o in math_op_rels] + \
                 [(o, PositionIndex([2])) for o in math_op_rels] + \
                 [('int', PositionIndex([0]))])

# these are the place types
AGENT, OBJECT, COORD, NUM_MAX, NUM_MIN, NUM, UNKNOWN = range(7)

# for string output
type_names = {
    AGENT: 'agent',
    OBJECT: 'object',
    COORD: 'coord',
    NUM_MAX: 'num_max',
    NUM_MIN: 'num_min',
    NUM: 'num',
    UNKNOWN: 'unknown'
}

# specificity ordering relations
Esempio n. 22
0
	for src_p in pred_order:
		tgt_p = pred_map[src_p]

		print src_p, tgt_p

		if src_p not in src_gnds or tgt_p not in tgt_gnds:
			print >> sys.stderr, "PROBABLY A BAD MATCH BETWEEN %s AND %s" % (src_p, tgt_p)
			continue

		matches = cross_product(src_gnds[src_p], tgt_gnds[tgt_p])

		# get the position mapping this is fake right now, but we should get this
		# from a different script in the future right now just assume all the
		# constant positions are preserved
		tmp_src_g, tmp_tgt_g = matches[0]
		src_p = PositionIndex.get_all_positions(tmp_src_g)
		tgt_p = PositionIndex.get_all_positions(tmp_tgt_g)
		pmap = dict([(p, p) for p in src_p if p in tgt_p])

		# here we're going to match up all the grounds for this predicate
		# the order of the matching is random and can affect the quality of the
		# match, but I don't have any good idea about how to do it right now
		matches = filter_matches(matches, cmap, pmap)
		while len(matches) > 0:
			src_g, tgt_g = matches.pop()
			commit_ground_match(src_g, tgt_g, cmap, pmap)
			matches = filter_matches(matches, cmap, pmap)

	for sp, tp in pred_map.items():
		print 'map predicate %s %s' % (sp, tp)
Esempio n. 23
0
        tgt_p = pred_map[src_p]

        print src_p, tgt_p

        if src_p not in src_gnds or tgt_p not in tgt_gnds:
            print >> sys.stderr, "PROBABLY A BAD MATCH BETWEEN %s AND %s" % (
                src_p, tgt_p)
            continue

        matches = cross_product(src_gnds[src_p], tgt_gnds[tgt_p])

        # get the position mapping this is fake right now, but we should get this
        # from a different script in the future right now just assume all the
        # constant positions are preserved
        tmp_src_g, tmp_tgt_g = matches[0]
        src_p = PositionIndex.get_all_positions(tmp_src_g)
        tgt_p = PositionIndex.get_all_positions(tmp_tgt_g)
        pmap = dict([(p, p) for p in src_p if p in tgt_p])

        # here we're going to match up all the grounds for this predicate
        # the order of the matching is random and can affect the quality of the
        # match, but I don't have any good idea about how to do it right now
        matches = filter_matches(matches, cmap, pmap)
        while len(matches) > 0:
            src_g, tgt_g = matches.pop()
            commit_ground_match(src_g, tgt_g, cmap, pmap)
            matches = filter_matches(matches, cmap, pmap)

    for sp, tp in pred_map.items():
        print 'map predicate %s %s' % (sp, tp)
Esempio n. 24
0
def get_predicates(rules, roles):
	"""Extract predicate information from the rules"""

	preds = set()
	pred_names = set()
	predTypes = {}
	# maps places to the equivalence class they're in
	ec = TypedEquivalenceClass()
	for r in rules:
		goal_place_types = {}
		if r.get_head().get_relation() == 'goal':
			score = r.get_head().get_term(1).get_name()
			if score == 0 or score == 100:
				# we can't really say anything about the middle cases
				goal_place_types = check_min_max(r, ec, score)
				score = r.get_head().get_term(1)
			sentences = r.get_body()
		elif r.get_head().get_relation() == 'terminal':
			sentences = r.get_body()
		else:
			sentences = [r.get_head()] + r.get_body()

		for i,s1 in enumerate(sentences):
			s1pred = s1.get_predicate()
			assert s1pred != None

			if s1pred in placetype.preset_types:
				# the first place is supposed to get acted upon, not act upon the
				# second place. The preset places are not to be acted upon
				continue

			predTypes[s1pred] = s1.get_type()
			
			s1pos = PositionIndex.get_all_positions(s1)
			for p1 in s1pos:
				ec.get_or_make_class((s1pred, p1))

			if len(s1pos) == 0:
				preds.add(Predicate(s1pred, s1.get_type(), ()))
				pred_names.add(s1pred)
				continue
			
			added = False
			for s2 in sentences[i+1:]:
				s2pred = s2.get_predicate()
				s2pos = PositionIndex.get_all_positions(s2)
	
				assert s1pred != None and s2pred != None

				for p1 in s1pos:
					place1 = (s1pred, p1)
					t1 = p1.fetch(s1)
					c1 = ec.get_or_make_class(place1)
					if place1 in placetype.preset_types:
						ec.set_class_type(c1, placetype.preset_types[place1])
					for p2 in s2pos:
						place2 = (s2pred, p2)
						t2 = p2.fetch(s2)
						if isinstance(t1, Variable) and isinstance(t2, Variable) and \
								t1 == t2:
							if place2 in goal_place_types:
								ec.set_class_type(c1, goal_place_types[place2])
							elif place2 in placetype.preset_types:
								ec.set_class_type(c1, placetype.preset_types[place2])
							else:
								# put these two places in the same equivalence class
								place1 = (s1pred, p1)
								place2 = (s2pred, p2)
								ec.make_equivalent(place1, place2)

	
	# run through the rules again.  If a role constant appears somewhere, and
	# no non-role constants appear in that place, then that place is an agent
	possible_agent_places = set()
	impossible_agent_places = set()
	for r in rules:
		if r.get_head().get_predicate() != None:
			sentences = [r.get_head()] + r.get_body()
		else:
			sentences = r.get_body()
		for s in sentences:
			for p in PositionIndex.get_all_positions(s):
				place = (s.get_predicate(), p)
				t = p.fetch(s)
				if t in roles:
					if place not in impossible_agent_places:
						possible_agent_places.add(place)
				else:
					if isinstance(t, Constant):
						impossible_agent_places.add(place)
						possible_agent_places.discard(place)
	
	collected = {}
	for place in ec.get_all_members():
		if place in possible_agent_places:
			type = placetype.AGENT
		else:
			type = ec.get_member_type(place)
		collected.setdefault(place[0],[]).append((place, type))

	for p, types in collected.items():
		types.sort(lambda x,y: cmp(x[0],y[0]))
		types_no_place = [t[1] for t in types]
		preds.add(Predicate(p, predTypes[p], types_no_place))
		pred_names.add(p)

	# go over one more time and see if we missed anything
	for r in rules:
		sentences = [r.get_head()] + r.get_body()
		for s in sentences:
			p = s.get_predicate()
			if p == None:
				continue
			if p not in pred_names:
				pos = PositionIndex.get_all_positions(s)
				preds.add(Predicate(p, s.get_type(), tuple([placetype.UNKNOWN] * len(pos))))

	return preds
Esempio n. 25
0
    def expand_with_rule(self, r, bi, elab):
        expanded = []
        b = r.get_body()[bi]
        elab_head = elab.get_head()
        positions = PositionIndex.get_all_positions(b)
        assert positions == PositionIndex.get_all_positions(elab_head)

        # this is so there won't be name collisions
        elab.mangle_vars("__cr_")

        # first we have to add the equality constraints constraints from the head
        # of the elab rule to the condition which is being substituted.
        for p1, p2 in elab.get_headvar_constraints():
            r.add_pos_constraint(bi, p1, bi, p2, Comparison('=='))

        # propagate the constraints throughout the rule
        r.enforce_equality()

        # make the head of the elab rule and the condition being expanded look
        # exactly the same
        preserve_vars = []
        terms = [p.fetch(b) for p in positions]
        for p, t in zip(positions, terms):
            elab_term = p.fetch(elab_head)
            if t == elab_term:
                continue
            if isinstance(elab_term, Constant) and isinstance(t, Variable):
                p.set(b, elab_term.copy())
            elif isinstance(elab_term, Variable) and isinstance(t, Constant):
                p.set(elab_head, t.copy())
            elif isinstance(elab_term, Variable) and isinstance(t, Variable):
                # should change the variables in the elab rule to match the
                # expanded rule. Since the equality constraints on the head
                # variables are already applied to the substituted condition,
                # we should have that if two variables in the elab head are
                # equal, those variables in the condition are equal too
                p.set(elab_head, t.copy())
                preserve_vars.append(t.get_name())
            else:
                assert t == elab_term

        r.enforce_equality(preserve_vars)
        elab.enforce_equality(preserve_vars)

        offset = r.num_conditions()
        gr_head = elab.get_head()

        # for each constraint that applied to the condition
        # being expanded, we have to insert duplicates of
        # those that apply to the inserted conditions

        # we're going to append all the new rules to the end of
        # the body first, and then add and modify the approriate
        # constraints. After everything is done, remove the body
        # condition that was substituted

        # no variable equalities should be drawn here
        for grb in elab.get_body():
            r.add_condition(grb)

        # add the variable constraints
        for p in positions:
            if isinstance(p.fetch(gr_head), Constant):
                continue
            b2b_cons = r.get_constraints_on(bi, p)  # body-to-body constraints
            hv_bindings = elab.get_headvar_binding(p)
            for old_i, old_p, comp, order in b2b_cons:
                for bound_i, bound_p in hv_bindings:
                    if order == 0:
                        # head var first
                        r.add_pos_constraint(offset + bound_i, bound_p, old_i,
                                             old_p, comp)
                    else:
                        r.add_pos_constraint(old_i, old_p, offset + bound_i,
                                             bound_p, comp)

                    if comp.relation() == '==':
                        # have to rename the variables in original condition to
                        # equal new condition
                        new_cond = r.get_cond(bound_i + offset)
                        new_name = bound_p.fetch(new_cond)
                        old_p.set(r.get_cond(old_i), new_name)

        # finally remove the replaced condition
        r.remove_condition(bi)
        expanded.append(r)

        return expanded
Esempio n. 26
0
    def __init__(self, head, body):
        self.__head = head
        self.__body = body

        # relations between variables like < <= = !=
        # also for relations between variables and constants
        # self.__var_rels = {}

        # a list  (body_index1,pos1,body_index2,pos2,comparison operator)
        self.__var_constraints = []

        # explicitly add all equality constraints between variables
        for bi1, b1 in enumerate(self.__body):
            positions1 = PositionIndex.get_all_positions(b1)
            for p1 in positions1:
                v1 = p1.fetch(b1)
                if isinstance(v1, Variable):
                    # can't use enumerate here, have to preserve correct indexing
                    # for bi2
                    for bi2, b2 in zip(range(bi1, len(self.__body)),
                                       self.__body[bi1:]):
                        positions2 = PositionIndex.get_all_positions(b2)
                        for p2 in positions2:
                            v2 = p2.fetch(b2)
                            if isinstance(v2, Variable):
                                if (p1 != p2 or bi1 != bi2) and v1 == v2:
                                    self.__var_constraints.append(
                                        (bi1, p1, bi2, p2, Comparison('==')))

        # a mapping head_pos -> [(body_index, body_pos)]
        self.__headvar_bindings = {}

        hpositions = PositionIndex.get_all_positions(head)
        for hp in hpositions:
            hv = hp.fetch(head)
            if not isinstance(hv, Variable):
                continue
            bound = False
            for bi, b in enumerate(self.__body):
                bpositions = PositionIndex.get_all_positions(b)
                for bp in bpositions:
                    bv = bp.fetch(b)
                    if isinstance(bv, Variable):
                        if (hv == bv):
                            self.__headvar_bindings.setdefault(hp, []).append(
                                (bi, bp))
                            bound = True

            #assert bound, "Head variable %s not bound to any body variables" % hv
            if not bound:
                print >> sys.stderr, "Head variable %s not bound to any body variables" % hv

        # equality constraints on head
        self.__headvar_constraints = []
        for i, p1 in enumerate(hpositions):
            t1 = p1.fetch(head)
            if isinstance(t1, Variable):
                for p2 in hpositions[i + 1:]:
                    t2 = p2.fetch(head)
                    if t1 == t2:
                        self.__headvar_constraints.append((p1, p2))

        CacheHash.__init__(self)
Esempio n. 27
0
	def expand_with_rule(self, r, bi, elab):
		expanded = []
		b = r.get_body()[bi]
		elab_head = elab.get_head()
		positions = PositionIndex.get_all_positions(b)
		assert positions == PositionIndex.get_all_positions(elab_head)

		# this is so there won't be name collisions
		elab.mangle_vars("__cr_")
		
		# first we have to add the equality constraints constraints from the head
		# of the elab rule to the condition which is being substituted.
		for p1,p2 in elab.get_headvar_constraints():
			r.add_pos_constraint(bi, p1, bi, p2, Comparison('=='))
		
		# propagate the constraints throughout the rule
		r.enforce_equality()
		
		# make the head of the elab rule and the condition being expanded look
		# exactly the same
		preserve_vars = []
		terms = [p.fetch(b) for p in positions]
		for p, t in zip(positions, terms):
			elab_term = p.fetch(elab_head)
			if t == elab_term:
				continue
			if isinstance(elab_term, Constant) and isinstance(t, Variable):
				p.set(b, elab_term.copy())
			elif isinstance(elab_term, Variable) and isinstance(t, Constant):
				p.set(elab_head, t.copy())
			elif isinstance(elab_term, Variable) and isinstance(t, Variable):
				# should change the variables in the elab rule to match the
				# expanded rule. Since the equality constraints on the head
				# variables are already applied to the substituted condition,
				# we should have that if two variables in the elab head are
				# equal, those variables in the condition are equal too
				p.set(elab_head, t.copy())
				preserve_vars.append(t.get_name())
			else:
				assert t == elab_term

		r.enforce_equality(preserve_vars)
		elab.enforce_equality(preserve_vars)
		
		offset = r.num_conditions()
		gr_head = elab.get_head()

		# for each constraint that applied to the condition 
		# being expanded, we have to insert duplicates of 
		# those that apply to the inserted conditions

		# we're going to append all the new rules to the end of
		# the body first, and then add and modify the approriate
		# constraints. After everything is done, remove the body
		# condition that was substituted
		
		# no variable equalities should be drawn here
		for grb in elab.get_body():
			r.add_condition(grb)

		# add the variable constraints
		for p in positions:
			if isinstance(p.fetch(gr_head), Constant):
				continue
			b2b_cons = r.get_constraints_on(bi, p) # body-to-body constraints
			hv_bindings = elab.get_headvar_binding(p)
			for old_i, old_p, comp, order in b2b_cons:
				for bound_i, bound_p in hv_bindings:
					if order == 0:
						# head var first
						r.add_pos_constraint(offset + bound_i, bound_p, old_i, old_p, comp)
					else:
						r.add_pos_constraint(old_i, old_p, offset + bound_i, bound_p, comp)

					if comp.relation() == '==':
						# have to rename the variables in original condition to
						# equal new condition
						new_cond = r.get_cond(bound_i + offset)
						new_name = bound_p.fetch(new_cond)
						old_p.set(r.get_cond(old_i), new_name)

		# finally remove the replaced condition
		r.remove_condition(bi)
		expanded.append(r)

		return expanded
Esempio n. 28
0
def get_predicates(rules, roles):
    """Extract predicate information from the rules"""

    preds = set()
    pred_names = set()
    predTypes = {}
    # maps places to the equivalence class they're in
    ec = TypedEquivalenceClass()
    for r in rules:
        goal_place_types = {}
        if r.get_head().get_relation() == 'goal':
            score = r.get_head().get_term(1).get_name()
            if score == 0 or score == 100:
                # we can't really say anything about the middle cases
                goal_place_types = check_min_max(r, ec, score)
                score = r.get_head().get_term(1)
            sentences = r.get_body()
        elif r.get_head().get_relation() == 'terminal':
            sentences = r.get_body()
        else:
            sentences = [r.get_head()] + r.get_body()

        for i, s1 in enumerate(sentences):
            s1pred = s1.get_predicate()
            assert s1pred != None

            if s1pred in placetype.preset_types:
                # the first place is supposed to get acted upon, not act upon the
                # second place. The preset places are not to be acted upon
                continue

            predTypes[s1pred] = s1.get_type()

            s1pos = PositionIndex.get_all_positions(s1)
            for p1 in s1pos:
                ec.get_or_make_class((s1pred, p1))

            if len(s1pos) == 0:
                preds.add(Predicate(s1pred, s1.get_type(), ()))
                pred_names.add(s1pred)
                continue

            added = False
            for s2 in sentences[i + 1:]:
                s2pred = s2.get_predicate()
                s2pos = PositionIndex.get_all_positions(s2)

                assert s1pred != None and s2pred != None

                for p1 in s1pos:
                    place1 = (s1pred, p1)
                    t1 = p1.fetch(s1)
                    c1 = ec.get_or_make_class(place1)
                    if place1 in placetype.preset_types:
                        ec.set_class_type(c1, placetype.preset_types[place1])
                    for p2 in s2pos:
                        place2 = (s2pred, p2)
                        t2 = p2.fetch(s2)
                        if isinstance(t1, Variable) and isinstance(t2, Variable) and \
                          t1 == t2:
                            if place2 in goal_place_types:
                                ec.set_class_type(c1, goal_place_types[place2])
                            elif place2 in placetype.preset_types:
                                ec.set_class_type(
                                    c1, placetype.preset_types[place2])
                            else:
                                # put these two places in the same equivalence class
                                place1 = (s1pred, p1)
                                place2 = (s2pred, p2)
                                ec.make_equivalent(place1, place2)

    # run through the rules again.  If a role constant appears somewhere, and
    # no non-role constants appear in that place, then that place is an agent
    possible_agent_places = set()
    impossible_agent_places = set()
    for r in rules:
        if r.get_head().get_predicate() != None:
            sentences = [r.get_head()] + r.get_body()
        else:
            sentences = r.get_body()
        for s in sentences:
            for p in PositionIndex.get_all_positions(s):
                place = (s.get_predicate(), p)
                t = p.fetch(s)
                if t in roles:
                    if place not in impossible_agent_places:
                        possible_agent_places.add(place)
                else:
                    if isinstance(t, Constant):
                        impossible_agent_places.add(place)
                        possible_agent_places.discard(place)

    collected = {}
    for place in ec.get_all_members():
        if place in possible_agent_places:
            type = placetype.AGENT
        else:
            type = ec.get_member_type(place)
        collected.setdefault(place[0], []).append((place, type))

    for p, types in collected.items():
        types.sort(lambda x, y: cmp(x[0], y[0]))
        types_no_place = [t[1] for t in types]
        preds.add(Predicate(p, predTypes[p], types_no_place))
        pred_names.add(p)

    # go over one more time and see if we missed anything
    for r in rules:
        sentences = [r.get_head()] + r.get_body()
        for s in sentences:
            p = s.get_predicate()
            if p == None:
                continue
            if p not in pred_names:
                pos = PositionIndex.get_all_positions(s)
                preds.add(
                    Predicate(p, s.get_type(),
                              tuple([placetype.UNKNOWN] * len(pos))))

    return preds