Esempio n. 1
0
        //Результатом вычисления кообласти является коллекция морфизмов, полученная в результате применения функуторов,
        //являющихся элементами морфизма, другим элементам морфизма.
        //public static List<Конус> Вычислить(Конус f)
        //{
        //    List<Конус> результат = new List<Конус>();
        //    Конус шаблон = ШаблоныФункторов.FirstOrDefault(p => f.СоответствуетШаблону(p));
        //    //Если соответствующий f шаблон функтора не найден, возвращаем морфизм как есть (соответствует тождественному функтору)
        //    if (шаблон == null)
        //    {
        //        результат.Add(f);
        //        return результат;
        //    }
        //    //Здесь используется инфиксная для 2-функторов и постфиксная для 1-функторов запись.
        //    //Поэтому второй элемент шаблона (с индексом 1) содержит символ типа функтора.
        //    switch (шаблон.Элементы[1].Имя)
        //    {
        //        case "id":
        //            {
        //                результат = Вычислить(f.Элементы[0]);
        //            } break;
        //        case ">":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьОбласть(левыйОперанд, правыйОперанд);
        //            } break;
        //        case "<":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьКообласть(левыйОперанд, правыйОперанд);
        //            }; break;
        //        case "*":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьПроизведение(левыйОперанд, правыйОперанд);
        //            }; break;
        //        case "+":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьСумму(левыйОперанд, правыйОперанд);
        //            }; break;
        //        case "-":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьРазность(левыйОперанд, правыйОперанд);
        //            }; break;
        //        case "^":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьПересечение(левыйОперанд, правыйОперанд);
        //            }; break;
        //        case "~:":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьПроекцию(левыйОперанд, правыйОперанд);
        //            }; break;
        //        case "~":
        //            {
        //                List<Конус> левыйОперанд = Вычислить(f.Элементы[0]);
        //                List<Конус> правыйОперанд = Вычислить(f.Элементы[2]);
        //                результат = ВычислитьВыбор(левыйОперанд, правыйОперанд);
        //            }; break;
        //        default:
        //            {
        //                результат.Add(f);
        //            }; break;
        //    }
        //    return результат;
        //}

        //Метод использует слово как ленту конвеера для выполнения вычислений над словами-элементами исходного слова
        public static Dictionary <string, Конус> ВычислитьФунктор(Конус f)
        {
            Dictionary <string, Конус> результат = new Dictionary <string, Конус>();

            if (f.ЭтоАтом() || f.ЭтоШаблон())
            {
                результат.Add(f.Имя, f);
                return(результат);
            }
            Dictionary <string, Конус>[] результаты = new Dictionary <string, Конус> [f.Элементы.Length];   //массив списков результатов
            for (int i = 0; i < f.Элементы.Length; i++)
            {
                Конус e = f.Элементы[i];
                результаты[i] = new Dictionary <string, Конус>();
                //Если i-й элемент слова не распознается как функтор
                if (!ЭтоИмяФунктора(e.Имя))
                {
                    //и если значение для i-го элемента еще не вычислено, то вычисляем значение рекурсивно
                    Dictionary <string, Конус> результатЭлемента = ВычислитьФунктор(e);
                    foreach (string key in результатЭлемента.Keys)
                    {
                        результаты[i][key] = результатЭлемента[key];
                    }
                }
                else
                {
                    if (i == 0)
                    {
                        continue;
                    }
                    switch (e.Имя)
                    {
                    case "id":
                    {
                        foreach (string key in результаты[i].Keys)
                        {
                            результаты[i][key] = результаты[i - 1][key];
                        }
                    }; break;

                    case ">":
                    {
                        Dictionary <string, Конус> результатЭлемента = ВычислитьОбласть(результаты[i - 1]);
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "<":
                    {
                        Dictionary <string, Конус> результатЭлемента = ВычислитьКообласть(результаты[i - 1]);
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "*":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 1)
                        {
                            результатЭлемента = ВычислитьПроизведение(результаты[i - 2], результаты[i - 1]);
                        }
                        else if (i > 0)
                        {
                            результатЭлемента = результаты[i - 1];
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "+":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 1)
                        {
                            результатЭлемента = ВычислитьСумму(результаты[i - 2], результаты[i - 1]);
                        }
                        else if (i > 0)
                        {
                            результатЭлемента = результаты[i - 1];
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "-":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 1)
                        {
                            результатЭлемента = ВычислитьРазность(результаты[i - 2], результаты[i - 1]);
                        }
                        else if (i > 0)
                        {
                            результатЭлемента = результаты[i - 1];
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "^":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 1)
                        {
                            результатЭлемента = ВычислитьПересечение(результаты[i - 2], результаты[i - 1]);
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "~:":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 1)
                        {
                            результатЭлемента = ВычислитьПроекцию(результаты[i - 2].Values, результаты[i - 1].Values).ToDictionary(m => m.Имя);
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "~":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 1)
                        {
                            результатЭлемента = ВычислитьВыбор(результаты[i - 2], результаты[i - 1]);
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case ">:":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 0)
                        {
                            результатЭлемента = ВычислитьКопредел(результаты[i - 1]);
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    case "<:":
                    {
                        Dictionary <string, Конус> результатЭлемента = new Dictionary <string, Конус>();
                        if (i > 0)
                        {
                            результатЭлемента = ВычислитьПредел(результаты[i - 1]);
                        }
                        foreach (string key in результатЭлемента.Keys)
                        {
                            результаты[i][key] = результатЭлемента[key];
                        }
                    }; break;

                    default:
                    {
                        throw new Exception("Неизвестный функтор:" + e.Имя);
                    };
                    }
                }
            }
            return(результаты[f.Элементы.Length - 1]);
        }