#!/usr/bin/python
################################################################
#
#              Check A Proof 
#
################################################################
#
# Command Line Arguments:
#   1. The name of the file containing the proof to be checked
#      (without the .tex extension)
#   2. The number of the theorem whose proof is to be checked
#   3. (Optional) Name of the rules file.
#       The default is "rules" (+.tex)
#       If the rules file name begins with "debug" verbose 
#       debugging output is generated by the unifier.
#       Debugging output can also be triggered by supplying the
#       line number of a rule in rules.tex as this arguement.
#
################################################################
import sys,pickle,os
from stat import ST_MTIME
from getpath import getpath
from urllib import urlretrieve
#
import synt, pattern
from unify import main_unifier
#
#
#
if len(sys.argv)< 3:
	print 'Usage: check <file> <theorem-number> [<rules-file>]'
	raise SystemExit

Theorem_ref = sys.argv[2]

if not pattern.exref.match(Theorem_ref):
	print Theorem_ref, "not a valid theorem number"
	raise SystemExit

filename = sys.argv[1] + '.tex'
try:
	f = open(filename,"r")
	line_list = f.readlines()
	f.close()
except:
	print filename + ' not found.'
	raise SystemExit


debug_flag = False 
solerule_num = 0
if len(sys.argv) > 3:
	if sys.argv[3].isdigit():
		solerule_num = int(sys.argv[3])
		rulefilename = "rules.tex"
		debug_flag = True
	else:
		rulefilename = sys.argv[3] + '.tex'
		if sys.argv[3].startswith("debug"): 
			debug_flag = True
else:
	rulefilename = "rules.tex"

rulepathname = getpath(rulefilename)
if not rulepathname: 
	print rulefilename + ' not found.'
	raise SystemExit


#
# Default zero+plus references file:
#
basicsfilename = "common.tex"
basicspathname = getpath(basicsfilename)


############################################################
#
# Load math data from .dfs file
#
############################################################

try:
	f = open(sys.argv[1] + ".dfs","r")
	dfs_mtime = os.stat(sys.argv[1] + ".dfs")[ST_MTIME]
except:
	print "File, " + sys.argv[1] + ".dfs, not found. "
	print "Run parse  ", sys.argv[1]
	raise SystemExit
syntdb = pickle.load(f)
f.close()
if len(syntdb) < 12:
	print "File, " + sys.argv[1] + ".dfs, obsolete. "
	print "Run parse ", sys.argv[1]
	raise SystemExit
synt.mathdb = syntdb


#############################################################
#
#  Do pre-processing: Run all directives
#
#############################################################

for r in line_list:
	inputfilem = pattern.inputfile.match(r)
	if inputfilem:
		fname = inputfilem.group(1) 
		fpathname = getpath(fname)
		if not fpathname:
			print "File",fname, " not found."
			raise SystemExit
		elif os.stat(fpathname)[ST_MTIME] > dfs_mtime:
			for s in open(fpathname):
				if pattern.directive.match(s):
					synt.process_directive(s)

for s in line_list: 
	if pattern.directive.match(s):
		synt.process_directive(s)
	
line_list = synt.translate(line_list) 

#
#############################################################
#
# Get rule list
#
#############################################################
#
f = open(rulepathname,"r")
rule_file_lines = f.readlines()
f.close()
len_rule_file = len(rule_file_lines)
if solerule_num > len_rule_file:
	print "Not that many lines in: ", rulefilename
	raise SystemExit

rulelist = []

for k in range(len_rule_file): 
	r = rule_file_lines[k]
	linenum = k + 1
	if r.find('$') == -1:continue
	parsed_rule = synt.ruleparse(r)
	if parsed_rule == 0:
		print "Error in rules file, line: ", linenum
		raise SystemExit
	elif solerule_num == 0 or solerule_num == linenum:
		parsed_rule.append(linenum)
		rulelist.append(parsed_rule)

fixed_variables = ['a','b','c','d','e']

if not rulelist:
	print "No rules found in: ", rulefilename 
	raise SystemExit

#
############################################################
#
# Define all the functions  
#
############################################################
#

