示例#1
0
        /*
         * Het eigenlijk werk wordt gedaan door drie wederzijds recursieve methodes:
         * - ParseExpressie, die een complete propositie ontleedt
         * - ParseTerm, die een formule ontleedt waarin op top-nivo geen of-operatoren worden gebruikt
         * - ParseFactor, die alleen maar een losse variabele verwerkt,
         *    of een negatie, of een complete propositie, die dan wel tussen haakjes moet staan.
         * De methodes leveren de herkende deelformule op,
         * en verplaatsen de cursor naar de positie in de invoer daar net voorbij.
         */
        private IFormule ParseFactor()
        {
            SkipSpaces();

            if (cursor < lengte && inhoud[cursor] == '(')
            {
                cursor++;                              // passeer het openingshaakje
                IFormule resultaat = ParseExpressie(); // tussen de haakjes mag een complete propositie staan
                SkipSpaces();
                if (inhoud[cursor] != ')')
                {
                    throw new Exception("sluithaakje ontbreekt op positie " + cursor);
                }
                cursor++; // passeer het sluithaakje
                return(resultaat);
            }

            if (cursor < lengte && (inhoud[cursor] == '-' || inhoud[cursor] == '!' || inhoud[cursor] == '~'))
            {
                cursor += 1; // passeer het negatieteken
                IFormule resultaat = ParseFactor();
                return(MaakNegatie(resultaat));
            }

            // geen haakje, geen not-teken, dus dan moeten we een variabele herkennen
            string variabele = "";

            // Controleer alle opvolgende letters en cijfers en maak er een variabele van
            while (cursor < lengte && Char.IsLetterOrDigit(inhoud[cursor]))
            {
                variabele += inhoud[cursor];
                cursor    += 1;
            }
            return(MaakPropositie(variabele));
        }
示例#2
0
        /*
         * Deze recursieve methode krijgt een Formule, een Set van nog te valueren variabelen,
         * en een Valuatie voor een deel van de variabelen.
         *
         * Deze methode geeft een Valuatie terug die de gegeven formule vervult.
         * Wanneer zo'n Valuatie niet bestaat geeft hij de waarde null terug.
         */
        private static Valuatie Vervulbaar(IFormule formule, SortedSet <string> variabelen, Valuatie valuatie)
        {
            Valuatie resultaat;
            string   var = GetElement(variabelen);

            if (var == null)
            {
                return(valuatie);
            }

            // Haal variabele uit lijst van te checken variabelen
            variabelen.Remove(var);

            // Controleer of formule vervulbaar is voor de waarde (eerst waar, want als zowel waar als onwaar mogelijk is, wordt waar gekozen)
            resultaat = VervulbaarVoorWaarde(formule, variabelen, valuatie, var, true);
            if (resultaat != null)
            {
                return(resultaat);
            }
            resultaat = VervulbaarVoorWaarde(formule, variabelen, valuatie, var, false);
            if (resultaat != null)
            {
                return(resultaat);
            }
            return(null);
        }
示例#3
0
        public static void Main()
        {
            while (true)
            {
                try
                {
                    String   invoer   = Console.ReadLine();
                    IFormule formule  = Parser.ParseFormule(invoer);
                    Valuatie valuatie = Solver.Vervulbaar(formule);

                    if (valuatie == null)
                    {
                        Console.WriteLine("UNSAT");
                    }
                    else
                    {
                        Console.WriteLine("SAT\n" + valuatie);
                    }
                }
                catch (Exception exc)
                {
                    Console.WriteLine("FOUT: " + exc.Message);
                }
                break;
            }
        }
示例#4
0
        /*
         * Deze methode start het recursieve ontleedproces op,
         * en controleert na afloop of inderdaad de hele invoer is geconsumeerd.
         */
        private IFormule ParseFormule()
        {
            IFormule e = ParseExpressie();

            SkipSpaces();
            if (cursor < lengte)
            {
                throw new Exception($"Extra input op positie {cursor} ({inhoud[cursor]})");
            }
            return(e);
        }
