Dear Lyle,

the digital logic simulation code in CTM works by concurrently waiting
for new input. In you example, you use infinite lazy sequences. These
sequences will be consumed  by the gates because the GateLoop function
is not lazy.
New threads are created because laziness is implemented using threads
(which are cheap in Oz).

One way to fix this is to make the infinite sequences in your example
concurrently depending on the input instead of lazy. See the changed
definitions for Repeat and LMap:

---------------

declare
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

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

proc {FullAdder X Y Z ?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

% Z0s=0|0|0|...
% {FullAdder X1s Y1s Z0s C1s S1s}
% {FullAdder X2s Y2s C1s C2s S2s}
% {FullAdder X3s Y3s C2s C3s S3s}
% {FullAdder Z0s Z0s C3s _   S4s}

fun {Repeat In F}
   thread
      {Map In fun {$ _} {F} end}
   end
end

fun {LMap Xs F}
   thread
      case Xs
      of nil then nil
      [] X|Xr then {F X}|{LMap Xr F}
      end
   end
end

local
   Bit
in
   fun {Bit N Xs}
      {LMap Xs fun {$ X} X.N end}
   end

   proc {ChainedAdder Xs Ys ?Ss}
      N Cs
      Zeros={Repeat Xs fun {$} 0 end}
   in
      N={Width Xs.1}

      Cs={Repeat Xs fun {$} {MakeTuple '#' N+1} end}
      Ss={Repeat Xs fun {$} {MakeTuple '#' N+1} end}

      {Browse cs#Cs}
      {Browse ss#Ss}

      {Bit 1 Cs}=Zeros

      for I in 1..N do
         {FullAdder {Bit I Xs} {Bit I Ys} {Bit I Cs} {Bit I+1 Cs} {Bit I Ss}}
      end

      {FullAdder Zeros Zeros {Bit N+1 Cs} _ {Bit N+1 Ss}}
   end
end

X=(0#1#1)|_
Y=(1#0#1)|_
S

{ChainedAdder X Y S}
{Browse inp(X Y)#sum(S)}

---------------

Another possibility would be to make the whole circuit simulation
lazy. However, just adding "lazy" to the GateLoop function doesn't
seem to be enough. I didn't explore that alternative any further so
far...

Cheers,
  Wolfgang


On 1/1/10, Lyle Kopnicky <[email protected]> wrote:
> Hi folks,
>
> I'm new to the list. I've been reading CTM, and I attempted to solve
> Exercise 9 in Chapter 4. This involves creating a "gate" that adds together
> two numbers by chaining full adders. I decided to encode the multiple bits
> of a number as a tuple. Unfortunately, although my code produces the correct
> result, it runs away with creating new threads. Although I've figured out
> that it keeps extending Cs, I don't know why. The key procedure to look at
> is ChainedAdder. The top section (up through the declaration of FullAdder)
> is copied straight from 4.3.5.
>
> I've run this through the debugger, and I can watch some threads being
> created, but the runaway threads seem to be coming from nowhere. Any ideas?
>
> Thanks,
> Lyle Kopnicky
>
> declare GateMaker
> 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
>
> declare AndG OrG NandG NorG XorG
> AndG ={GateMaker fun {$ X Y} X*Y end}
> OrG  ={GateMaker fun {$ X Y} X+Y-X*Y end}
> NandG={GateMaker fun {$ X Y} 1-X*Y end}
> NorG ={GateMaker fun {$ X Y} 1-X-Y+X*Y end}
> XorG ={GateMaker fun {$ X Y} X+Y-2*X*Y end}
>
>
> declare FullAdder
> proc {FullAdder X Y Z ?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
>
>
> % Z0s=0|0|0|...
> % {FullAdder X1s Y1s Z0s C1s S1s}
> % {FullAdder X2s Y2s C1s C2s S2s}
> % {FullAdder X3s Y3s C2s C3s S3s}
> % {FullAdder Z0s Z0s C3s _   S4s}
>
> declare Repeat
> fun lazy {Repeat F}
>    {F}|{Repeat F}
> end
>
> declare Zeros
> Zeros={Repeat fun {$} 0 end}
>
> declare LMap
> fun lazy {LMap Xs F}
>    case Xs
>    of nil then nil
>    [] X|Xr then {F X}|{LMap Xr F}
>    end
> end
>
>
> declare ChainedAdder
> local
>    Bit
> in
>    fun {Bit N Xs}
>       {LMap Xs fun {$ X} X.N end}
>    end
>
>    proc {ChainedAdder Xs Ys ?Ss}
>       N Cs
>    in
>       N={Width Xs.1}
>
>       Cs={Repeat fun {$} {MakeTuple '#' N+1} end}
>       Ss={Repeat fun {$} {MakeTuple '#' N+1} end}
>
>       {Browse cs#Cs}
>       {Browse ss#Ss}
>
>       {Bit 1 Cs}=Zeros
>
>       for I in 1..N do
>          {FullAdder {Bit I Xs} {Bit I Ys} {Bit I Cs} {Bit I+1 Cs} {Bit I
> Ss}}
>       end
>
>       {FullAdder Zeros Zeros {Bit N+1 Cs} _ {Bit N+1 Ss}}
>    end
> end
>
>
> declare
> X=(0#1#1)|_
> Y=(1#0#1)|_
> S
>
> {ChainedAdder X Y S}
> {Browse inp(X Y)#sum(S)}
>
> % END OF FILE
> _________________________________________________________________________________
>  mozart-users mailing list
> [email protected]
>  http://www.mozart-oz.org/mailman/listinfo/mozart-users
>
_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

Reply via email to