def fetchrefs(file_refkey, filerefnums):
	if file_refkey == '0':
		if basicspathname:
			try:
				f = open(basicspathname,"r")
				line_list = f.readlines()
				f.close()
			except:
				print "Error reading", basicspathname
				raise SystemExit
		else:
			print  basicsfilename, "not found."
			raise SystemExit

	elif extfile[file_refkey].startswith("http:"):
		try:
			(tempfilename, headers) = urlretrieve(extfile[file_refkey])
			f = open(tempfilename,"r")
			line_list = f.readlines()
			f.close() 
		except:
			print extfile[file_refkey], "not found."
			raise SystemExit
	else:
		try:
			f = open(extfile[file_refkey],"r")
			line_list = f.readlines()
			f.close()
		except:
			print extfile[file_refkey], "not found."
			raise SystemExit
			
	filerefnums_copy = filerefnums[:] 
	linetail = [line_list[0], 0 , 1 , line_list]
	r = linetail[0]
	while r:                   # Begin external file pass
		thmnumm = pattern.thmnum.match(r)
		if thmnumm:
			sreference = thmnumm.group(2)
			reference = thmnumm.group(3)
			current_ref = file_refkey + sreference + '.' + reference
			if current_ref in filerefnums:
				TeXdollars = pattern.TeXdollar.search(r)
				linetail[0] = r[TeXdollars.end(1):]
				reffed_item = synt.getformula(linetail)
				if reffed_item:
					wp = synt.deep(reffed_item[2])
				else:
					print current_ref, "failed to parse."
					raise SystemExit
				basic_ref[current_ref] = [wp, synt.varlist(wp)]
				if current_ref in filerefnums_copy:
					filerefnums_copy.remove(current_ref)
				else:
					print current_ref,"repeated in", basicsfilename
					raise SystemExit
		synt.getline(linetail)
		r = linetail[0] 
	
	
	if filerefnums_copy:
		if len(filerefnums_copy) == 1:
			print "Reference not found: ", filerefnums_copy[0]
		else:
			print "References not found: ", filerefnums_copy
		raise SystemExit	

def try_transitive_rules(tran_inst, takenvars, localvars):
	pr_form = synt.deep(tran_inst[0])
	pq_form = synt.deep(tran_inst[1])
	qr_form = synt.deep(tran_inst[2])
	instance = [pq_form, qr_form]
	conclusion = pr_form
	result = tryrules(conclusion, instance, ['$','-','$'], takenvars, localvars)
	if result:
		return result
	instance = [pq_form, qr_form, '\\ttvar']
	tryagain = tryrules(conclusion, instance, ['$','-','$',';','$'],takenvars,localvars)
	if tryagain:
		subst = tryagain[1][1]
		for p in syntdb[synt.MD_THMS]: 
			forms = ['\\ttvar']
			instances = [revar(p[0],p[1],takenvars)]
			for x in subst:
				forms.append(x)
				instances.append(subst[x])
			m = main_unifier(forms,instances,localvars,debug_flag)
			if m:
				return m
	return 0

def tryrules(conclusion, premises, signature, takenvars, localfixedvars):
# A signature contains two kinds of entries: constants and references.
# References begin with either a dollar sign, a numeral, a lower case letter, or a period.
# Constants are not allowed to contain any of these symbols.
# The conclusion may be repeated in a rule.
	reflenran = range(len(signature))
	save_varnum = synt.newvarnum	
	takenvars_copy = takenvars[:]
	for rule in rulelist:
		synt.newvarnum = save_varnum
		takenvars = takenvars_copy[:]
		rule_sig = rule[2]
		arrow_spot = rule_sig.index('<=')
		rule_hyp_list = rule[0][arrow_spot + 1:]
		if len(rule_hyp_list) != len(signature):
			continue	
		punct_mismatch = True 
		for i in reflenran: 
			if signature[i] == rule_sig[i + arrow_spot + 1]:
				pass
			elif signature[i] in synt.reference_punctuator_list:
				break
			elif rule_sig[i+ arrow_spot + 1] in synt.reference_punctuator_list:
				break
		else:
			punct_mismatch = False
		if punct_mismatch:
			continue
		for x in rule[1]:
			if x in takenvars:
				freshvarsub = synt.freshsub(rule[1],takenvars)	
				r = synt.subst(freshvarsub[0],freshvarsub[1], rule[0])
				break
		else:
			r = rule[0]
			freshvarsub = []

		goals = []
		for i in range(arrow_spot):
			goals.append(conclusion)
		instance = goals + premises 

		rulefixedvars = []
		for y in rule[1]:
			if y in fixed_variables:   # Globally defined for rules of inference 
				if freshvarsub:
					rulefixedvars.append(synt.subst(freshvarsub[0],freshvarsub[1], y))
				else:
					rulefixedvars.append(y)
		
		form = []
		for i in range(len(rule[2] )):
			if rule[2][i] == '$':
				if r[i][0][0] in [10,11]:
					form.append(r[i][1])
				else:
					form.append(r[i])
		rulem = main_unifier(form, instance, localfixedvars + rulefixedvars,debug_flag)
		if rulem: 
			return [rule, rulem]
	return 0
	
