Search code examples
showoz

Why I get sum(<P/3> <P/3>) when I use Show in OZ?


I'm learning Oz, and was trying to run an example that I found in a book, it is about to simulate a full adder, but what I get is sum( ), so I do not know where the mistake, I would appreciate your help.

Here is part of the code:

fun {XorG X Y}
   fun {$ X Y}
      fun {GateLoop X Y}
         case X#Y of (X|Xr)#(Y|Yr) then
            {X+Y-2*X*Y}|{GateLoop Xr Yr}
         end
      end
   in
      thread {GateLoop X Y} end
   end
end

proc {FullAdder X Y ?C ?S}   
   K L M
in
   K={AndG X Y}
   L={AndG Y Z}
   M={AndG X Z}
   C={OrG K {OrG L M}}
   S={XorG Z {XorG X Y}}
end

declare
X=1|1|0|_
Y=0|1|0|_ C S in
{FullAdder X Y C S}
{Show sum(C S)}

AndG and OrG are similar to XorG.


Solution

  • A full adder has 3 inputs and 2 outputs. Indeed you use Z in the FullAdder function but never declare it. So first add it as an argument. Then you have to define a stream for Z as you did for X and Y. Namely :

    declare
    X=1|1|0|_
    Y=0|1|0|_ 
    Z=1|1|1|_ C S in
    {FullAdder X Y Z C S}
    {Show sum(C S)}
    

    But your main problem is that your XOR gate function is not well defined. It returns an anonymous function. So a call like {XorG A B} returns a function. A better way to implement logic gates is to use a generic function GateMaker in order not to duplicate code :

    fun {GateMaker F}
       fun {$ Xs Ys}
          fun {GateLoop Xs Ys}
             case Xs#Ys of (X|Xr)#(Y|Yr) then
                {F X Y}|{GateLoop Xr Yr}
             end
          end
       in
          thread {GateLoop Xs Ys} end
       end
    end
    

    Then you only have to define your gates like this :

    AndG = {GateMaker fun {$ X Y} X*Y end}
    OrG = {GateMaker fun {$ X Y} X+Y-X*Y end}
    XorG = {GateMaker fun {$ X Y} X+Y-2*X*Y end}
    ...
    

    Once you define the gates correctly your FullAdder should work properly.