#lang planet jaymccarthy/parenlog
(type Gamma numConst num)
(type Gamma boolConst bool)
(:- (type Gamma (if Test Then Else) Tau)
(type Gamma Test bool)
(type Gamma Then Tau)
(type Gamma Else Tau))
(? (type mt numConst num)) (? (type mt (if boolConst numConst numConst) num)) (? (type mt (if boolConst numConst boolConst) num))
(? (type mt boolConst T)) (? (type mt (if boolConst numConst numConst) T)) (? (type mt (if boolConst numConst boolConst) T))
(? (type mt T num))
(type (bind V T Gamma) (var V) T)
(:- (type (bind V_ T_ Gamma) (var V) T)
(type Gamma (var V) T))
(? (type (bind w bool (bind v num mt))
(var v)
T))
(:- (type Gamma (fun Var Body) (T1 -> T2))
(type (bind Var T1 Gamma) Body T2))
(? (type mt (fun x (if (var x) numConst boolConst)) T))
(? (type mt (fun x (if (var x) numConst numConst)) T))
(:- (type Gamma (app Fun Arg) T2)
(type Gamma Fun (T1 -> T2))
(type Gamma Arg T1))
(? (type mt
(app (fun x (if (var x) numConst numConst))
boolConst)
T))
(? (type mt (fun x (var x)) T))
(? (type mt
(app (fun id
(if (app (var id) boolConst)
(app (var id) boolConst)
(app (var id) boolConst)))
(fun x (var x)))
T))
(? (type mt
(app (fun id
(if (app (var id) boolConst)
(app (var id) numConst)
(app (var id) numConst)))
(fun x (var x)))
T))
(? (type mt (fun x (app (var x) (var x))) num))
(? (type mt (fun x (app (var x) (var x))) T))