#!/usr/bin/python
################################################################
#
#              Find Dependencies of A Proof 
#
################################################################
#
import pickle,os,re,argparse
#
import pattern, synt, prop
#
parser = argparse.ArgumentParser()

parser.add_argument("file",
		help = "name of the file with proof(s) to be audited")

parser.add_argument("num",
		help = "number of theorem to be audited") 

parser.add_argument("-a", "--alldependencies", action="store_true",
		help = "include dependencies from all external files")

parser.add_argument("-e", "--externalfile", type=str,
		help = "0 or other external file reference key")

args = parser.parse_args()

if args.file.endswith('.tex'):
	Arg_1 = args.file[-4:]
else:
	Arg_1 = args.file

filename = Arg_1 + '.tex'

if not os.path.isfile(filename):
	raise SystemExit("File " + Arg_1 + ".tex not found")

if not os.path.isfile(Arg_1 + ".pfs"):
	raise SystemExit("No .pfs file found: Run parse " + Arg_1)

try:
	f = open(Arg_1 + ".pfs" ,"rb")
	doc = pickle.load(f)
	f.close()
except:
	raise SystemExit("Error loading ", Arg_1+ ".pfs")
	
def numerals2nums(x):
	return list(map(int,x.split(".")))
	
Theorem_ref = args.num

if Theorem_ref not in doc.propdict:
	print(Theorem_ref, " not found.")
	raise SystemExit	

#Find what theorems depend on the given theorem:
n = 0
newlist = [Theorem_ref]
oldlist = []
while newlist:
	combined_list = oldlist + newlist
	t = []
	t = set()
	for x in doc.proofdict:
		for p in newlist:
			if p in doc.proofdict[x].prop_refnums and x not in combined_list:
				t.add(x)
				n = n + 1
	oldlist = oldlist + newlist
	newlist = list(t)
del oldlist[0]
consequences = oldlist
n_consequences = len(consequences)

callers = []
for x in doc.proofdict:
	if Theorem_ref in doc.proofdict[x].prop_refnums:
		callers.append(x)

#Find what the given theorem needs:
n = 0
newlist = [Theorem_ref]
oldlist = []
while newlist:
#	print len(oldlist),len(newlist)
	combined_list = oldlist + newlist
	t = set()
	for p in newlist:
		y = doc.proofdict.get(p, -1)
		if y != -1:
			for q in y.prop_refnums: 
				if q not in combined_list:
					if q not in doc.propdict:
						print("Non-existent reference in proof of",p, ":",q )
						continue
					t.add(q)
					n = n + 1
	oldlist = oldlist + newlist
	newlist = list(t)
#del oldlist[0]
basicpreds = set()
for p in oldlist:
	y = doc.proofdict.get(p, -1)
	if y != -1:
		basicpreds = basicpreds| y.basic_refnums
basicpredecessors = list(basicpreds)
basicpredecessors.sort(key=numerals2nums)

predecessors = oldlist[1:]
n_predecessors = len(predecessors)

print()

print("used by", n_consequences,":")
consequences.sort(key=numerals2nums)
for p in consequences:
	print(p, end = ', ')
print()
print()

print("needs ", n_predecessors,":")
predecessors.sort(key=numerals2nums)
for p in predecessors:
	print(p, end = ', ')
print()
if args.alldependencies:
	print()
	print("uses ",len(basicpredecessors)," zero plus references :")
	for p in basicpredecessors:
		print(p, end = ', ')
	print()
	print()