示例#5
0
        private IFormule ParseExpressie()
        {
            IFormule t = ParseTerm();

            SkipSpaces();
            if (cursor < lengte - 1 && (inhoud[cursor] == '\\' && inhoud[cursor + 1] == '/' || inhoud[cursor] == '|' && inhoud[cursor + 1] == '|'))
            {
                cursor += 2;     // passeer het voegteken
                IFormule e = ParseExpressie();
                return(MaakDisjunctie(t, e));
            }
            return(t);
        }
示例#6
0
        private IFormule ParseTerm()
        {
            IFormule f = ParseFactor();

            SkipSpaces();
            if (cursor < lengte - 1 && (inhoud[cursor] == '/' && inhoud[cursor + 1] == '\\' || inhoud[cursor] == '&' && inhoud[cursor + 1] == '&'))
            {
                cursor += 2;     // passeer het voegteken
                IFormule t = ParseTerm();
                return(MaakConjunctie(f, t));
            }
            return(f);
        }
示例#7
0
        /*
         * Deze methode geeft een Valuatie terug die de gegeven Formule vervult.
         * Wanneer zo'n Valuatie niet bestaat geeft hij de waarde null terug.
         *
         * Deze methode roept de gelijknamige recursieve methode met 3 parameters aan, met de volgende initiele waarden:
         * - formule       de gegeven Formule,
         * - variabelen    de Set van alle variabelen uit de Formule, verkregen door eerst de methode Verzamel aan te roepen,
         * - valuatie      de lege valuatie.
         */
        public static Valuatie Vervulbaar(IFormule formule)
        {
            if (formule == null)
            {
                return(null);
            }

            SortedSet <string> variabelen = new SortedSet <string>();

            formule.Verzamel(variabelen);

            Valuatie valuatie = new Valuatie();

            return(Vervulbaar(formule, variabelen, valuatie));
        }
示例#8
0
 /*
  * Deze methode controleert de vervulbaarheid van een formule voor een bepaalde waarde voor een enkele variabele
  */
 private static Valuatie VervulbaarVoorWaarde(IFormule formule, SortedSet <string> variabelen, Valuatie valuatie, string var, bool waarde)
 {
     // Voeg variabele toe aan valuatie
     valuatie.VoegToe(var, waarde);
     // Controleer of formule waar kan zijn
     if (formule.KanWaar(valuatie))
     {
         // Controleer recursief
         Valuatie resultaat = Vervulbaar(formule, variabelen, valuatie);
         // Als er een resultaat is, return deze
         if (resultaat != null)
         {
             return(resultaat);
         }
     }
     // Anders verwijder de variabele weer uit de valuatie en return null
     valuatie.Verwijder(var);
     return(null);
 }
示例#9
0
 /*
  * Het eigenlijk werk wordt gedaan door drie wederzijds recursieve methodes:
  * - ParseExpressie, die een complete propositie ontleedt
  * - ParseTerm, die een formule ontleedt waarin op top-nivo geen of-operatoren worden gebruikt
  * - ParseFactor, die alleen maar een losse variabele verwerkt,
  *    of een negatie, of een complete propositie, die dan wel tussen haakjes moet staan.
  * De methodes leveren de herkende deelformule op,
  * en verplaatsen de cursor naar de positie in de invoer daar net voorbij.
  */
 private IFormule ParseFactor()
 {
     SkipSpaces();
     if (cursor < lengte && inhoud[cursor] == '(')
     {
         cursor++;                              // passeer het openingshaakje
         IFormule resultaat = ParseExpressie(); // tussen de haakjes mag een complete propositie staan
         SkipSpaces();
         if (inhoud[cursor] != ')')
         {
             throw new Exception("sluithaakje ontbreekt op positie " + cursor);
         }
         cursor++; // passeer het sluithaakje
         return(resultaat);
     }
     else if (cursor < lengte && (inhoud[cursor] == '-' || inhoud[cursor] == '!' || inhoud[cursor] == '~'))
     {
         // TODO: zorg dat de parser ook een negatie kan herkennen
         cursor++;
         IFormule resultaat = ParseFactor();
         SkipSpaces();
         return(MaakNegatie(resultaat));
     }
     else
     {
         // geen haakje, geen not-teken, dus dan moeten we een variabele herkennen
         // TODO: zorg dat de parser ook een variabele kan herkennen
         string resultaat = "";
         while (cursor < lengte && char.IsLetterOrDigit(inhoud[cursor]))
         {
             resultaat += inhoud[cursor];
             cursor++;
         }
         return(MaakPropositie(resultaat));
     }
 }
