McGill University
School of Computer Science

Computer Science COMP 199 (Winter term)
Excursions in Computing Science

%MATLABpak11: flipflopNandAll, flipflopSettle, flipflopNandFEall, 
% flipflopWrite, flipflopRead, booleanFA, booleanFAeval, booleanRevPolEval,
% push, pop

% function [w,x,y,z] = flipflopNandAll(w,x,y,z)
% THM 060828
function [w,x,y,z] = flipflopNandAll(w,x,y,z)
y1 = y;
z1 = z;
y = nand(w,z1);
z = nand(x,y1);

% function [w,x,y,z] = flipflopSettle(w,x,y,z)
% THM 060828
function [w,x,y,z] = flipflopSettle(w,x,y,z)
[w,x,y,z] = flipflopNandAll(w,x,y,z);
[w,x,y,z] = flipflopNandAll(w,x,y,z);

% function [data,enable,y,z] = flipflopNandFEall(data,enable,y,z)
% THM 060828
% nand flipflop prefaced by nand front end
function [data,enable,y,z] = flipflopNandFEall(data,enable,y,z)
w = nand(data,enable);
x = nand(not(data),enable);
[w,x,y,z] = flipflopSettle(w,x,y,z);

% function y = flipflopwrite(data,y)
% THM 060828
function y = flipflopWrite(data,y)
[data,enable,y,z] = flipflopNandFEall(data,1,y,not(y));

% function y = flipflopRead(data,y)
% THM 060828
function y = flipflopRead(data,y)
[data,enable,y,z] = flipflopNandFEall(data,0,y,not(y));

% function ok = booleanFA(expression)
% THM 060828
% triples[1+statebefore,1+plus|letter|other] = stateafter
% plus = 2; letter = 1; other = 0;
function ok = booleanFA(expression)
%triples = [0,0,3;
%	    0,1,1;
%	    0,2,3;
%	    1,0,3;
%	    1,1,1;
%	    1,2,2;
%	    2,0,3;
%	    2,1,1;
%	    2,2,3;
%	    3,0,3;
%	    3,1,3;
%	    3,2,3
%	   ];
triples = [3,1,3;	%plus	 3 2 3 3
	   3,1,2;	%letter  1 1 1 3
	   3,1,3;	%other   3 3 3 3
	   3,3,3	%  state 0 1 2 3
	];
state = 0;
for pos = 1:length(expression)
  if expression(pos)=='+', input = 2;
  elseif isletter(expression(pos)), input = 1;
  else input = 0; end
  state = triples(1+state,1+input);
end
ok = state==1;

% function value = booleanFAeval(expression,identifiers,values)
% THM 060828
% triples[1+statebefore,1+plus|letter|other] = stateafter
% actions[1+statebefore,1+plus|letter|other] = eval|and|or|nop
% plus = 2; letter = 1; other = 0;
% eval = 'e'; and = 'a'; or = 'o'; nop = 'n';
function value = booleanFAeval(expression,identifiers,values)
triples = [3,1,3;	%plus	 3 2 3 3
	   3,1,2;	%letter  1 1 1 3
	   3,1,3;	%other   3 3 3 3
	   3,3,3	%  state 0 1 2 3
	];
actions = ['nen';	%plus	 n n n n
	   'nan';	%letter	 e a o n
	   'non';	%other 	 n n n n
	   'nnn';	%  state 0 1 2 3
	];
state = 0;
for pos = 1:length(expression)
  current = expression(pos);
  if current=='+', input = 2;
  elseif isletter(current)
    input = 1;
    currval = lookup(current,identifiers,values);
  else input = 0; end
  action = actions(1+state,1+input);
  if action=='e', value = currval;
  elseif action=='a', value = and(value,currval);
  elseif action=='o', value = or(value,currval);
  end
  state = triples(1+state,1+input);
end
if state~=1, value = -1; end

% function value = booleanRevPolEval(expression,identifiers,values)
% THM 060828
% letter: evaluate and push onto stack; operator: pop stack twice, push result
% e.g. of identifiers = 'abcd'
% e.g. of values = [1,1,1,0]
% e.g. of use
%	booleanRevPolEval('ab.cd.+',identifiers,values)
% e.g. of use with shuntingYard:
%	booleanRevPolEval(shuntingYard('((a.b)+(c.d))'),identifiers,values)
function value = booleanRevPolEval(expression,identifiers,values)
stack = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]; top = 1;
for pos = 1:length(expression)
  current = expression(pos);
  if current=='+'
    [x,stack,top] = pop(stack,top);	%pop, push for integer stack
    if x<0 | 1<x
      value = -1;
      return
    end
    [y,stack,top] = pop(stack,top);
    if y<0 | 1<y
      value = -1;
      return
    end
    [stack,top] = push(or(x,y),stack,top);
  elseif current=='.'
    [x,stack,top] = pop(stack,top);
    if x<0 | 1<x
      value = -1;
      return
    end
    [y,stack,top] = pop(stack,top);
    if y<0 | 1<y
      value = -1;
      return
    end
    [stack,top] = push(and(x,y),stack,top);
  elseif isletter(current)
    currval = lookup(current,identifiers,values);
    [stack,top] = push(currval,stack,top);
  else
    value = -1;
    return
  end
