public Tuple <bool, List <Rule> > DeductableGoal(TP2_AI.Form1 form, Goal goal, List <Fact> facts, List <Rule> rules, bool save_trace, StreamWriter file) //on retroune si on a des règles qui peuvent déduire le but et les règles
        {
            List <Rule> deductingRules = new List <Rule>();

            foreach (Rule r in rules)
            {
                foreach (Conclusion c in r.GetConclusion())
                {
                    if (goal.Name == c.Name && goal.Negated == c.Negated)
                    {
                        deductingRules.Add(r);
                    }
                }
            }
            form.updateText("Deducting rules : " + deductingRules.Count);
            if (save_trace)
            {
                file.WriteLine("Deducting rules : " + deductingRules.Count);
            }

            if (deductingRules.Count() != 0)
            {
                deductingRules.OrderBy(o => o.GetPremises().Count);
                return(Tuple.Create <bool, List <Rule> >(true, deductingRules));
            }
            else
            {
                return(Tuple.Create <bool, List <Rule> >(false, null)); // no rules && no list
            }
        }
        public bool Verif(TP2_AI.Form1 form, Rule rule, List <Fact> facts, List <Rule> rules, bool save_trace, StreamWriter file)
        {
            form.updateText("Verifying rule number " + rule.Number + "'s premises");
            if (save_trace)
            {
                file.WriteLine("Verifying rule number " + rule.Number + "'s premises");
            }
            bool           ver  = true;
            List <Premise> list = rule.GetPremises();

            for (int i = 0; i < list.Count && ver; i++)
            {
                Premise p = list[i];
                ver = Demo(form, new Goal(p.Name, p.Negated), facts, rules, save_trace, false);
            }
            return(ver);
        }
        public bool Demo(TP2_AI.Form1 form, Goal goal, List <Fact> facts, List <Rule> rules, bool save_trace, bool first_time)
        {
            if (first_time)
            {
                file           = new StreamWriter(@"" + Path.GetDirectoryName(form.Bc_path) + "/TRACE.txt", !first_time);
                file.AutoFlush = true;
            }

            bool butDemontre = false;

            if (butDemontre = SearchGoal(goal, facts))
            {
                return(butDemontre);
            }
            else
            {
                Tuple <bool, List <Rule> > t = DeductableGoal(form, goal, facts, rules, save_trace, file);
                form.updateText("----------------------------------------");
                while (!butDemontre && t.Item1)
                {
                    foreach (Rule r in t.Item2)
                    {
                        butDemontre = Verif(form, r, facts, rules, save_trace, file);
                        if (butDemontre)
                        {
                            cleanList(facts); // on elimine les duplications: erreure due à la structure des données et la récursivité
                            if (save_trace)
                            {
                                file.WriteLine("before adding a new fact");
                            }
                            form.updateText("before adding a new fact");
                            string fc = null;
                            foreach (Fact f in facts)
                            {
                                fc += f.Name + "|" + f.Negated + "|| ";
                            }
                            form.updateText(fc);
                            if (save_trace)
                            {
                                file.WriteLine(fc);
                            }

                            string cc = null;
                            foreach (Conclusion c in r.GetConclusion())
                            {
                                cc += "Added new fact: " + c.Name + " nagetion: " + c.Negated + Environment.NewLine;
                                facts.Add(new Fact(r.Number, c.Name, c.Negated));
                            }
                            form.updateText(cc);
                            if (save_trace)
                            {
                                file.WriteLine(cc);
                            }
                            form.updateText("new facts base");
                            if (save_trace)
                            {
                                file.WriteLine("new facts base");
                            }

                            fc = null;
                            foreach (Fact f in facts)
                            {
                                fc += f.Name + "|" + f.Negated + "|| ";
                            }
                            form.updateText(fc);
                            if (save_trace)
                            {
                                file.WriteLine(fc);
                            }
                            goto Flag2;
                        }
                    }
                    form.updateText("Reseting deducting rules List");
                    if (save_trace)
                    {
                        file.WriteLine("Reseting deducting rules list");
                    }

                    t = DeductableGoal(form, goal, facts, rules, save_trace, file);
                }
                if (!butDemontre & goal.Demandable == true)
                {
                    form.updateText("I asked you a question");
                    if (save_trace)
                    {
                        file.WriteLine("Iasked you a question");
                    }
                    AskQuestion(goal);
                    butDemontre = Response(goal);
                }
            }
Flag2:
            if (butDemontre)
            {
                facts.Add(new Fact(0, goal.Name, goal.Negated));
            }
            return(butDemontre);
        }
        public string ForwardChainingWithConflict(TP2_AI.Form1 form, List <Rule> rules, List <Fact> facts, Goal goal, bool saturate, bool save_trace)
        {
            StreamWriter file = new StreamWriter(@"" + Path.GetDirectoryName(form.Bc_path) + "/TRACE.txt");

            file.AutoFlush = true;
            bool        goal_reached = false;
            bool        error        = false; //on suppose qu'il y aura pas d'erreur jusqu'à la présence du cas
            string      result       = String.Empty;
            List <Rule> BRF          = new List <Rule>();

            while ((BRF = Filtrage(rules, facts)).Count != 0)
            {
                if (saturate) //chainage avant en largeur
                {
                    foreach (Rule rule in BRF)
                    {
                        List <Conclusion> c = rule.GetConclusion();
                        foreach (Conclusion c_ in c)
                        {
                            if (SearchError(c_, facts))
                            {
                                error = true;
                            }
                            if (error)
                            {
                                goto error;
                            }
                            facts.Add(new Fact(rule.Number, c_.Name, c_.Negated));
                        }
                        rule.Used = true;
                        form.updateText("Rule: " + rule.Number + " used");
                        if (save_trace)
                        {
                            file.Write(rule.Number + " | ");
                        }
                    }
                    if (save_trace)
                    {
                        file.WriteLine();
                    }
                    string f = null;
                    foreach (Fact fact in facts)
                    {
                        f += "[" + fact.Name + " Négation: " + fact.Negated + "] ";
                        if (save_trace)
                        {
                            file.Write("[" + fact.Name + " Négation: " + fact.Negated + "] ");
                        }
                    }
                    form.updateText(f);
                    if (save_trace)
                    {
                        file.WriteLine();
                    }
                }
                else // Chainage avant en profendeur avec conflit
                {
                    Rule rule           = BRF.First <Rule>(); // choix règle FIFO
                    List <Conclusion> c = rule.GetConclusion(); // on extrait la conclusion de la régle
                    foreach (Conclusion c_ in c)
                    {
                        if (SearchError(c_, facts))
                        {
                            error = true;
                        }
                        if (error)
                        {
                            goto error;        // on specifie qu'il y'avait une erreur
                        }
                        facts.Add(new Fact(rule.Number, c_.Name, c_.Negated));
                    }
                    form.updateText("Rule " + rule.Number + " used.");
                    if (save_trace)
                    {
                        file.WriteLine("Rule used " + rule.Number);
                    }
                    string f = null;
                    foreach (Fact fact in facts)
                    {
                        f += "[" + fact.Name + "  Négation: " + fact.Negated + "] ";
                        if (save_trace)
                        {
                            file.Write("[" + fact.Name + " Négation: " + fact.Negated + "] ");
                        }
                    }
                    form.updateText(f);
                    if (save_trace)
                    {
                        file.WriteLine();
                    }
                    rule.Used = true;
                    if (SearchGoal(goal, facts))
                    {
                        goal_reached = true;
                        goto foundgoal;
                    }
                }
            }
            if (saturate) // en cas de saturation on cherche la presence du but après avoir déduit tout les régles
            {
                goal_reached = SearchGoal(goal, facts);
            }
foundgoal:  //label
error:      //label
            file.Close();
            if (goal == null)
            {
                return("Deduction des faits términée");
            }
            if (goal_reached)
            {
                result = "Le but est atteint dans la BF";
            }
            else if (error)
            {
                result = "Il y'avait une erreur [ambuguité dans les conclusion des régles et la BF]";
            }
            else if (!goal_reached)
            {
                result = "Le but n'est pas atteint";
            }
            return(result);
        }