示例#10
0
 public Negatie(IFormule negatie)
 {
     formule = negatie;
 }
示例#11
0
 static IFormule MaakNegatie(IFormule formule)
 {
     return(new Negatie(formule));
 }
示例#12
0
 static IFormule MaakDisjunctie(IFormule links, IFormule rechts)
 {
     return(new Disjunctie(links, rechts));
 }
示例#13
0
 /*
  * Deze recursieve methode krijgt een Formule, een Set van nog te valueren variabelen,
  * en een Valuatie voor een deel van de variabelen.
  *
  * Deze methode geeft een Valuatie terug die de gegeven formule vervult.
  * Wanneer zo'n Valuatie niet bestaat geeft hij de waarde null terug.
  */
 private static Valuatie Vervulbaar(IFormule formule, SortedSet <string> variabelen, Valuatie valuatie)
 {
     // TODO: schrijf de methode die een Valuatie vindt die een formule vervult
     return(null);
 }
示例#14
0
        /*
         * Het hoofdprogramma leest een regel van de standaardinvoer, en zet die om naar een formule.
         * We zoeken een valuatie die de formule vervult.
         * Als dat lukt, printen we "SAT" op de eerste regel van de standaarduitvoer, en op de tweede regel de valuatie.
         * Als de formule niet vervulbaar is, printen we alleen "UNSAT" op de eerste regel.
         */
        public static void Main()
        {
            while (true)
            {
                try
                {
                    String invoer = Console.ReadLine();


                    IFormule formule = Parser.ParseFormule(invoer);
                    Console.WriteLine(formule.ToString());  // deze regel kun je gebruiken om de parser te testen

                    DateTime start    = DateTime.Now;
                    Valuatie valuatie = Solver.Vervulbaar(formule);
                    DateTime eind     = DateTime.Now;

                    invoer = Console.ReadLine();
                    if (invoer == "p")
                    {
                        Console.WriteLine(formule.ToString());
                    }
                    else if (invoer == "e")
                    {
                    }
                    else if (invoer == "t")
                    {
                    }
                    else if (invoer == "u")
                    {
                    }
                    else if (invoer == "v")
                    {
                    }
                    else if (invoer == "n")
                    {
                        if (valuatie == null)
                        {
                            Console.Write($"SAT\n{valuatie}");
                        }
                    }
                    else if (invoer == "y")
                    {
                        if (valuatie == null)
                        {
                            Console.WriteLine("UNSAT");
                        }
                        else
                        {
                            Console.WriteLine($"SAT\n{valuatie}");
                        }
                    }



                    Console.WriteLine($"oplostijd: {(eind - start).Ticks / 1E7} seconde");   // deze regel kun je gebruiken om het solve-proces te timen
                }
                catch (Exception exc)
                {
                    // De parser kan exceptions opwerpen als de formule syntaxfouten bevat
                    Console.WriteLine($"FOUT: {exc.Message}");
                }

                break;          // in de definitieve versie moet deze break staan, zodat er maar 1 formule wordt verwerkt.
                                // tijdens het testen kun je hem tijdelijk weghalen, zodat je meerdere formules na elkaar kunt proberen.
            }
            Console.ReadLine(); // in de definitieve versie moet dit weg, maar tijdens interactief testen voorkomt dit dat het window meteen wegflitst
        }
示例#15
0
 static IFormule MaakDisjunctie(IFormule links, IFormule rechts)
 {
     // TODO: schrijf de methode die een Disjunctie maakt
     return(new Disjunctie(links, rechts));
 }
示例#16
0
 static IFormule MaakNegatie(IFormule formule)
 {
     // TODO: schrijf de methode die een Negatie maakt
     return(new Negatie(formule));
 }
示例#17
0
 public Negatie(IFormule formule)
 {
     this.formule = formule;
 }
示例#18
0
 public Disjunctie(IFormule links, IFormule rechts)
 {
     lformule = links;
     rformule = rechts;
 }
示例#19
0
 public Conjunctie(IFormule links, IFormule rechts)
 {
     this.links  = links;
     this.rechts = rechts;
 }