def make_instance(pref,takenvars,releasedvars = []):
	if 'H' in pref:
		block_sub = synt.freshsub(releasedvars,takenvars)
	else:
		block_sub = []
	premises = []
	for t in pref: 
		if t[0] == '0' or t[0].islower():
			premises.append(revar(basic_ref[t][0], basic_ref[t][1], takenvars))
		elif t[0].isdigit():
			premises.append(revar(ext_ref[t][0], ext_ref[t][1], takenvars))
		elif t[0] == '.':
			refnum = inrnum[t]
			if block_sub:
				premise =  synt.subst(block_sub[0],block_sub[1], int_reflist[refnum-1])
				premises.append(revar(premise, int_vars[refnum -1],
                            takenvars, given_varlist[refnum]+ block_sub[0]))
			else:
				premise = int_reflist[refnum -1]
				premises.append(revar(premise, int_vars[refnum -1],
                            takenvars, given_varlist[refnum]))
	return premises
		
def revar(pexp,vars_pexp,takenvars,fixedvars = []):	
	s = synt.freshsub(vars_pexp,takenvars,fixedvars)
	return synt.subst(s[0],s[1],pexp)

def checknoterefs(parsed_reference,used_notes):
	for x in parsed_reference:
		if x[0] == '.':
			if x in inrnum.keys():
				y = inrnum[x]
			else:
				return x + " invalid note reference."
			used_notes.append(x)
			if not(y < c):
				return "Reference " + x + " Not Valid"
			for z in given_numlist[y]:
				if z not in current_givennums:
					return "Reference " + x + " Not Valid"
	return ''

#
#############################################################
#
#  Locate the theorem referred to on the command line
#        and print it.
#
#############################################################
#

linetail = [line_list[0],0,1,line_list]
r = linetail[0]

while r:
	thmnumm = pattern.thmnum.match(r)
	if thmnumm:
		sreference = thmnumm.group(2)
		reference = thmnumm.group(3)
		if Theorem_ref == sreference + '.' + reference:
			break	
	synt.getline(linetail)
	r = linetail[0]
else:
	print 'No such theorem as', Theorem_ref
	raise SystemExit
TeXdollars = pattern.TeXdollar.search(r)
linetail[0] = r[TeXdollars.end(1):]

print
print "Theorem",Theorem_ref,


reffed_item = synt.getformula(linetail,False)
if reffed_item:
	theorem = reffed_item[0]
	parsed_theorem = reffed_item[2]
else:
	print " failed to parse."
	raise SystemExit
print theorem 
print
shortproof = ''
#
#############################################################
#
# Get all the external reference numbers listed in the proof 
#
#############################################################
#
basic_ref = {}
basic_refnums = []  # basic_ref.keys()
file_refkeys = []
ext_ref = {}
ext_refnums = []  # ext_ref.keys()
#
if reffed_item[1].find('\\By') > -1: # Just a one liner
	shortproof = reffed_item[1]
	bym = pattern.by.match(shortproof)
	if not bym :
		print "Bad short proof"
		raise SystemExit
	parsed_ref = synt.refparse(bym.group(1))
	if parsed_ref == 0:
		print "Bad short proof"
		raise SystemExit
	for r in parsed_ref:
		if r[0] == '0':
			if r not in basic_refnums:
 				basic_refnums.append(r)
			if '0' not in file_refkeys:
				file_refkeys.append('0')
		elif r[0].islower():
			if r not in basic_refnums:
 				basic_refnums.append(r)
			outfilem = pattern.outfileref.match(r)
			if outfilem.group(1) not in file_refkeys:
				file_refkeys.append(outfilem.group(1))
		elif r[0].isdigit():
 			if r not in ext_refnums:
 				ext_refnums.append(r)
