%  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….

===================================================================================*/

 

/*#######################################################################################

#######################################################################################*/