-
Notifications
You must be signed in to change notification settings - Fork 46
/
Hypergraph.m
110 lines (77 loc) · 3.35 KB
/
Hypergraph.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Package["SetReplace`"]
PackageImport["GeneralUtilities`"]
PackageExport["Hypergraph"]
PackageExport["HypergraphQ"]
PackageExport["HypergraphSymmetry"]
SetRelatedSymbolGroup[Hypergraph, HypergraphQ, HypergraphSymmetry, EdgeList, VertexList];
(* HypergraphQ *)
SetUsage @ "HypergraphQ[hg$] yields True if hg$ is a valid Hypergraph object and False otherwise.";
SyntaxInformation[HypergraphQ] = {"ArgumentsPattern" -> {expr_}};
HypergraphQ[expr_Hypergraph] := System`Private`HoldNoEntryQ[expr];
HypergraphQ[_] = False;
(* HypergraphSymmetry *)
$hypergraphSymmetries = {"Ordered", "Unordered", "Cyclic", "Directed"};
SetUsage @ "HypergraphSymmetry[hg$] returns the symmetry of the hypergraph hg$.";
HypergraphSymmetry[HoldPattern[Hypergraph[hyperedges_, symmetry_] ? HypergraphQ]] := symmetry;
(* Hypergraph *)
SetUsage[Hypergraph, "
Hypergraph[{he$1, he$2, $$}] yields an ordered hypergraph with hyperedges he$j.
Hypergraph[$$, sym$] returns a hypergraph with symmetry sym$.
* Valid hypergraph symmetries include: " <> listToSentence[$hypergraphSymmetries] <> ".
"];
SyntaxInformation[Hypergraph] = {"ArgumentsPattern" -> {hyperedges_, symmetry_.}};
Hypergraph /: Information`GetInformation[obj_Hypergraph ? HypergraphQ] :=
<|
"ObjectType" -> Hypergraph,
"Symmetry" -> HypergraphSymmetry,
"VertexCount" -> VertexCount[obj],
"EdgeCount" -> EdgeCount[obj]
|>;
Default[Hypergraph, 2] = "Ordered";
((expr : Hypergraph[args___]) ? System`Private`HoldEntryQ) /; CheckArguments[expr, {1, 2}] :=
hypergraph[args];
hypergraph[hyperedges : {___List}, symmetry : Alternatives @@ $hypergraphSymmetries] :=
System`Private`ConstructNoEntry[Hypergraph, hyperedges, symmetry];
Hypergraph::invalidHyperedges = "The argument at position 1 should be ";
hypergraph[hyperedges_] := hypergraph[hyperedges, "Ordered"];
hypergraph[hyperedges_, symmetry : Alternatives @@ $hypergraphSymmetries] :=
Failure["HypergraphFailure", <|
"MessageTemplate" -> "`1` should be a list of of lists representing hyperedges.",
"MessageParameters" -> {hyperedges},
"Input" -> hyperedges
|>];
hypergraph[hyperedges_, symmetry_] :=
Failure["HypergraphFailure", <|
"MessageTemplate" -> "`1` should be a supported symmetry: `2`.",
"MessageParameters" -> {symmetry, $hypergraphSymmetries},
"Input" -> symmetry
|>];
(* Accessors *)
Hypergraph /: EdgeList[HoldPattern[Hypergraph[hyperedges_, _] ? HypergraphQ]] := hyperedges;
Hypergraph /: EdgeCount[hg_Hypergraph ? HypergraphQ] := Length[EdgeList[hg]];
Hypergraph /: VertexList[hg_Hypergraph ? HypergraphQ] := DeleteDuplicates[Catenate[EdgeList[hg]]];
Hypergraph /: VertexCount[hg_Hypergraph ? HypergraphQ] := Length[VertexList[hg]];
(* Normal *)
Hypergraph /: Normal[hg_Hypergraph ? HypergraphQ] := EdgeList[hg];
(* SameQ *)
Hypergraph /: SameQ[hg1_Hypergraph, hg2_Hypergraph] := Normal[hg1] === Normal[hg2];
(* Boxes *)
Hypergraph /: MakeBoxes[hg_Hypergraph ? HypergraphQ, fmt_] :=
Module[{collapsed, expanded},
collapsed = BoxForm`SummaryItem /@ {
{"VertexCount: ", VertexCount[hg]},
{"EdgeCount: ", EdgeCount[hg]}
};
expanded = BoxForm`SummaryItem /@ {
{"Symmetry: ", HypergraphSymmetry[hg]}
};
BoxForm`ArrangeSummaryBox[
Hypergraph,
hg,
HypergraphPlot[EdgeList[hg], ImageSize -> {29, 29}],
collapsed,
expanded,
fmt,
"Interpretable" -> True
]
];