-
Notifications
You must be signed in to change notification settings - Fork 3
/
belief_test.py
173 lines (141 loc) · 5.87 KB
/
belief_test.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
171
172
173
#!/usr/bin/env python
import os
import subprocess
import re
import pprint
import json
import pickle
import argparse
import time
def timesteps(almalog):
messages = []
with open(almalog) as file_in:
timesteps = []
currenttime = {}
splitter = re.compile(": | \(parents: | \(children: |, children: ")
for line in file_in:
if "Idling..." in line:
continue
while line.startswith("alma: "):
line = line[6:]
if line.startswith("-a: "):
# Record info from ALMA messages that matter for calculating inference count
line = line[4:]
if line.startswith("Duplicate clause "):
line = line[17:-1].split(" merged into ")
for kind, arg1, _ in messages:
if (kind == "add" or kind == "obs") and arg1 == line[0]:
messages.remove((kind, arg1, _))
break
messages.append(("dupe", line[0], line[1]))
elif line.endswith(" removed\n"):
line = line[:-9]
for kind, arg1, arg2 in messages:
if (((kind == "add" or kind == "obs") and (line == arg1))
or (kind == "update" and (line == arg2 or line.startswith(arg2 + " (")))):
messages.remove((kind, arg1, arg2))
break
messages.append(("del", line, None))
elif line.endswith(" added\n"):
messages.append(("add", line[:-7], None))
elif line.endswith(" observed\n"):
messages.append(("obs", line[:-10], None))
elif "updated to" in line:
line = line[:-1].split(" updated to ")
for kind, arg1, arg2 in messages:
if ((kind == "add" or kind == "obs") and line[0] == arg1) or (kind == "update" and line[0] == arg2):
messages.remove((kind, arg1, arg2))
break
messages.append(("update", line[0], line[1]))
else:
# Process KB line
line = splitter.split(line)
lenLine = len(line)
if lenLine >= 2:
pieces = len(line)
sentence = None
parents = None
children = None
if pieces == 2:
sentence = line[1][:-1]
else:
sentence = line[1]
if pieces == 3:
if '[' in line[2]:
parents = line[2][:-2]
else:
children = line[2][:-2]
elif pieces == 4:
parents = line[2]
children = line[3][:-2]
if parents:
parents = parents.split("], [")
parents[0] = parents[0][1:]
parents[-1] = parents[-1][:-1]
parents = [parent_set.split(", ") for parent_set in parents]
for index, parent_set in enumerate(parents):
parents[index] = [int(parent) for parent in parent_set]
if children:
children = children.split(", ")
children = [int(child) for child in children]
currenttime[int(line[0])] = (sentence, parents, children)
elif lenLine == 1:
timesteps.append((currenttime, messages))
currenttime = {}
messages = []
#pp = pprint.PrettyPrinter(indent=2)
#for time in timesteps:
# pp.pprint(time)
# print("")
return timesteps
def main():
ap = argparse.ArgumentParser()
ap.add_argument('-b', '--base', required=True, help='Base axiom file', type=str)
ap.add_argument('-t', '--topic', required=True, help='Axioms for specific topic', type=str)
ap.add_argument('-d', '--dir', required=True, help='.pl and .txt directory', type=str)
ap.add_argument('-a', '--axiom_count', required=True, help='Base axiom count', type=int)
args = vars(ap.parse_args())
distrust_re = re.compile("distrusted\(\"(.*)\", ([0-9]*)\)")
expected_dir = os.path.join(args['dir'], "expected")
pl_dir = os.path.join(args['dir'], "almafiles")
base_axiom_count = args['axiom_count']
axiom_parent_count = [0] * base_axiom_count
for filename in sorted(os.listdir(expected_dir)):
prefix = filename[:-4]
# Run with base and corresponding pl file from almafiles dir
print("Running " + prefix)
with open(os.devnull, 'w') as devnull:
subprocess.call(["./alma.x", "-f" , args['base'], "-f", args['topic'], "-f", os.path.join(pl_dir, prefix + ".pl"), "-r"], stdout = devnull, stderr = devnull)
time.sleep(1)
# Parse timesteps structure from ALMA log
log = max(os.listdir("."), key=os.path.getctime)
log_info = timesteps(log)
# Open file of expected final beliefs
with open(os.path.join(expected_dir, filename)) as file_expected:
expecteds = [line.strip() for line in file_expected.readlines()]
expected_believed = [-1] * len(expecteds)
expected_distrusted = [-1] * len(expecteds)
for t, (timestep, messages) in enumerate(log_info):
for index, (sentence, parents, child) in timestep.items():
if parents is not None:
for parent_set in parents:
for parent in parent_set:
if parent < base_axiom_count:
axiom_parent_count[parent] = axiom_parent_count[parent]+1
if sentence in expecteds:
expected_believed[expecteds.index(sentence)] = t
distrust = distrust_re.search(sentence)
if distrust and distrust.group(1) in expecteds:
expected_distrusted[expecteds.index(distrust.group(1))] = t
present = 0
for index, expected in enumerate(expecteds):
if expected_believed[index] > expected_distrusted[index]:
#print("Found " + expected + " at timestep " + str(expected_believed[index]))
present = present + 1
else:
print(expected + " missing!")
print(str(present) + "/" + str(len(expecteds)) + " expected beliefs found in log " + log + "\n")
for index, entry in enumerate(axiom_parent_count):
print("Used axiom " + str(index) + " to infer " + str(entry) + " times")
if __name__ == "__main__":
main()