### A walk in the semantic park

Olivier Danvy, Jacob Johannsen, Ian Zerny
2011 Proceedings of the 20th ACM SIGPLAN workshop on Partial evaluation and program manipulation - PERM '11
To celebrate the 20th anniversary of PEPM, we are inviting you to a walk in the semantic park and to inter-derive reduction-based and reduction-free negational normalization functions. Terms: A Boolean formula is either a variable, a negated formula, a conjunction of two formulas, or a disjunction of two formulas. We implement Boolean formulas with the following ML data type: The fold functional associated to this data type abstracts its recursive descent by parameterizing what to do in each
more » ... at to do in each case: fun term_foldr ( var , neg , conj , disj ) t = let fun visit ( VAR x ) = var x | visit ( NEG t ) = neg ( visit t ) | visit ( CONJ ( t1 , t2 )) = conj ( visit t1 , visit t2 ) | visit ( DISJ ( t1 , t2 )) = disj ( visit t1 , visit t2 ) in visit t end Normal forms: A normal form is a formula where only variables are negated. Since ML does not support subtyping, we implement normal forms with the following specialized data type: CPS transformation: The search function is CPS-transformed by naming its intermediate results, sequentializing their computation, and introducing an extra functional argument, the continuation, that maps an intermediate result to a final answer: (* term × ( found → α) → α *) fun s ea rc h _t er m_ n eg ( VAR x , k ) = k ( VAL ( NEGVAR_nf x )) | s ea r ch _t er m _n eg ( NEG t , k ) = k ( POTRED ( PR_NEG t )) | s ea r ch _t er m _n eg ( CONJ ( t1 , t2 ) , k ) = k ( POTRED ( PR_CONJ ( t1 , t2 ))) | s ea r ch _t er m _n eg ( DISJ ( t1 , t2 ) , k ) = k ( POTRED ( PR_DISJ ( t1 , t2 ))) Decomposition: We are now in position to extend the search function to not only return a potential redex (if one exists) but also its reduction context. The result is the decomposition function of a reduction semantics, where value_or_decomposition, decompose, decompose_term, decompose_term_neg, and decompose_cont are the respective clones of found, search, search_term, search_ term_neg, and apply_cont: datatype v a l u e _ o r _ d e c o m p o s i t i o n = VAL of value | DEC of p o te nt ia l _r ed ex × cont (* cont × value → v a l u e _ o r _ d e c o m p o s i t i o n *) fun decompo se_cont ( C0 , v ) = VAL v | decomp ose_con t ( C1 ( v1 , k ) , v2 ) = decomp ose_con t (k , CONJ_nf ( v1 , v2 )) | decomp ose_con t ( C2 (k , t2 ) , v1 ) = decomp ose_ter m ( t2 , C1 ( v1 , k )) | decomp ose_con t ( C3 ( v1 , k ) , v2 ) = decomp ose_con t (k , DISJ_nf ( v1 , v2 )) | decomp ose_con t ( C4 (k , t2 ) , v1 ) = decomp ose_ter m ( t2 , C3 ( v1 , k )) (* term × cont → v a l u e _ o r _ d e c o m p o s i t i o n *) and d e c o m p o s e _ t e r m _ n e g ( VAR x , k ) = decomp ose_con t (k , NEGVAR_nf x ) | d e c o m p o s e _ t e r m _ n e g ( NEG t , k ) = DEC ( PR_NEG t , k ) | d e c o m p o s e _ t e r m _ n e g ( CONJ ( t1 , t2 ) , k ) = DEC ( PR_CONJ ( t1 , t2 ) , k ) | d e c o m p o s e _ t e r m _ n e g ( DISJ ( t1 , t2 ) , k ) = DEC ( PR_DISJ ( t1 , t2 ) , k ) (* term × cont → v a l u e _ o r _ d e c o m p o s i t i o n *) and decompo se_term ( VAR x , k ) = decomp ose_con t (k , POSVAR_nf x )