else:                         # This is the main case
	while 1:
		synt.getline(linetail)
		r = linetail[0] 
		if r == '':
			print "End of file encountered in the proof."
			raise SystemExit
		if r[0] == '%':
			continue
		by_spot = r.find('\\By')
		bye_spot = r.find('\\Bye')
		if pattern.thmnum.match(r):
			break
		if by_spot != -1:
			if bye_spot != -1:
				parsed_ref = synt.refparse(r[by_spot +4:].strip())
			else:
				parsed_ref = synt.refparse(r[by_spot +3:].strip())
			if parsed_ref == 0:
				print "Bad reference:"
				print r
				raise SystemExit
			for r in parsed_ref:
				if r[0] == '0':
					if r not in basic_refnums:
						basic_refnums.append(r)
					if '0' not in file_refkeys:
						file_refkeys.append('0')
				elif  r[0].islower():
					if r not in basic_refnums:
						basic_refnums.append(r)
					outfilem = pattern.outfileref.match(r)
					if outfilem.group(1) not in file_refkeys:
						file_refkeys.append(outfilem.group(1))
				elif r == Theorem_ref:
					print "Theorem used in its proof"
					raise SystemExit
				elif r[0].isdigit():
					if r not in ext_refnums:
						ext_refnums.append(r)
		if bye_spot != -1:
			break
		
# End first pass
#
#
#
##############################################################
#
#
#  Get the notes and internal and external references
#
#
##############################################################
#
#
# The following variable is changed by workparse as well as
# in all fresh variable instantiations.
#
synt.newvarnum = 0
#
extfile = {}
Note_list = []
note_nums = []  # 
int_vars = []
int_reflist = []
#
Final_ref = ''

ext_refnums_copy = ext_refnums[:]
#
#
linetail = [line_list[0],0,1,line_list] # Begin second pass
r = linetail[0]

while r:
#
#  Get reference definitions
#
	if r.startswith("%external_ref"):  
		r_split = r.split()
		if len(r_split)< 3:
			print "Bad reference definition"
			raise SystemExit
		if r_split[1] == '0':
			basicsfilename = r_split[2]
			basicspathname = getpath(basicsfilename)
		elif not r_split[1].islower():
			print "Bad reference definition"
			raise SystemExit
		extfile[r_split[1]] = r_split[2]
#
	thmnumm = pattern.thmnum.match(r)
	if thmnumm:
		sreference = thmnumm.group(2)
		reference = thmnumm.group(3)
		current_ref = sreference + '.' + reference
#
# 	Get all internal notes 
#
		if Theorem_ref == current_ref: 
			TeXdollars = pattern.TeXdollar.search(r)
			linetail[0] = r[TeXdollars.end(1):]
			reffed_item = synt.getformula(linetail,False)
			if reffed_item:
				wp = synt.deep(reffed_item[2])
			else:
				print current_ref, "failed to parse."
				raise SystemExit
			final_by_spot = reffed_item[1].find('\\By') 
			if final_by_spot > -1:
				shortproof = reffed_item[1][final_by_spot + 3:]
				shortproof = shortproof.strip() 
			else:
				lineaftertheorem = True
				while r:
					synt.getline(linetail)
					r = linetail[0] 
					by_spot = r.find('\\By')
					bye_spot = r.find('\\Bye')
					notem = pattern.note.match(r)
					if bye_spot != -1:
						Final_ref = r[bye_spot + 4:].strip()
						if not Final_ref:
							print "QED needs reason."
							raise SystemExit
						break
					if by_spot != -1 and lineaftertheorem and not notem:
 						shortproof = r[by_spot + 3:]
 						shortproof = shortproof.strip() 
 						break
					if pattern.thmnum.match(r):
						break
					if notem: 
						note_num = '.' + notem.group(1)
						if note_num in note_nums:
							print "Duplicate note number", note_num
							raise SystemExit
						note_start = notem.start(3)
						note_nums.append(note_num)
						linetail[0] = linetail[0][note_start:]
						next_note = synt.getnote(linetail)
						if not next_note:
							print "Note error."
							print linetail[2]
							raise SystemExit
						Note_list.append(next_note)	
						if next_note[0] == 1:
							int_reflist.append(synt.negdeep(next_note[2]))
							int_vars.append(next_note[1])
						else:# Not done yet