end
[value,stack,top] = pop(stack,top);

% function [stack,top] = push(value,stack,top)
% THM 060828
function [stack,top] = push(value,stack,top)
if top >= length(stack)
  return
else
  stack(top) = value;
  top = top + 1;
end

% function [value,stack,top] = pop(stack,top)
% THM 060828
function [value,stack,top] = pop(stack,top)
if top < 2
  value = -1
  return
else
  top = top - 1;
  value = stack(top);
  stack(top) = -1;
end


% function concretePoetry
% THM	060911
% invokes
%	state = getNextState(automaton,state);
%	word = getNextWord(adj);
%	sentence = appendWord(sentence,truncate(word));
%function concretePoetry
adj = ['bright  ';'common  ';'found   ';'friendly';'good    ';'hostile ';'little  ';'our     ';'retold  ';'same    ';'sought  ';'spoken  ';'your    '];
adv=['gently  ';'just    ';'not     ';'probably';'there   ';'too     '];
art = ['a'];
conj = ['& ';'so'];
noun = ['armour     ';'bridging   ';'chickadee  ';'colosseum  ';'distance   ';'effort     ';'fire       ';'forgiveness';'game       ';'hope       ';'light      ';'moon       ';'news       ';'patience   ';'pluto      ';'point      ';'realties   ';'satellites ';'shirts     ';'song       ';'speck      ';'thoughts   ';'view       ';'views      ';'wisdom     '];
prep = ['back';'for ';'onto';'of  ';'to  ';'with'];
pron = ['this';'you '];
verb = ['are       ';'be        ';'crashing  ';'is        ';'press     ';'reflecting';'spins     '];
encodeState = ['start';'adj  ';'adv  ';'art  ';'noun ';'prep ';'pron ';'verb ';'stop '];	% not used, but explains the integer entries in automaton:
automaton = [1,2,0,1/2; 1,5,1/2,5/6; 1,4,10/12,11/12; 1,7,11/12,1; 2,5,0,4/7; 2,2,4/7,6/7; 2,9,6/7,1; 3,8,0,1/3; 3,4,1/3,2/3; 3,3,4/6,5/6; 3,9,5/6,1; 4,2,0,1/2; 4,5,1/2,1; 5,5,0,8/25; 5,6,8/25,14/25; 5,9,14/25,19/25; 5,8,19/25,23/25; 5,2,23/25,24/25; 5,3,24/25,1; 6,5,0,5/11; 6,2,5/11,7/11; 6,8,7/11,9/11; 6,3,9/11,10/11; 6,7,10/11,1; 7,8,0,3/4; 7,3,3/4,1; 8,3,0,1/2; 8,4,1/2,5/6; 8,8,5/6,11/12; 8,9,11/12,1 ];
sentence = '';
state = 1;
while state~=9
  state = getNextState(automaton,state);
  switch state
    case 2
      word = getNextWord(adj);
    case 3
      word = getNextWord(adv);
    case 4
      word = getNextWord(art);
    case 5
      word = getNextWord(noun);
    case 6
      word = getNextWord(prep);
    case 7
      word = getNextWord(pron);
    case 8
      word = getNextWord(verb);
    case 9
      break
  end
  sentence = appendWord(sentence,truncate(word));
end
sentence 

% function state = getNextState(automaton,oldState,which)
% THM	060911
% transfer from one part of speech to another (adj,adv,art,noun,prep,pron,verb)
% invoked by concretePoetry
function state = getNextState(automaton,oldState)
which = rand;
sizes = size(automaton);
for j = 1:sizes(1)
  if (automaton(j,1)==oldState) and (automaton(j,3)≤which) and (which<automaton(j,4))
    state = automaton(j,2); return
  end
end

% function word = getNextWord(partOfSpeech)
% THM	060911
% pick any word, with equal probability, from a part of speech array
% invoked by concretePoetry
function word = getNextWord(partOfSpeech)
sizes = size(partOfSpeech);
next = ceil(rand * sizes(1));
word = partOfSpeech(next,:);

% function sentence = appendWord(sentence,word)
% THM 060911
% invoked by concretePoetry
function sentence = appendWord(sentence,word)
lenS = length(sentence);
sentence(lenS+1) = ' ';		% separate with a space
lenW = length(word);
for j = 1:lenW
  sentence(lenS+j+1) = word(j);
end