#!/usr/bin/perl my $TYPE_T="mu(x.Variant(None:Unit, " . "Boolean:Unit, " . "Nat:Unit, " . "Arrow:Record(in:x, out:x)" . "))"; my $TERM_T="mu(y.Variant(Tru:Unit, " . "Fls:Unit, " . "Zero:Unit, " . "Var:Char, " . "Abs:Record(var:Char, tp:$TYPE_T, t:y), " . "App:Record(fun:y, arg:y), " . "If:Record(cond:y, thn:y, els:y), " . "Succ:y, " . "Pred:y, " . "IsZero:y, " . "Fix: y, " . "None:Unit " . "))"; my $ENV_T = "->(Char,$TYPE_T)"; $temparea = " =(app(f,project(v.cond)), tag(Boolean=Unit as $TYPE_T)) "; $iftest=" tag(If=record(cond=tag(Tru=# as $TERM_T), thn=tag(Zero=# as $TERM_T), els=tag(Zero=# as $TERM_T)) as $TERM_T) fi"; $succtest=" tag (Succ=tag (Zero=# as $TERM_T) as $TERM_T)"; $valtest=" tag (Zero=# as $TERM_T)"; $prog = " app(app(fix(abs(f:->($ENV_T,->($TERM_T,$TYPE_T)).abs(env:$ENV_T.abs(tm:$TERM_T.case tm of Tru=v => tag(Boolean=# as $TYPE_T) | Fls=v => tag(Boolean=# as $TYPE_T) | Zero=v => tag(Nat=# as $TYPE_T) | Var=v => app(env, v) | Abs=v => ( case app(app(f, app(app(app(extendEnv, env),project(v.var)),project(v.tp)) ), project(v.t)) of Boolean=vv => tag (Arrow=record(fun=project(v.tp), arg=tag(Boolean=# as $TYPE_T)) as $TYPE_T) | Nat=vv => tag (Arrow=record(fun=project(v.tp), arg=tag(Nat=# as $TYPE_T)) as $TYPE_T) | Arrow=vv => tag (Arrow=record(fun=project(v.tp), arg=tag(Arrow=vv as $TYPE_T)) as $TYPE_T) | None=vv => tag(None=# as $TYPE_T) esac ) | App=v => ( case app(app(f,env), project(v.fun)) of Arrow=vv => if =(project(vv.fun), app(app(f,env), project(v.arg))) then project(vv.arg) else tag(None=# as $TYPE_T) fi | Boolean=vv => tag(None=# as $TYPE_T) | Nat=vv => tag(None=# as $TYPE_T) | None=vv => tag(None=# as $TYPE_T) esac ) | If=v => if =(app(app(f,env),project(v.cond)), tag(Boolean=# as $TYPE_T)) then ( if =(app(app(f,env),project(v.thn)), app(f,project(v.els))) then app(app(f,env),project(v.thn)) else tag(None=# as $TYPE_T) fi ) else tag(None=# as $TYPE_T) fi | Succ=v => if =(app(app(f,env),v), tag(Nat=# as $TYPE_T)) then tag(Nat=# as $TYPE_T) else tag(None=# as $TYPE_T) fi | Pred=v => if =(app(app(f,env),v), tag(Nat=# as $TYPE_T)) then tag(Nat=# as $TYPE_T) else tag(None=# as $TYPE_T) fi | Fix=v => ( case v of Abs=v => if =(app(app(f,env), project(v.t)), project(v.tp)) then project(v.tp) else tag(None=# as $TYPE_T) fi | Tru=v => tag(Nat=# as $TYPE_T) | Fls=v => tag(Nat=# as $TYPE_T) | Abs=v => tag(Nat=# as $TYPE_T) | App=v => tag(Nat=# as $TYPE_T) | If=v => tag(Nat=# as $TYPE_T) | Succ=v => tag(Nat=# as $TYPE_T) | Pred=v => tag(Nat=# as $TYPE_T) | Fix=v => tag(Nat=# as $TYPE_T) esac ) esac )))), emptyEnv), tag(App=record(fun=tag(Abs=record(var='a', tp=tag(Nat=# as $TYPE_T), t=tag(Var='a' as $TERM_T) ) as $TERM_T), arg=tag(Zero=# as $TYPE_T)) as $TYPE_T) ) "; $testEnv = " app( app( app( app( extendEnv, app(app(app(extendEnv,emptyEnv),'c'), tag(Boolean=# as $TYPE_T)) ), 'd' ), tag(Nat=# as $TYPE_T) ), 'b' ) "; $extendEnv = " app( abs(extendEnv:->(->(Char,$TYPE_T),->(Char,->($TYPE_T,->(Char,$TYPE_T)))). $prog ), abs(oldEnv:->(Char,$TYPE_T). abs(s:Char. abs(n:$TYPE_T. abs(sprime:Char. if =(s,sprime) then n else app(oldEnv,sprime) fi ) ) ) ) ) "; $emptyEnv = " app(abs(emptyEnv:$ENV_T. $extendEnv ), abs(s:Char.tag(none = # as $TERM_T)) ) "; $_ = " $emptyEnv "; #print; #print "\n-------------------------------------------------------\n\n"; s/\n/ /g; $file = "5-programming.sml"; print "Writing code as $file...\n"; open (FILE, ">$file"); print FILE "\n val tc = \"".$_.'" val tcm = ps tc '; close (FILE);