#							print "next_note =", next_note
							int_vars.append(next_note[-1])
							int_reflist.append(synt.negdeep(next_note[-2][1][-1][0]))
					elif by_spot != -1:
						if not Note_list:
							print "Reference without note or short proof."
							raise SystemExit
						reffed_item = next_note
						if reffed_item[0] == 1:
							tag_spot = reffed_item
						else:
							tag_spot = reffed_item[-2]
						if not tag_spot[-1].strip():
							tag_spot[-1] = tag_spot[-1]+  r[by_spot +3:]
						else:
							print "Unattached reference:", r[by_spot:]
					lineaftertheorem = False
#
#   Get each external reference 
# 
		elif current_ref in ext_refnums:
			if r.find('$') == -1: 
				print "Theorem ", r ," must start on the same line." 
				raise SystemExit
			TeXdollars = pattern.TeXdollar.search(r)
			linetail[0] = r[TeXdollars.end(1):]
			reffed_item = synt.getformula(linetail)
			if reffed_item:
				wp = synt.deep(reffed_item[2])
			else:
				print current_ref, "failed to parse."
				raise SystemExit
			ext_ref[current_ref] = [wp, synt.varlist(wp)]
			ext_refnums_copy.remove(current_ref)
	synt.getline(linetail)
	r = linetail[0]

# End second pass

#
#  Determine whether a proof was given. 
# 

if Final_ref:
	wpt = synt.deep(parsed_theorem)
	Note_list.append([1, synt.varlist(wpt),wpt, [theorem], Final_ref])
elif shortproof:  # In this case Note_list remains empty
	parsed_reference = synt.refparse(shortproof)
	print "By ", shortproof
	if parsed_reference == 0:
		print "Bad reference", 
		raise SystemExit
	elif 'D' in parsed_reference:
		print  "Definitions not checked"
		raise SystemExit
	elif 'A' in parsed_reference:
		print  "Axioms not checked"
		raise SystemExit
	else:
		for letter in ['G','H','S']:
			if letter in parsed_reference:
				print "Not allowed in a short proof"
				raise SystemExit
else:
	print "Proof Not ready."
	raise SystemExit

#
#  If not all external references found, quit
#
if ext_refnums_copy:
	if len(ext_refnums_copy) == 1:
		print "Reference not found: ", ext_refnums_copy[0]
	else:
		print "References not found: ", ext_refnums_copy
	raise SystemExit
#
#
#  Translation of note numbers to consecutive
#
#
c = 0
inrnum = {} 
nums_consec = True
for t in note_nums:
	c = c+1
	inrnum[t] = c
	if int(t[1:]) != c :
		nums_consec = False
if not nums_consec:
	print "Not numbered consecutively. Use renote to fix this.\n"


############################################################
#
#  Get references from basic and other external files
#
############################################################
#

for fk in file_refkeys:
	refnums = []
	for gk in basic_refnums: 
		if gk.startswith(fk):
			refnums.append(gk)
	fetchrefs(fk,refnums)

#
################################################################
# 
#     Create the given-hence blocks 
#
################################################################
#

given_vars = {}
given_vars[0] = [[],[]]
#given_vars[Consecutive Note Number of some Given Note] =
#        [ List of Non-bound vars contained in the Given Note,
#          List of variables Set in the scope of the Given Note]
given_varlist = ['placeholder']
given_numlist = ['placeholder']

used_notes = []

if shortproof:
	current_givennums = []
else:
	current_givennums = [0]
current_givenvars = []

c = 0
for note in Note_list:
	c = c+1
