/*
 * $RCSfile: aristo.js,v $
 *
 * objektorientierter Aristo in JavaScript
 *
 * $Revision: 1.3 $
 *
 * $Author: dm $
 *
 * $Date: 2003/03/12 21:56:33 $
 *
 * $Log: aristo.js,v $
 * Revision 1.3  2003/03/12 21:56:33  dm
 * einfache Hilfe-Funktion hinzugefuegt.
 *
 * Revision 1.2  2003/03/12 15:04:26  dm
 * Scheint zu funktionieren!
 *
 * Revision 1.1  2003/03/11 11:38:53  dm
 * Initial revision
 *
 */

/*
 * Klasse:     Urteil
 * Vorfahre:   (-)
 *
 * Eigenschaften:
 *    subjekt
 *    praedikat
 *    copula
 *    ok
 *
 * Methoden:
 *    toString()
 *    equals (ur)
 */
function Urteil (str)
{
   var Ausdruck = /(\w+)\s+([aeio])\s+(\w+)/;

   if (Ausdruck.test (str))
   {
      Ausdruck.exec(str);
      this.subjekt = RegExp.$1;
      this.praedikat = RegExp.$3;
      this.copula = RegExp.$2;
      this.ok = true;
   }
   else this.ok = false;

   this.toString = function ()
   {
      return (this.subjekt + ' ' + this.copula + ' ' + this.praedikat);
   }

   this.equals = function (ur)
   {
      if ((this.subjekt==ur.subjekt)
         && (this.praedikat==ur.praedikat)
         && (this.copula==ur.copula))
         return true;

      return false;
   }
}

/*
 * Klasse:     Syllogismus
 * Vorfahre:   (-)
 *
 * Eigenschaften:
 *    name
 *    figur
 *    copula1
 *    copula2
 *    folgerung
 *
 * Methoden:
 *    folgere
 */
function Syllogismus (nm, fg, cop1, cop2, folg, dirty)
{
   this.name = nm;
   this.figur = fg;
   this.copula1 = cop1;
   this.copula2 = cop2;
   this.folgerung = folg;

   if (arguments.length==6)   this.dirty = dirty;
   else this.dirty = false;

   this.folgere = function (ur1, ur2)
   {
      var ret = new Urteil ('');

      switch (this.figur)
      {
         case 1:
            if ((ur1.subjekt==ur2.praedikat)
               && (ur1.copula==this.copula1)
               && (ur2.copula==this.copula2))
            {
               ret.subjekt = ur2.subjekt;
               ret.praedikat = ur1.praedikat;
               ret.copula = this.folgerung;
               ret.ok = true;
            }
            break;

         case 2:
            if ((ur1.praedikat==ur2.praedikat)
               && (ur1.copula==this.copula1)
               && (ur2.copula==this.copula2))
            {
               ret.subjekt = ur2.subjekt;
               ret.praedikat = ur1.subjekt;
               ret.copula = this.folgerung;
               ret.ok = true;
            }
            break;

         case 3:
            if ((ur1.subjekt==ur2.subjekt)
               && (ur1.copula==this.copula1)
               && (ur2.copula==this.copula2))
            {
               ret.subjekt = ur2.praedikat;
               ret.praedikat = ur1.praedikat;
               ret.copula = this.folgerung;
               ret.ok = true;
            }
            break;

         case 4:
            if ((ur1.praedikat==ur2.subjekt)
               && (ur1.copula==this.copula1)
               && (ur2.copula==this.copula2))
            {
               ret.subjekt = ur2.praedikat;
               ret.praedikat = ur1.subjekt;
               ret.copula = this.folgerung;
               ret.ok = true;
            }
            break;
      }
      return ret;
   }
}

/*
 * Klasse:     Aristo
 * Vorfahre:   (-)
 *
 * Eigenschaften:
 *    syllogismen
 *    praem
 *    konkl
 *    proto
 *    reflexOk
 *    dirty
 *    sek
 *
 * Methoden:
 *    addPraem
 *    folgere
 *    setPraem
 *    help
 */
