
Program Neuromaty;

{Vypocet neuromatu  prebieha tak, ze pociatocna  aktivita neuronu start sa  siri po vsetkych cestach
sieti, ktore suhlasia so vstupnym slovom. Za tymto ucelom neurony daneho typu kontroluju, ci vstupny
bit suhlasi s  uvedenym typom. To znamena, ze neuron  j typu 1 aktivny, prave vtedy,  ked je vstupny
neuron inp aktivny  a sucasne je aktivny aspon jeden  z k neuronov typu 1 alebo  typu 0 alebo start,
ktore su k nemu  pripojene. Tomu zodpoveda vaha w(inp,j)=k a prah h(j)=k+1.  Podobne neuron j typu 0
je aktivny prave vtedy, ked je vstupny neuron inp  pasivny a sucasne je aktivny aspon jeden z k neu
ronov typu 0  alebo typu 1 alebo start,  ktore su k nemu pripojene.  Tomu zodpoveda vaha w(inp,j)=-k
a prah h(j)=1. Nakoniec vystupny neuron out realizuje disjunkciu, a teda je aktivny prave vtedy, ked
je aktivny aspon jeden z jeho vstupov. Jeho prah je h(out)=1.}

const Nmax=15;
type  neuron= record
                    h: integer;   {prah}
                    s: integer;   {stav}
                    t: integer;   {typ}
               end;
      Neuromat= array[-2..Nmax] of neuron;  {-2=start, -1=out, 0=inp}
      vahy= array[-2..Nmax, -2..Nmax] of integer;

var NM, NMn: Neuromat;
    w: vahy;
    d: array[-2..Nmax] of integer;
    ed: array[-2..Nmax,-2..Nmax] of 0..1;  {hrany grafu}
    x: integer;                            {precitany vstup 0 alebo 1}
    N: integer;                            {pocet neuronov}
    f: text;
    i, j: integer;
    t: integer;

function Stav(ii:integer; x:integer):integer;
{vypocita stav neuronu}
var st:integer;
    j, Sta:integer;
begin
   if ii=0 then Sta:=x
      else begin st:=0;
                 for j:=-2 to N do
                 if ed[j,ii]=1 then st:=st+w[ii,j]*NM[j].s;
                 st:=st-NM[ii].h;
                 if st>=0 then Sta:=1  else Sta:=0;
            end;
    Stav:=Sta
end;{Stav}

procedure Nacitaj_NM(var N:integer; var NM: Neuromat; var w:vahy);
{Vytvori stav neuromatu}
var i, j, k: integer;
begin
     Assign(f,'neur.dta'); reset(f); writeln('Pocet neuronov'); readln(N);
     writeln('Typy a stavy neuronov');
     for i:=1 to N do read(f,NM[i].t); readln(f);
     NM[-2].t:=-1; NM[-1].t:=-1; NM[0].t:=-1;       {Vynimocne neurony}
     writeln('Typy neuronov');
     for i:=1 to N do write(NM[i].t:3); writeln;

     for i:=-1 to N do NM[i].s:=0; NM[-2].s:=1;
     writeln('Hrany grafu ');
     for j:=-2 to N do
         for i:=-2 to N do ed[j,i]:=0;
     while not eof(f) do
     begin  readln(f,j,i); ed[j,i]:=1; end;
     writeln('Vypocet d ');
     for i:=-2 to N do
     begin
          d[i]:=0; for j:=-2 to N do
                      if (j<>0) and (ed[j,i]=1) then inc(d[i]);
     end;

     {Vypocet vah}
     for i:=-2 to N do
     begin for j:=-2 to N do w[i,j]:=0;
           for j:=-2 to N do
              if (j<>0) and (ed[j,i]=1) then w[i,j]:=1;
           if NM[i].t=1 then                     {Neurony typu 1}
           begin
                w[i,0]:=d[i]; NM[i].h:=d[i]+1;
           end;
           if NM[i].t=0 then                     {Neurony typu 0}
           begin
                w[i,0]:=-d[i]; NM[i].h:=1;
           end;
      end;
      NM[-2].h:=1; NM[-1].h:=1; NM[0].h:=1;
      for j:=-2 to N do
          if (j<>0) and (ed[j,-1]=1) then w[-1,j]:=1;

      writeln('Vypis prahov'); for i:=-2 to N do write(NM[i].h:3); writeln;
      writeln('Vypis vah:');
      for i:=-2 to N do
      begin  writeln;
             for j:=-2 to N do
             begin write(w[i,j]:3); if j=0 then write('  ');end;
             if i=0 then writeln;
      end; close(f);
end;{Nacitaj_NM}
begin {hlavny program}
      Nacitaj_NM(N,NM,w); writeln; writeln;
      writeln('Praca neuromatu pri rozpoznavani slov');
      writeln('=====================================');
      writeln; writeln('Stavy neuronov');
      write(' Krok ');
      for i:=-2 to N do write(i:5); writeln('  Vystup je  ');
      write(' '); for i:=1 to 65 do write('-'); writeln;
      t:=0; read(x);
      while (x=1) or (x=0) do
      begin
           write('  ',t:4,'  ');
           for i:=-2 to N do write(NM[i].s:5); writeln(NM[-1].s:8);
           for i:=-1 to N do NMn[i].s:=Stav(i,x);
           inc(t); for j:=-1 to N do NM[j].s:=NMn[j].s;
           read(x);
      end; writeln('KONIEC');
      readln
end.