-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhit.py
More file actions
129 lines (109 loc) · 4.19 KB
/
Copy pathhit.py
File metadata and controls
129 lines (109 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# -*- coding: utf-8 -*-
# !/usr/bin/env python
"""
Modulo para calcular HIT de una tupla en un modelo
"""
from itertools import product
from collections import defaultdict
from misc import indent
from first_order.isomorphisms import Isomorphism
class TupleModelHash():
"""
Clase de HIT, toma un modelo ambiente y la tupla generadora
"""
def __init__(self, model, generator_tuple, th=None, debug=False):
"""
Calcula HIT de una tupla generadora en un modelo.
Si viene en th una tupla (T,H), se considera que son
los datos para un hit ya calculado (ie hitp)
"""
generator_tuple = list(generator_tuple)
self.generator_tuple = generator_tuple
self.model = model
self.debug = debug
if self.debug:
self.V = list(generator_tuple)
if th:
# es un hit creado a partir de datos ya listos
self.T, self.H = th
return
self.ops = defaultdict(set)
for op in model.operations:
self.ops[model.operations[op].arity].add(model.operations[op])
self.rels = defaultdict(set)
for rel in model.relations:
self.rels[model.relations[rel].arity].add(model.relations[rel])
self.H = [generator_tuple]
i = len(generator_tuple)-1
self.T = defaultdict(set, {a: {j}
for j, a in enumerate(generator_tuple)})
O = self.H[-1]
while O:
flath = [item for sublist in self.H for item in sublist]
self.H.append([])
for ar in sorted(self.ops):
for f in sorted(self.ops[ar], key=lambda f: f.sym):
for tup in product(flath, repeat=ar):
if any(t in O for t in tup):
i += 1
x = f(*tup)
self.T[x].add(i)
if self.debug:
self.V.append(x)
if all(x not in h for h in self.H):
self.H[-1].append(x)
O = self.H[-1]
self.T = {k: frozenset(self.T[k]) for k in self.T}
self.H.pop(-1)
# hit relacional
self.R = []
for ar in sorted(self.rels):
for r in sorted(self.rels[ar], key=lambda r: r.sym):
self.R.append(set())
for tup in product(flath, repeat=ar):
if r(*tup):
self.R[-1].add(tuple(flath.index(i) for i in tup))
self.R = [frozenset(r) for r in self.R]
def __eq__(self, other):
return set(self.T.values()) == set(other.T.values()) and self.R == other.R
def __hash__(self):
return hash(frozenset(self.T.values()))
def iso(self, other):
if self == other:
flat_h_self = [item for sublist in self.H for item in sublist]
flat_h_other = [item for sublist in other.H for item in sublist]
d = {(flat_h_self[i]): flat_h_other[i]
for i in range(len(flat_h_self))}
return Isomorphism(d, self.model.restrict(self.universe()),
other.model.restrict(other.universe()), None)
return None
def tuple(self):
return self.generator_tuple
def universe(self):
return {item for sublist in self.H for item in sublist}
def structure(self):
return self.model.restrict(self.universe())
def __repr__(self):
result = "TupleModelHash(\n"
result += indent("Tuple=%s,\n" % self.generator_tuple)
result += indent("History=%s,\n" % self.H)
result += indent("Type=%s,\n" % {k: sorted(self.T[k]) for k in self.T})
result += indent("Relations=%s,\n" % self.R)
if self.debug:
result += indent("V=%s,\n" % self.V)
result += ")"
return result
if __name__ == "__main__":
"""
Para testeo
"""
from parser.parser import parser
MODEL = parser("./model_examples/posetrombo.model", preprocess=True)
# print(MODEL)
TA = [0, 3]
TB = [1, 2]
FA = TupleModelHash(MODEL, TA)
FB = TupleModelHash(MODEL, TB)
print(FA)
print(FB)
print(FA == FB)