function Aristo (praem, dop, drt)
{
   this.addPraem = function (ur)
   {
      if (!ur.ok) return false;

      if (!this.reflexOk && (ur.subjekt==ur.praedikat)) return false;

      var i;
      for (i=0; i<this.praem.length; i++)
      {
         if (ur.equals (this.praem[i])) return false;
      }

      this.praem[this.praem.length] = ur;

      return true;
   }

   this.syllogismen = new Array ();

   // erste Figur
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Barbara', 1, 'a', 'a', 'a');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Celarent', 1, 'e', 'a', 'e');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Darii', 1, 'a', 'i', 'i');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Ferio', 1, 'e', 'i', 'o');

   // zweite Figur
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Cesare', 2, 'e', 'a', 'e');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Camestres', 2, 'a', 'e', 'e');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Festino', 2, 'e', 'i', 'o');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Baroco', 2, 'a', 'o', 'o');

   // dritte Figur
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Darapti', 3, 'a', 'a', 'i', true);
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Felapton', 3, 'e', 'a', 'o', true);
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Disamis', 3, 'i', 'a', 'i');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Datisi', 3, 'a', 'i', 'i');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Bocardo', 3, 'o', 'a', 'o');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Ferison', 3, 'e', 'i', 'o');

   // vierte Figur
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Bamalip', 4, 'a', 'a', 'i', true);
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Calemes', 4, 'a', 'e', 'e');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Dimatis', 4, 'i', 'a', 'i');
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Fesapo', 4, 'e', 'a', 'o', true);
   this.syllogismen[this.syllogismen.length]
      = new Syllogismus ( 'Fresison', 4, 'e', 'i', 'o');

   this.folgere = function ()
   {
      var dt = new Date ();

      this.proto += 'beginne Folgerungen...\n';

      var anzahl, ersterNeuer, tmp = -1, laeufe=0;
      do {
         // derzeitige Anzahl aller Praemissen
         anzahl = this.praem.length;
         ersterNeuer = tmp;

         var i, j, k, folg;
         for (i=0; i<anzahl-1; i++)
         {
            for (j=Math.max(ersterNeuer, i+1); j<anzahl; j++)
            {
               //this.proto += 'alle Syllogismen mit ' + i + ' und ' + j + '\n';
               //this.proto += '(#=' + anzahl + ', 1.=' + ersterNeuer + ')\n';

               for (k=0; k<this.syllogismen.length; k++)
               {
                  if (!this.dirty && this.syllogismen[k].dirty)
                     continue;

                  /*
                  this.proto += '  versuche ' + this.syllogismen[k].name
                                + ' mit ' + this.praem[i]
                                + ' und ' + this.praem[j]
                                + '\n';
                  */

                  folg = this.syllogismen[k].folgere (this.praem[i], this.praem[j]);
                  if (this.addPraem (folg))
                  {
                     if (anzahl+1==this.praem.length) tmp = anzahl;
                     this.konkl += folg + '\n';
                     this.proto += folg + ', weil (' + this.praem[i] + ') und ('
                                   + this.praem[j] + ') nach '
                                   + this.syllogismen[k].name + '\n';
                  }

                  folg = this.syllogismen[k].folgere (this.praem[j], this.praem[i]);
                  if (this.addPraem (folg))
                  {
                     if (anzahl+1==this.praem.length) tmp = anzahl;
                     this.konkl += folg + '\n';
                     this.proto += folg + ', weil (' + this.praem[j] + ') und ('
                                   + this.praem[i] + ') nach '
                                   + this.syllogismen[k].name + '\n';
                  }
               }
            }
         }

         laeufe++;

      } while (anzahl<this.praem.length);

      this.sek = ((new Date ()).getTime () - dt.getTime ()) / 1000;
      this.proto += 'Fertig. (' + laeufe + ' Durchlaeufe)\n';
   }

   this.setPraem = function (str, dop, drt)
   {
      this.praem = new Array ();
      this.konkl = '';
      this.proto = '';
      this.reflexOk = dop;
      this.dirty = drt;
      this.sek = 0;

      this.proto += 'lese Praemissen...\n';

      var arr = str.replace (/\r/g, '\n').replace (/\n+/g, '\n').split ('\n');

      var i;
      for (i=0; i<arr.length; i++)
      {
         if (arr[i].length==0) continue;

         this.proto += 'Praemisse "' + arr[i] + '": ';

         var ur = new Urteil (arr[i]);

         if (ur.ok)
         {
            this.addPraem (ur);
            this.proto += 'ok.\n';
         }
         else this.proto += 'Fehler!\n';
      }
   }

   this.help = function ()
   {
      var ww = 200, wh = 270;
      var sw = (screen.width-ww)/2, sh = (screen.height-wh)/2;

      var hlpWin = window.open ('', 'hlpWin',
          'innerWidth=' + ww + ',innerHeight=' + wh
          + ',screenX=' + sw + ',screenY=' + sh
          + ',scrollbars=yes,dependent=yes,status=no,toolbar=no,resizable=yes');

      hlpWin.moveTo (sw, sh);

      with (hlpWin.document)
      {
         open ('txt/html');
         writeln ('<html><head>');
         writeln ('<title>Hilfe zu Aristo</title>');
         writeln ('<style>');
         writeln ('dt {font-family: monospace; font-weight: bold}');
         writeln ('body {background-color: rgb(230,200,200)}');
         writeln ('</style>');
         writeln ('</head><body>');
         writeln ('<h2>Hilfe zu Aristo</h2>');
         writeln ('<dl>');
         writeln ('<dt>S a P</dt><dd>Alle S sind P.</dd>');
         writeln ('<dt>S e P</dt><dd>Kein S ist P.</dd>');
         writeln ('<dt>S i P</dt><dd>Einige S sind P.</dd>');
         writeln ('<dt>S o P</dt><dd>Einige S sind nicht P.</dd>');
         writeln ('</dl>');
         writeln ('</body></html>');
         close ();
      }

      hlpWin.focus ();
   }

   if (arguments.length>0)
   {
      this.setPraem (praem, dop, drt);
      this.folgere ();
   }
}

