% Prolog implementation of SOS rules for our simple imperative language. % We represent an environment as a list of terms `x=v`. % Thus, the following predicate implements the lookup in an environment: lookup([Y=W|E],X,V) :- X=Y -> V=W ; lookup(E,X,V). % This predicate implements an update of an environment, i.e., % update(S,X,V,S1) holds if S1 = S[X/V]: update([] ,X,V,[X=V]). update([Y=W|S],X,V,S1) :- X=Y -> S1=[X=V|S] ; update(S,X,V,S2), S1=[Y=W|S2]. % We define the evaluation of expressions as a predicate % where the clauses are just the translation of the natural semantics rules: eval(_,N,N) :- number(N). eval(S,X,V) :- atom(X), lookup(S,X,V). eval(S,E1+E2,V) :- eval(S,E1,V1), eval(S,E2,V2), V is V1+V2. eval(S,E1-E2,V) :- eval(S,E1,V1), eval(S,E2,V2), V is V1-V2. eval(S,E1*E2,V) :- eval(S,E1,V1), eval(S,E2,V2), V is V1*V2. eval(S,E1 V=true ; V=false). eval(S,E1>E2,V) :- eval(S,E1,V1), eval(S,E2,V2), (V1>V2 -> V=true ; V=false). eval(S,E1=E2,V) :- eval(S,E1,V1), eval(S,E2,V2), (V1=V2 -> V=true ; V=false). % The predicate step(S1,Sigma1,S2,Sigma2) represents an SOS step. step((X = E) ,Sigma,skip,SigmaV) :- eval(Sigma,E,V), update(Sigma,X,V,SigmaV). step(if(E,S,_) ,Sigma,S,Sigma) :- eval(Sigma,E,true). step(if(E,_,S) ,Sigma,S,Sigma) :- eval(Sigma,E,false). step(while(E,_),Sigma,skip,Sigma) :- eval(Sigma,E,false). step(while(E,S),Sigma,(S ; while(E,S)),Sigma) :- eval(Sigma,E,true). step((skip ; S),Sigma,S,Sigma). step((S1 ; S) ,Sigma,(S2 ; S),Sigma1) :- step(S1,Sigma,S2,Sigma1). % Computing sequences of steps (until skip) and return final environment: exec(skip,Sigma,Sigma) :- !. % final state reached exec(S1,Sigma1,R) :- step(S1,Sigma1,S2,Sigma2), exec(S2,Sigma2,R). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Examples: compute factorial of variable n: % % ?- P = (p=1; while(n>0, (p=p*n ; n=n-1))), exec(P,[n=6],R).