% Homework 9
heading([],[]).
heading([X|_],Z):-Z
is X.
program(Program,
FinalStorage) :-
newStorage(NewStorage),
statement(Program, NewStorage,
FinalStorage) .
/*####################################################################################
Create a new Storage with the special
identifiers true, false, and null.
These identifiers have, respectively, true,
false, and null as values.
#####################################################################################*/
newStorage([true
= true, false = false, null = null]).
statement( Var
:= Expression, S_In, S_Out):-
expression(Expression, S_In, Value),
store(Var, Value, S_In, S_Out).
/*####################################################################################
This is a tangent, but why does this parse
correctly without parentheses around (Stmt1; Stmt2)?
';' binds less tightly than ','
p(a;b, c) = p(A, C) succeeds and p(a;b,c) =
p(A; C) fails.
But (a;b, c) = (A, C) fails and (a;b, c) =
(A; C) succeeds.
The answer is that presumably ',' (when not
enclosed within parentheses within
a term) is treated as a separator at the term
level rather than as an operator.
#####################################################################################*/
statement(
function(F, Body), S_In, S_Out ) :-
F =.. [Name | Params],
store(Name, function(Params, Body), S_In,
S_Out ).
statement(
Stmt1; Stmt2, S_In, S_Out):-
statement(Stmt1, S_In, S),
statement(Stmt2, S, S_Out).
% ======== IF
Construct ===========
statement(
if(Cond, ThenPart, ElsePart), S_In, S_Out):-
expression(Cond, S_In, Value),
ifBody(Value, ThenPart, ElsePart, S_In,
S_Out).
% ======== WHILE
Construct ===========
statement(
while(Cond, Body), S_In, S_Out):-
expression(Cond, S_In, Value),
whileBody(Value, Cond, Body, S_In, S_Out).
% ========
REPEATUNTIL Construct ===========
statement(
repeatuntil(Cond, Body), S_In, S_Out):-
expression(Cond, S_In, Value),
repeatuntilBody(Value, Cond, Body, S_In,
S_Out).
%####################################################
ifBody(true,
ThenPart, _ElsePart, S_In, S_Out) :-
statement(ThenPart, S_In, S_Out).
ifBody(false,
_ThenPart, ElsePart, S_In, S_Out) :-
statement(ElsePart, S_In, S_Out).
%####################################################
whileBody(true,
Cond, Body, S_In, S_Out) :-
statement(Body, S_In, S),
statement(while(Cond, Body), S, S_Out).
whileBody(false,
_Cond, _Body, S, S).
%####################################################
repeatuntilBody(true,
Cond, Body, S_In, S_Out) :-
statement(Body, S_In, S),
statement(repeatuntil(Cond, Body), S,
S_Out).
repeatuntilBody(false,
_Cond, _Body, S, S).
expression(
Value, _, Value):-
integer(Value).
/*####################################################################################
Should really
check to ensure that Variable is a valid identifier.
?- atom(+).
succeeds, but we don't want to attempt to
fetch the value of "+" as an idendifier.
#####################################################################################*/
%####### ONLY
DEFINED +,-,==,\==,> ###################
expression( Variable,
S, Value):-
atom(Variable),
fetch(Variable, S, Value).
expression( Exp1
+ Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
Res is V1 + V2.
expression( Exp1
- Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
Res is V1 - V2.
expression( Exp1
== Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
booleanValue(V1 = V2, Res).
expression( Exp1
\== Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
booleanValue(V1 \== V2, Res).
expression( Exp1
> Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
booleanValue(V1 > V2, Res).
/*#######################################################################################
Question 1
Extend the
interpreter in Notes 9 to include the other relational
operators as well
as a do-while (i.e., repeat-until) construct.
#######################################################################################*/
/*############# ADDING *,/,>=,<=,<
####################
% the code below
add expression for:
-multiplication
-division
-less than
-greater or
equal
-less or equal
-less
###################################################################*/
%======
multiplication ===========
expression( Exp1
* Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
Res is V1 * V2.
%====== division
===========
expression( Exp1
/ Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
Res is V1 * V2.
%====== less than
===========
expression( Exp1
< Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
booleanValue(V1 < V2, Res).
%====== greater
of equal ===========
expression( Exp1
>= Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
booleanValue(V1 >= V2, Res).
%====== less or
equal ===========
expression( Exp1
=< Exp2, S, Res):-
expression(Exp1, S, V1),
expression(Exp2, S, V2),
booleanValue(V1 =< V2, Res).
booleanValue(Expression,
true) :- Expression, !.
booleanValue(_Expression,
false).
%###################################################################
%###################################################################
fetch(Variable,
Storage, Value) :- member(Variable = Value, Storage), !.
fetch(_Variable,
_Storage, null).
store(Reserved,
_Value, S_In, [Reserved = Reserved | S_Out]) :-
member(Reserved, [true, false, null]), !,
deleteOnce(Reserved = _, S_In, S_Out).
store(Variable,
Value, S_In, [Variable = Value | S_Out]) :-
deleteOnce(Variable = _, S_In, S_Out).
deleteOnce(X, [X
| Xs], Xs) :- !.
deleteOnce(X, [Y
| Ys], [Y | Zs]) :- deleteOnce(X, Ys, Zs).
deleteOnce(_,
[], []).
/*#######################################################################################
Question 2
Add function
declarations and function calls to the language.
#######################################################################################*/
% the following
code is bugged
statement(
function(F, Body), S_In, S_Out ) :-
F =.. [Name | Pars],
store(Name, function(Pars, Body), S_In,
S_Out ).
fetchFunctionDef(_,_,null,null).
fetchFunctionDef(FName,FuncS,Params,Body):-
member(FName=(Params,Body),FuncS),!.
bindParameters([],
[], _, []).
bindParameters([P|Params],[A|Args],NewS,[P:=A|NextS]):-bindParameters(Params,
Args, NewS, NextS).
expression(call(FName,
ArgList), FuncStor, Storage, Res) :-
fetchFunctionDef(FName, FuncStor, ParamList,
Body),
expression(ArgList, FuncStor, Storage,
ArgValues),
newStorage(NewStorage),
bindParameters(ParamList, ArgValues,
NewStorage, StorageWithBoundParameters),
statement(Body, FuncStor, _,
StorageWithBoundParameters, ResultStorage),
fetch(result, ResultStorage, Res).
/*==============================================================================
?-
program(function(add,[x,y],return x+y); z = call(add,[5,6]),FinalStorage).
č some problems….
===================================================================================*/
/*#######################################################################################
#######################################################################################*/