-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathResPriority.mag
114 lines (98 loc) · 3.68 KB
/
ResPriority.mag
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
111
112
113
114
import "Utils.mag": not_implemented;
declare type PGGAlg_ResPriority: PGGAlg;
declare type PGGAlg_ResPriority_Null: PGGAlg_ResPriority;
declare type PGGAlg_ResPriority_Random: PGGAlg_ResPriority;
declare type PGGAlg_ResPriority_Reverse: PGGAlg_ResPriority;
declare attributes PGGAlg_ResPriority_Reverse: priority;
declare type PGGAlg_ResPriority_Key: PGGAlg_ResPriority;
declare attributes PGGAlg_ResPriority_Key: key;
declare type PGGAlg_ResPriority_Truncate: PGGAlg_ResPriority;
declare attributes PGGAlg_ResPriority_Truncate: priority, limit;
intrinsic PGGAlg_ResPriority_Null_Make() -> PGGAlg_ResPriority_Null
{The "Null" subgroups priority.}
alg := New(PGGAlg_ResPriority_Null);
return alg;
end intrinsic;
intrinsic PGGAlg_ResPriority_Random_Make() -> PGGAlg_ResPriority_Random
{The "Random" subgroups priority.}
alg := New(PGGAlg_ResPriority_Random);
return alg;
end intrinsic;
intrinsic PGGAlg_ResPriority_Reverse_Make(:Priority:=false) -> PGGAlg_ResPriority_Reverse
{The "Reverse" subgroups priority.}
alg := New(PGGAlg_ResPriority_Reverse);
alg`priority := Priority cmpne false select Priority else PGGAlg_ResPriority_Null_Make();
return alg;
end intrinsic;
intrinsic PGGAlg_ResPriority_Truncate_Make(limit :: RngIntElt : Priority:=false) -> PGGAlg_ResPriority_Truncate
{The "truncate" subgroups priority.}
require limit ge 0: "limit must be at least 0";
alg := New(PGGAlg_ResPriority_Truncate);
alg`limit := limit;
alg`priority := Priority cmpne false select Priority else PGGAlg_ResPriority_Null_Make();
return alg;
end intrinsic;
intrinsic PGGAlg_ResPriority_Key_Make(key :: PGGExpr) -> PGGAlg_ResPriority_Key
{The "Key" subgroups priority.}
alg := New(PGGAlg_ResPriority_Key);
assert FreeVariables(key) subset {"Index", "OrbitIndex", "Diversity", "Information"};
alg`key := key;
return alg;
end intrinsic;
intrinsic Print(alg :: PGGAlg_ResPriority_Null)
{Print.}
printf "null";
end intrinsic;
intrinsic Print(alg :: PGGAlg_ResPriority_Random)
{"}
printf "random";
end intrinsic;
intrinsic Print(alg :: PGGAlg_ResPriority_Reverse)
{"}
printf "reverse of %o", alg`priority;
end intrinsic;
intrinsic Print(alg :: PGGAlg_ResPriority_Truncate)
{"}
printf "truncate %o of %o", alg`limit, alg`priority;
end intrinsic;
intrinsic Print(alg :: PGGAlg_ResPriority_Key)
{"}
printf "key %o", alg`key;
end intrinsic;
intrinsic Prioritize(X, P :: PGGAlg_ResPriority_Null, s :: PGGAlgState_ResGroups) -> .
{Prioritizes X.}
return X;
end intrinsic;
intrinsic Prioritize(X, P :: PGGAlg_ResPriority_Reverse, s :: PGGAlgState_ResGroups) -> .
{Prioritizes X.}
return Reverse(Prioritize(X, P`priority, s));
end intrinsic;
intrinsic Prioritize(X, P :: PGGAlg_ResPriority_Random, s :: PGGAlgState_ResGroups) -> .
{Prioritizes X.}
return Shuffle(X);
end intrinsic;
intrinsic Prioritize(X, P :: PGGAlg_ResPriority_Key, s :: PGGAlgState_ResGroups) -> .
{"}
return SortBy(X, function (i)
return Evaluate(P`key, func<name | case<name |
"Index": Index(s`overgroup, i`subgroup),
"OrbitIndex": Index(s`overgroup, Stabilizer(s`overgroup, [{x : x in o} : o in Orbits(i`subgroup)])),
"Diversity": Diversity(i, s),
"Information": Information(i, s),
default: not_implemented(name)
>>);
end function);
end intrinsic;
intrinsic Prioritize(X, P :: PGGAlg_ResPriority_Truncate, s :: PGGAlgState_ResGroups) -> .
{"}
Y := Prioritize(X, P`priority, s);
xs := ToList(Y);
if #xs gt P`limit then
for i in [P`limit..#xs] do
Forget(xs[i]);
end for;
return PGG_ToIter(xs[1..P`limit]);
else
return Y;
end if;
end intrinsic;