-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerar_palabras.py
170 lines (144 loc) · 5.42 KB
/
generar_palabras.py
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#
#Esto es una adaptacion del programa del capitulo de NLP del libro AIMA
#de Rusell y Norvig para probar programas en MeLon.
#
#Carlos Castillo ([email protected]), version 0.1,
#
from __future__ import generators
import operator, math, random, copy, sys, os.path, bisect
#______________________________________________________________________________
# Simple Data Structures: infinity, Dict, Struct
infinity = 1.0e400
def Dict(**entries):
"""Create a dict out of the argument=value arguments.
>>> Dict(a=1, b=2, c=3)
{'a': 1, 'c': 3, 'b': 2}
"""
return entries
class DefaultDict(dict):
"""Dictionary with a default value for unknown keys."""
def __init__(self, default):
self.default = default
def __getitem__(self, key):
if key in self: return self.get(key)
return self.setdefault(key, copy.deepcopy(self.default))
def __copy__(self):
copy = DefaultDict(self.default)
copy.update(self)
return copy
class Struct:
"""Create an instance with argument=value slots.
This is for making a lightweight object whose class doesn't matter."""
def __init__(self, **entries):
self.__dict__.update(entries)
def __cmp__(self, other):
if isinstance(other, Struct):
return cmp(self.__dict__, other.__dict__)
else:
return cmp(self.__dict__, other)
def __repr__(self):
args = ['%s=%s' % (k, repr(v)) for (k, v) in vars(self).items()]
return 'Struct(%s)' % ', '.join(args)
def update(x, **entries):
"""Update a dict; or an object with slots; according to entries.
>>> update({'a': 1}, a=10, b=20)
{'a': 10, 'b': 20}
>>> update(Struct(a=1), a=10, b=20)
Struct(a=10, b=20)
"""
if isinstance(x, dict):
x.update(entries)
else:
x.__dict__.update(entries)
return x
# Grammars and Lexicons
def Rules(**rules):
"""Create a dictionary mapping symbols to alternative sequences.
>>> Rules(A = "B C | D E")
{'A': [['B', 'C'], ['D', 'E']]}
"""
for (lhs, rhs) in rules.items():
rules[lhs] = [alt.strip().split() for alt in rhs.split('|')]
return rules
def Lexicon(**rules):
"""Create a dictionary mapping symbols to alternative words.
>>> Lexicon(Art = "the | a | an")
{'Art': ['the', 'a', 'an']}
"""
for (lhs, rhs) in rules.items():
rules[lhs] = [word.strip() for word in rhs.split('|')]
return rules
class Grammar:
def __init__(self, name, rules, lexicon):
"A grammar has a set of rules and a lexicon."
update(self, name=name, rules=rules, lexicon=lexicon)
self.categories = DefaultDict([])
for lhs in lexicon:
for word in lexicon[lhs]:
self.categories[word].append(lhs)
def rewrites_for(self, cat):
"Return a sequence of possible rhs's that cat can be rewritten as."
return self.rules.get(cat, ())
def isa(self, word, cat):
"Return True iff word is of category cat"
return cat in self.categories[word]
def __repr__(self):
return '<Grammar %s>' % self.name
Melon = Grammar('Melon',
Rules(
S = 'E',
E = '''Booleano|Variable|Entero|Booleano|Variable|Entero|Booleano|Variable|Entero|
Booleano|Variable|Entero|Booleano|Variable|Entero|Booleano|Variable|Entero|
Booleano|Variable|Entero|Booleano|Variable|Entero|%[]%|
E % E|E :: E|- E| E / E| E * E | E + E| E - E| ! E| E \/ E | E /\ E|E < E| E > E|
E <= E| E >= E| E = E| E <> E| %let P = E in E tel%| %fun PL -> E PLOP nuf%|%if E then E else E fi%
|%( E )%
''',
P = '''Booleano|Variable| P :: P| %( P )%
''',
PLOP = '| & PL -> E PLOP',
Digito = " 1 | 2 | 3|4 |5 | 6|7|8|9",
EnteroI = "Digito | EnteroI Digito",
Entero = "% EnteroI %",
Letra = 'a|b|c|d|g|h|j|k|m|o|p|q|r|s|u|v|w|x|y|z',
VariableI = 'Letra | VariableI Letra',
Variable = '% VariableI %',
PL = 'P | P PL',
Booleano= ' %true%| %false%'
),
Lexicon(
))
def generate_random(grammar, s='S'):
"""Replace each token in s by a random entry in grammar (recursively).
This is useful for testing a grammar, e.g. generate_random(E_)"""
import random
def rewrite(tokens, into,alpha):
for token in tokens:
if token in grammar.rules:
try:
vl = alpha[token];
except:
vl=9999;
p = random.randint(0,len(grammar.rules[token])-1);
q = [];
ll = grammar.rules[token];
if token=='E':
if (p>vl and ll[p]!='Booleano' and ll[p]!='Variable' and ll[p]!='Entero') or (p>=35 and p<40):
q= ['%('];
for item in ll[p]:
q.append(item)
q.append(')%')
else:
q = ll[p];
else:
q = ll[p];
alpha[token] = min(p,vl);
rewrite(q, into,alpha)
elif token in grammar.lexicon:
into.append(random.choice(grammar.lexicon[token]))
else:
into.append(token)
return into
rv = ''.join(rewrite(s.split(), [],{}))
return rv.replace('%',' ').replace('&','|');
print generate_random(Melon)