#	note = Note_list[c-1]

	single_line_flag = note[0]
	if single_line_flag == 1:  
		parsed_item = note[2]
		textfragments = note[3]
		raw_justification = note[4]
		parsed_reference = synt.refparse(raw_justification.strip())
		if parsed_reference == 0:
			print "Bad reference"
			print "Note ", note_nums[c-1][1:],
			print "By ", raw_justification.strip()
			raise SystemExit
		note.append(parsed_reference)

		check_return = checknoterefs(parsed_reference,used_notes)
		noterefserror = ''
		if 'D' in parsed_reference:
			noterefserror = "D not allowed in proofs"
		if 'A' in parsed_reference:
			noterefserror = "A not allowed in proofs"
		if c == len(Note_list) :
			current_givennums.remove(0)
			nb = synt.nblist(parsed_item)
			for z in given_vars[0][1]:
				if z in nb:
					noterefserror = z +  " cannot be exported."
		if 'G' in parsed_reference:
			current_givennums.append(c)
			nb = synt.nblist(parsed_item)
			newvars = []
			for x in nb:
				if x not in current_givenvars:
					newvars.append(x)
			given_vars[c] = [newvars,[]]
		elif 'S' in parsed_reference:
			if type(parsed_item)is not list or len(parsed_item)!= 4 or\
				 type(parsed_item[1]) is not str or synt.symtype(parsed_item[1])!= 10 or\
					parsed_item[2] != '\\ident':
				noterefserror =  "Form: (<Newvar> \\ident <term>)\n"
			else:
				newvar = parsed_item[1]
				if newvar in current_givenvars or newvar in synt.nblist(parsed_item[3]):
					noterefserror =  newvar + " already defined."
				else:
					lastnum = current_givennums[-1]
					given_vars[lastnum][1].append(newvar)

		if 'H' in parsed_reference and not noterefserror: 
		# It is required that the conclusion
		# contains no occurrences of any variables
		# set subject to a given statement 
		# closed out by this hence statement.
			i = parsed_reference.index('H')
			nb = synt.nblist(parsed_item)

			deleted_givennums = []
			for x in parsed_reference[i:]:
				if len(x) < 2 or x[0] != '.':
					pass
				else:
					y = inrnum[x]
					if y in current_givennums:
						deleted_givennums.append(y)
						for z in given_vars[y][1]:
							if z in nb:
								noterefserror =  z +  " cannot be exported"
					else:
						noterefserror = x + " does not refer to a given."
			while deleted_givennums:
				y = current_givennums[-1]
				if y in deleted_givennums:
					deleted_givennums.remove(y)	
					current_givennums.pop()
				else:
					noterefserror = " overlooked given note:" + note_nums[y-1][1:]
					break

		if not noterefserror:
			noterefserror = check_return
		note.append(noterefserror)

	else:
		for link in note[:-1]:
			delta_goal = link[0]
			sigma_goals = link[1]
			textfragments = link[2]
			raw_justification = link[3]
			parsed_reference = synt.refparse(raw_justification.strip())
			if parsed_reference == 0:
				print "Bad reference"
				print "Note ", note_nums[c-1][1:],
				print "By ", raw_justification.strip()
				raise SystemExit
			for letter in ['H', 'G', 'S']:
				if letter in parsed_reference:
					noterefserror = letter + " not allowed in multi-line note"
					break
			else:
				noterefserror = checknoterefs(parsed_reference,used_notes)
			link.append(parsed_reference)
			link.append(noterefserror)
			
	given_numlist.append(current_givennums)

#  Make current_givenvars:

	current_givenvars = []
	for x in current_givennums:
		for y in given_vars[x][0]:
			if y not in current_givenvars:
				current_givenvars.append(y)
		for y in given_vars[x][1]:
			if y not in current_givenvars:
				current_givenvars.append(y)

	given_varlist.append(current_givenvars)
	current_givennums = current_givennums[:]

#
################################################################
# 
# Check the proof 
#
################################################################

Problem_found = False  # This variable records the final judgement on the proof.

#
# First check for outstanding givens
#
if current_givennums:
	if len(current_givennums) == 1:
		print "Outstanding given: ",
		print note_nums[current_givennums[0] - 1]
	else:
		print "Outstanding givens: ",
		for x in current_givennums:
			print note_nums[x-1],
		print
	print "Not ready for QED."
	Problem_found = True

# 
#   Check a short proof 
#

