/// <summary> /// 自己関係Rが三分的かどうか。 /// X の各元 x, y について、x R y, y R x, x = y のうちの何れか一つのみが成り立つ /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>三分的</returns> public static bool isTrichotomous <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { bool isXRY = hasRelation(itemX, rel, itemY); bool isYRX = hasRelation(itemX, rel, itemY); bool isXequalY = itemX.Equals(itemY); // どれか2条件を満たす要素があるなら偽 if (isXRY && (isYRX || isXequalY)) { return(false); } else if (isYRX && isXequalY) { return(false); } // どれにも当てはまらないならば偽 if (!isXRY && !isYRX && !isXequalY) { return(false); } } } return(true); }
/// <summary> /// 自己関係Rが左ユークリッド的かどうか。 /// X の任意の元 x, y, z について、x R z かつ y R z が成り立てば、 /// 必ず x R y かつ y R x が成り立つ /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>左ユークリッド的</returns> public static bool isLeftEuclidean <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { foreach (var itemZ in rel.Universe) { //itemX R itemZ かつ itemY R itemZ だが、 if (hasRelation(itemX, rel, itemZ) && hasRelation(itemY, rel, itemZ)) { //itemX R itemY でない、または itemY R itemX でない場合があるなら偽 if (!hasRelation(itemX, rel, itemY)) { return(false); } else if (!hasRelation(itemY, rel, itemX)) { return(false); } } } } } return(true); }
/// <summary> /// 自己関係relがあるとき、全体集合 rel.Universe の 元element が極大元かどうか /// a∈A ∀x∈A:¬(aRx) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係R</param> /// <param name="element">元</param> /// <returns>極大元である</returns> public static bool isMaximulElement <T>(this EndoRelation <T> rel, T element) { //実はelementがなくても真ではあるのだが… if (element == null) { var myEx = new System.ComponentModel.WarningException("極小元かどうか判定する際、空のelementが指定されました"); Console.WriteLine(myEx.Message); Console.WriteLine(myEx.ToString()); return(true); } else if (!rel.Universe.Contains(element)) { throw new ArgumentException("elementが全体集合rel.Universeの要素ではありません"); } //Xのどの元xも x R element とならない ような元elementかどうかを判定 foreach (T itemX in rel.Universe) { if (hasRelation(element, rel, itemX)) { return(false); } } return(true); }
/// <summary> /// 部分集合族の包含関係 ⊆ から 自己関係 R を生成するメソッド /// </summary> /// <typeparam name="TEnum"></typeparam> /// <param name="subsets">部分集合族</param> /// <param name="universe">全体集合</param> /// <returns></returns> public static EndoRelation <FiniteSet <TEnum> > CreateSubsetRelation <TEnum>(this FamilyOfSubsets <TEnum> subsets, FiniteSet <TEnum> universe) where TEnum : Enum { if (!subsets.isUniverseOK(universe)) { throw new ArgumentException("全体集合が、部分集合族の要素である、集合の要素を網羅していません"); } var retRel = new EndoRelation <FiniteSet <TEnum> >(); //自己関係の全体集合は冪集合(もとの台集合の部分集合族なので) retRel.SetUniverse(universe.PowerSet()); //要素となる集合を格納 foreach (FiniteSet <TEnum> subsetX in subsets) { foreach (FiniteSet <TEnum> subsetY in subsets) { //X⊆Y ⇔ X R Y という定義で自己関係Rを定義 if (subsetX.IsSubsetOf(subsetY)) { retRel.Add((subsetX, subsetY)); } } } return(retRel); }
/// <summary> /// 自己関係Rが整礎的かどうか。 /// X の任意の空でない部分集合Sが、極小元s(Sのどの元xもxRsとならない)を持つ /// ∀S ⊆ X (S ≠ X → ∃s∈S ∀x∈X ¬(x R s) ) /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>整礎的</returns> public static bool isWellFounded <T>(this EndoRelation <T> rel) { //全部分集合を取ることは冪集合をとることに等しく、こいつは場合によっては生成が5000兆時間かかるため、 //部分集合を生成しながら正誤の判定をする SortedSet <T> universe = rel.Universe; /// ∀S ⊆ X (S ≠ X → ∃s∈S ∀x∈X ¬(x R s) ) /// ¬(∃S ⊆ X ¬(S ≠ X → ∃s∈S ∀x∈X ¬(x R s) )) /// ¬(∃S ⊆ X (S = X ← ¬(∃s∈S ∀x∈X ¬(x R s)) )) // 1 << n は 2^n (2のn乗) for (int index = 0; index < (1 << universe.Count); index++) { var subset = new SortedSet <T>(); int bit = 0; foreach (var element in universe) { if ((index & (1 << bit)) != 0) { subset.Add(element); } bit++; } //判定を行う //空集合の場合は除外 if (subset.Count == 0) { continue; } bool existS = false; foreach (var itemS in subset) { //極小元だとわかった場合 if (rel.isMinimalElement(itemS)) { //だいたいの場合当てはまると思うが、一応 if (!(subset is null)) { existS = true; } } } //subsetにSがないとわかったら偽 if (existS) { return(false); } } return(true); }
/// <summary> /// 自己関係Rが非反射的かどうか。 /// すべての x∈U について x R x を満たさない /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>非反射的</returns> public static bool isIreflexive <T>(this EndoRelation <T> rel) { foreach (var item in rel.Universe) { //item R itemを満たす場合は偽 if (hasRelation(item, rel, item)) { return(false); } } return(true); }
/// <summary> /// 自己関係Rが完全性をもつかどうか。 /// X の各元 x, y について、x R y または y R x の一方あるいは両方が必ず満足される /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>完全性</returns> public static bool isTotal <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { // ItemX R ItemY でも ItemY R ItemXでもない場合があるなら偽 if (!hasRelation(itemX, rel, itemY) && !hasRelation(itemX, rel, itemY)) { return(false); } } } return(true); }
/// <summary> /// 自己関係Rが対称的かどうか。 /// X の各元 x, y について、x R y ならば y R x が成り立つ /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>対称的</returns> public static bool isSymmetric <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { //itemX R itemY だが itemY R itemX でない場合は偽 if (hasRelation(itemX, rel, itemY)) { if (!hasRelation(itemY, rel, itemX)) { return(false); } } } } return(true); }
/// <summary> /// 自己関係Rが余反射的かどうか。 /// X の各元 x, y について、x R y ならば x = y が成り立つ /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>余反射的</returns> public static bool isCoreflexive <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { //itemX R itemY だが itemX != itemY の場合は偽 if (hasRelation(itemX, rel, itemY)) { if (!itemX.Equals(itemY)) { return(false); } } } } return(true); }
/// <summary> /// 集合Sから、直積S×Sとなる自己関係R=S×Sを作成 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="originalSet">台集合</param> /// <returns>自己関係R=originalSet×originalSet</returns> public static EndoRelation <T> MakeSetProductSet <T>(SortedSet <T> originalSet) { if (originalSet is null) { throw new ArgumentNullException(nameof(originalSet)); } var retRel = new EndoRelation <T>(); foreach (var item1 in originalSet) { foreach (var item2 in originalSet) { retRel.Add((item1, item2)); } } return(retRel); }
/// <summary> /// 自己関係Rが反対称的かどうか。 /// X の各元 x, y について、x R y かつ y R x ならば x = yが成り立つ /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>反対称的</returns> public static bool isAntiSymmetric <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { //itemX R itemY かつ itemY R itemX だが、 if (hasRelation(itemX, rel, itemY) && hasRelation(itemY, rel, itemX)) { //itemXとitemYの値が同じでない場合は偽 if (!itemX.Equals(itemY)) { return(false); } } } } return(true); }
/// <summary> /// 自己関係Rが非対称かどうか。 /// X の各元 x, y について、x R y ならば 常に y R x が偽 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>非対称</returns> public static bool isAsymmetric <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { //itemX R itemY だが、 if (hasRelation(itemX, rel, itemY)) { //itemY R itemX の場合があるなら偽 if (hasRelation(itemY, rel, itemX)) { return(false); } } } } return(true); }
/// <summary> /// 自己関係Rが右一意的であるかどうか /// x R y かつ x R z なるときは必ず y = z となる /// 函数的・部分写像ともいう /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>右一意的</returns> public static bool isRightUnique <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { foreach (var itemZ in rel.Universe) { //x R y かつ x R z なるときは必ず y = z となる if (hasRelation(itemX, rel, itemY) && hasRelation(itemX, rel, itemZ)) { if (!(itemY.Equals(itemZ))) { return(false); } } } } } return(true); }
/// <summary> /// 自己関係Rが連続的かどうか。 /// X の各元 x に対して、x R y となるような y ∈ X がそれぞれとれる /// 必ず x R y かつ y R x が成り立つ /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>連続的</returns> public static bool isSerial <T>(this EndoRelation <T> rel) { //左全域的と全く同じ定義 foreach (var itemX in rel.Universe) { bool ExistY = false; foreach (var itemY in rel.Universe) { if (hasRelation(itemX, rel, itemY)) { ExistY = true; break; } } if (ExistY == false) { return(false); } } return(true); }
/// <summary> /// 自己関係Rが推移的かどうか。 /// X の各元 x, y について、x R y かつ y R z ならば x R z /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係</param> /// <returns>推移的</returns> public static bool isTransitive <T>(this EndoRelation <T> rel) { foreach (var itemX in rel.Universe) { foreach (var itemY in rel.Universe) { foreach (var itemZ in rel.Universe) { //itemX R itemY かつ itemY R itemZ だが、 if (hasRelation(itemX, rel, itemY) && hasRelation(itemY, rel, itemZ)) { //itemX R itemZ でない場合があるなら偽 if (!hasRelation(itemX, rel, itemZ)) { return(false); } } } } } return(true); }
/// <summary> /// 自己関係Rが右全域的かどうか /// U の各元 y に対して、それぞれ x R y となるような x ∈ U がとれる(存在する) /// 全射とも言う /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係R</param> /// <returns>右全域的</returns> public static bool isRightTotal <T>(this EndoRelation <T> rel) { foreach (var itemY in rel.Universe) { bool ExistX = false; foreach (var itemX in rel.Universe) { if (hasRelation <T>(itemX, rel, itemY)) { ExistX = true; break; } } if (ExistX == false) { return(false); } } return(true); }
/// <summary> /// 自己関係Rが一対一であるかどうか /// 左一意的かつ右一意的 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係R</param> /// <returns>一対一</returns> public static bool isOneToOne <T>(this EndoRelation <T> rel) { return(rel.isLeftUnique() && rel.isRightUnique()); }
/// <summary> /// 自己関係Rが対応かどうか /// 左全域的かつ右全域的 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係R</param> /// <returns>対応</returns> public static bool isCorrespondence <T>(this EndoRelation <T> rel) { return(rel.isLeftTotal() && rel.isRightTotal()); }
/// <summary> /// 自己関係Rが関数かどうか /// 右一意的かつ左全域的 /// 函数関係・一意対応・写像とも言う /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係R</param> /// <returns>関数</returns> public static bool isFunction <T>(this EndoRelation <T> rel) { return(rel.isLeftTotal() && rel.isRightUnique()); }
/// <summary> /// 自己関係Rが全単射かどうか /// 一対一かつ対応 /// 一対一対応・双射とも言う もちろん関数の条件を満たす /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rel">自己関係R</param> /// <returns>関数</returns> public static bool isBijection <T>(this EndoRelation <T> rel) { return(rel.isOneToOne() && rel.isCorrespondence()); }
/// <summary> /// 自己関係Rについて、 x R yを満たすかどうか /// </summary> /// <typeparam name="T"></typeparam> /// <param name="item1">左辺</param> /// <param name="rel">関係</param> /// <param name="item2">右辺</param> /// <returns>x R yを満たす</returns> public static bool hasRelation <T>(this T item1, EndoRelation <T> rel, T item2) { return(rel.Contains((item1, item2))); }