-rwxr-xr-x 7306 holtrace-20250617/ptparse.py raw
#!/usr/bin/env pypy3
# goal: parse formats produced by hol-light/ProofTrace
# in particular: parse_type, parse_term, parse_thm
# but leave json.loads() to callers
from pyparsing import StringEnd,Literal,Word,ZeroOrMore,OneOrMore,Optional,Forward,alphas,nums
import term
import type
needdistinct = type.TYVAR,type.APP,term.CONST,term.VAR,term.EVAL,term.MAPSTO
assert len(set(needdistinct)) == len(needdistinct)
def group(f,x):
def t(r): return f(*tuple(r))
return x.copy().setParseAction(t)
lparen = Literal('(').suppress()
rparen = Literal(')').suppress()
lbracket = Literal('[').suppress()
rbracket = Literal(']').suppress()
# not: parens, brackets, double quotes, slashes
name = Word(alphas+nums+r'!#$%&*+,-./:;<=>?@\^_`{|}~'+"'")
Type = Forward()
Typevar = group(type.var,Literal('v').suppress()+lbracket+name+rbracket)
Typeapp = group(type.app,Literal('c').suppress()+lbracket+name+rbracket+lbracket+ZeroOrMore(lbracket+Type+rbracket)+rbracket)
Type <<= Typevar|Typeapp
Term = Forward()
Termvar = group(term.var,Literal('v').suppress()+lparen+name+rparen+lparen+Type+rparen)
Termconst = group(term.const,Literal('c').suppress()+lparen+name+rparen+lparen+Type+rparen)
Termcomb = group(term.eval,Literal('C').suppress()+lparen+Term+rparen+lparen+Term+rparen)
Termabs = group(term.mapsto,Literal('A').suppress()+lparen+Term+rparen+lparen+Term+rparen)
Term <<= Termvar|Termconst|Termcomb|Termabs
def parse_type(x):
return (Type+StringEnd()).parseString(x)[0]
def parse_term(x):
return (Term+StringEnd()).parseString(x)[0]
def parse_thm(x):
hypotheses = tuple(parse_term(h) for h in x['hy'])
conclusion = parse_term(x['cc'])
return hypotheses,conclusion
def test():
import json
from type import app,bool,fun
from term import const,var,eval,mapsto
print('test ptparse')
num = app('num')
real = app('real')
Int = app('int')
Atype = type.var('A')
# from: Printf.printf "%s\n" (type_string `:num`);;
x = 'c[num][]'
assert parse_type(x) == num
# from: Printf.printf "%s\n" (type_string `:num->bool`);;
x = 'c[fun][[c[num][]][c[bool][]]]'
assert parse_type(x) == fun(num,bool)
# from: Printf.printf "%s\n" (type_string `:num->int->bool`);;
x = 'c[fun][[c[num][]][c[fun][[c[int][]][c[bool][]]]]]'
assert parse_type(x) == fun(num,fun(Int,bool))
# from: Printf.printf "%s\n" (type_string `:((num#1)->int)->(A->bool)`);;
x = 'c[fun][[c[fun][[c[prod][[c[num][]][c[1][]]]][c[int][]]]][c[fun][[v[A]][c[bool][]]]]]'
assert parse_type(x) == fun(fun(app('prod',num,app('1')),Int),fun(Atype,bool))
# from: Printf.printf "%s\n" (type_string `:(A->bool)->A`);;
# (this type is an example under "tyvars" in HOL Light manual)
x = 'c[fun][[c[fun][[v[A]][c[bool][]]]][v[A]]]'
assert parse_type(x) == fun(fun(Atype,bool),Atype)
# from: Printf.printf "%s\n" (term_string `m:num`);;
x = 'v(m)(c[num][])'
assert parse_term(x) == var('m',num)
# from: Printf.printf "%s\n" (term_string `m:A`);;
x = 'v(m)(v[A])'
assert parse_term(x) == var('m',Atype)
# from: Printf.printf "%s\n" (term_string `r zpow z`);;
x = 'C(C(c(real_zpow)(c[fun][[c[real][]][c[fun][[c[int][]][c[real][]]]]]))(v(r)(c[real][])))(v(z)(c[int][]))'
assert parse_term(x) == eval(eval(const('real_zpow',fun(real,fun(Int,real))),var('r',real)),var('z',Int))
# from: Printf.printf "%s\n" (term_string `x = 1 /\ y = 2 /\ !z. z >= 0`);;
# (this term is an example under "frees" in HOL Light manual)
x = 'C(C(c(/\\)(c[fun][[c[bool][]][c[fun][[c[bool][]][c[bool][]]]]]))(C(C(c(=)(c[fun][[c[num][]][c[fun][[c[num][]][c[bool][]]]]]))(v(x)(c[num][])))(C(c(NUMERAL)(c[fun][[c[num][]][c[num][]]]))(C(c(BIT1)(c[fun][[c[num][]][c[num][]]]))(c(_0)(c[num][]))))))(C(C(c(/\\)(c[fun][[c[bool][]][c[fun][[c[bool][]][c[bool][]]]]]))(C(C(c(=)(c[fun][[c[num][]][c[fun][[c[num][]][c[bool][]]]]]))(v(y)(c[num][])))(C(c(NUMERAL)(c[fun][[c[num][]][c[num][]]]))(C(c(BIT0)(c[fun][[c[num][]][c[num][]]]))(C(c(BIT1)(c[fun][[c[num][]][c[num][]]]))(c(_0)(c[num][])))))))(C(c(!)(c[fun][[c[fun][[c[num][]][c[bool][]]]][c[bool][]]]))(A(v(z)(c[num][]))(C(C(c(>=)(c[fun][[c[num][]][c[fun][[c[num][]][c[bool][]]]]]))(v(z)(c[num][])))(C(c(NUMERAL)(c[fun][[c[num][]][c[num][]]]))(c(_0)(c[num][])))))))'
# for regression, not manually checked:
assert parse_term(x) == eval(eval(const('/\\',fun(bool,fun(bool,bool))),eval(eval(const('=',fun(num,fun(num,bool))),var('x',num)),eval(const('NUMERAL',fun(num,num)),eval(const('BIT1',fun(num,num)),const('_0',num))))),eval(eval(const('/\\',fun(bool,fun(bool,bool))),eval(eval(const('=',fun(num,fun(num,bool))),var('y',num)),eval(const('NUMERAL',fun(num,num)),eval(const('BIT0',fun(num,num)),eval(const('BIT1',fun(num,num)),const('_0',num)))))),eval(const('!',fun(fun(num,bool),bool)),mapsto(var('z',num),eval(eval(const('>=',fun(num,fun(num,bool))),var('z',num)),eval(const('NUMERAL',fun(num,num)),const('_0',num)))))))
# from: Printf.printf "%s\n" (thm_string (ASSUME `p:bool`));;
x = '{"hy": ["v(p)(c[bool][])"], "cc": "v(p)(c[bool][])"}'
x = json.loads(x)
assert parse_thm(x) == ((var('p',bool),),var('p',bool))
# from: Printf.printf "%s\n" (thm_string (UNDISCH_ALL(REWRITE_RULE[IMP_CONJ](ISPECL[`y:num`;`x:num`;`z:num`]EQ_TRANS))));;
# i.e. x = z, y = x |-> y = z
x = '{"hy": ["C(C(c(=)(c[fun][[c[num][]][c[fun][[c[num][]][c[bool][]]]]]))(v(x)(c[num][])))(v(z)(c[num][]))", "C(C(c(=)(c[fun][[c[num][]][c[fun][[c[num][]][c[bool][]]]]]))(v(y)(c[num][])))(v(x)(c[num][]))"], "cc": "C(C(c(=)(c[fun][[c[num][]][c[fun][[c[num][]][c[bool][]]]]]))(v(y)(c[num][])))(v(z)(c[num][]))"}'
x = json.loads(x)
x_num = var('x',num)
y_num = var('y',num)
z_num = var('z',num)
assert parse_thm(x) == ((term.eq(x_num,z_num),term.eq(y_num,x_num)),term.eq(y_num,z_num))
# from: Printf.printf "%s\n" (thm_string EQ_REFL);;
x = '{"hy": [], "cc": "C(c(!)(c[fun][[c[fun][[v[A]][c[bool][]]]][c[bool][]]]))(A(v(x)(v[A]))(C(C(c(=)(c[fun][[v[A]][c[fun][[v[A]][c[bool][]]]]]))(v(x)(v[A])))(v(x)(v[A]))))"}'
x = json.loads(x)
x_A = var('x',Atype)
assert parse_thm(x) == ((),eval(const('!',fun(fun(Atype,bool),bool)),mapsto(x_A,term.eq(x_A,x_A))))
# from: Printf.printf "%s\n" (thm_string REAL_ZPOW_2);;
x = '{"hy": [], "cc": "C(c(!)(c[fun][[c[fun][[c[real][]][c[bool][]]]][c[bool][]]]))(A(v(x)(c[real][]))(C(C(c(=)(c[fun][[c[real][]][c[fun][[c[real][]][c[bool][]]]]]))(C(C(c(real_zpow)(c[fun][[c[real][]][c[fun][[c[int][]][c[real][]]]]]))(v(x)(c[real][])))(C(c(int_of_num)(c[fun][[c[num][]][c[int][]]]))(C(c(NUMERAL)(c[fun][[c[num][]][c[num][]]]))(C(c(BIT0)(c[fun][[c[num][]][c[num][]]]))(C(c(BIT1)(c[fun][[c[num][]][c[num][]]]))(c(_0)(c[num][]))))))))(C(C(c(real_mul)(c[fun][[c[real][]][c[fun][[c[real][]][c[real][]]]]]))(v(x)(c[real][])))(v(x)(c[real][])))))"}'
x = json.loads(x)
# for regression, not manually checked:
assert parse_thm(x) == ((),eval(const('!',fun(fun(real,bool),bool)),mapsto(var('x',real),eval(eval(const('=',fun(real,fun(real,bool))),eval(eval(const('real_zpow',fun(real,fun(Int,real))),var('x',real)),eval(const('int_of_num',fun(num,Int)),eval(const('NUMERAL',fun(num,num)),eval(const('BIT0',fun(num,num)),eval(const('BIT1',fun(num,num)),const('_0',num))))))),eval(eval(const('real_mul',fun(real,fun(real,real))),var('x',real)),var('x',real))))))
if __name__ == '__main__':
test()