if shortproof:  # In this case Note_list remains empty
	parsed_reference = synt.refparse(shortproof)
	wkpth = synt.deep(parsed_theorem)
	localvars = synt.varlist(wkpth)
	takenvars = localvars[:]
	instance = make_instance(parsed_reference,takenvars)
	used_rule = tryrules(wkpth,instance, parsed_reference, takenvars,localvars)
	if used_rule:
		print "Checked with", rulefilename, ":",used_rule[0][-1],
		print "level:",used_rule[1][0],"\n"
	else:
		print "Not checked.\n"
		Problem_found = True

#
#   Check the steps of a proof with notes
#

c = 0
for note in Note_list:
	c = c+1
#	note = Note_list[c-1]

	single_line_flag = note[0]
	if single_line_flag == 1:  
		varlist = note[1]
		parsed_item = note[2]
		textfragments = note[3]
		raw_justification = note[4]
		parsed_reference = note[5] 
		error_message = note[6]
		if c == len(Note_list) :
			print "QED By ", Final_ref
		else:
			print "Note ", note_nums[c-1][1:],
			for x in textfragments:
				print x,
			print
			print "By ", raw_justification.strip()

		if 'G' in parsed_reference:
			print
		elif 'S' in parsed_reference:
			print
		elif error_message:
			print error_message
			print "Not checked.\n"
			Problem_found = True
		else:
			released_vars = []	
			if 'H' in parsed_reference:
				for x in given_varlist[c - 1]:
					if x not in given_varlist[c] and x not in released_vars:
						released_vars.append(x)

			local_goal = parsed_item 
			nblocal = synt.nblist(local_goal)
#			local_givens = nblocal + given_varlist[c] 
			local_givens = []
			for y in nblocal + given_varlist[c]: 
				if y not in local_givens:
					local_givens.append(y)
			localvars = varlist[:]
			for x in given_varlist[c]:
				if x not in localvars:
					localvars.append(x)	
#			takenvars = localvars
			instance = make_instance(parsed_reference,localvars,released_vars)
			used_rule= tryrules(local_goal,instance,parsed_reference,localvars,local_givens)
			if used_rule:
				print "Checked with", rulefilename,":",used_rule[0][-1],
				print "level:",used_rule[1][0],"\n"
			else:
				print "Not checked.\n"
				Problem_found = True
	else:
		varlist = note.pop()
		chain = note
		print "Note ", note_nums[c-1][1:]
		assert chain != []

		linenum = 0
		for link in chain:
			delta_goal = link[0]
			sigma_goals = link[1]
			textfragments = link[2]
			raw_justification = link[3]
			parsed_reference = link[4]
			error_message = link[5]
			
			linenum = linenum + 1
			print "Line ", linenum ,'   ',
			for j in range(len(textfragments)):
				if j != 0: print '                  ',
				print textfragments[j],
			print
			print "By  ", raw_justification.rstrip()

			if error_message:
				print error_message
				print "Not checked."
				Problem_found = True
			else:
				deepstep = synt.negdeep(delta_goal) 
				takenvars = varlist[:]
				local_givens = takenvars[:]
				for x in given_varlist[c]:
					if x not in local_givens:
						local_givens.append(x)
					if x not in takenvars:
						takenvars.append(x)
				
				instance = make_instance(parsed_reference,takenvars)
				used_rule = tryrules(deepstep,instance, parsed_reference,takenvars,local_givens)
				transitivity_error = False
				for tran_inst in sigma_goals:
					transitivity_ok = try_transitive_rules(tran_inst,takenvars,local_givens)
					if not transitivity_ok:
						transitivity_error = True
						break

				if used_rule and not transitivity_error:
					print "Checked with", rulefilename,":",used_rule[0][-1],
					print "level:",used_rule[1][0],"\n"
				elif used_rule:
					print "step Checked with",rulefilename,":",used_rule[0][-1],
					print "level:",used_rule[1][0],"\n"
					print "But transitivity not checked."
					Problem_found = True
				else:
					print "Not checked."
					Problem_found = True
					print 
	

if Problem_found:
	print "Proof Not checked.\n"
else:
	print "Proof checked.\n"

for t in note_nums:
	if t not in used_notes:
		print "Unused note: ", t

#
# End of check
#
