@@ -8,32 +8,107 @@ namespace Plang.Compiler.TypeChecker;
8
8
9
9
public abstract class ParamAssignment
10
10
{
11
- private static Dictionary < string , IPExpr > Dic2StrDic ( Dictionary < Variable , IPExpr > dic )
11
+ private static IEnumerable < IEnumerable < T > > DifferentCombinations < T > ( IEnumerable < T > elements , int k )
12
12
{
13
- var dicAux = new Dictionary < string , IPExpr > ( ) ;
14
- foreach ( var ( k , i ) in dic )
13
+ var enumerable = elements as T [ ] ?? elements . ToArray ( ) ;
14
+ return k == 0
15
+ ? [ Array . Empty < T > ( ) ]
16
+ : enumerable . SelectMany ( ( e , i ) =>
17
+ DifferentCombinations ( enumerable . Skip ( i + 1 ) , k - 1 ) . Select ( c => new [ ] { e } . Concat ( c ) ) ) ;
18
+ }
19
+
20
+ private static Dictionary < int , T > EnumerableToIndexDict < T > ( IEnumerable < T > l , Func < T , T > f )
21
+ {
22
+ return Enumerable . Range ( 0 , l . Count ( ) ) . Zip ( l , ( a , b ) => new { a , b } ) . ToDictionary ( x => x . a , x => f ( x . b ) ) ;
23
+ }
24
+
25
+ private static Dictionary < int , Dictionary < string , int > > MakeVectorMap ( Dictionary < string , int > universe , int twise )
26
+ {
27
+ var vectorSet = new HashSet < Dictionary < string , int > > ( ) ;
28
+ foreach ( var param in DifferentCombinations ( universe . Select ( kv => kv . Key ) , twise ) )
29
+ {
30
+ var result = new List < Dictionary < string , int > > { new ( ) } ;
31
+ foreach ( var name in param )
32
+ {
33
+ var newResult = new List < Dictionary < string , int > > ( ) ;
34
+ for ( var i = 0 ; i < universe [ name ] ; i ++ )
35
+ {
36
+ var resultCopy = result . Select ( dict => dict . ToDictionary ( kv => kv . Key , kv => kv . Value ) ) . ToList ( ) ;
37
+ foreach ( var vector in resultCopy ) vector . Add ( name , i ) ;
38
+ newResult . AddRange ( resultCopy ) ;
39
+ }
40
+
41
+ result = newResult ;
42
+ }
43
+
44
+ vectorSet . UnionWith ( result ) ;
45
+ }
46
+
47
+ return EnumerableToIndexDict ( vectorSet , x => x ) ;
48
+ }
49
+
50
+ private static Dictionary < int , HashSet < int > > MakeAssignmentCoverageMap (
51
+ Dictionary < int , Dictionary < string , int > > assignmentMap ,
52
+ Dictionary < int , Dictionary < string , int > > vectorMap ,
53
+ List < int > assignments )
54
+ {
55
+ var assignmentCoverageMap = new Dictionary < int , HashSet < int > > ( ) ;
56
+ foreach ( var assignment in assignments )
15
57
{
16
- dicAux [ k . Name ] = i ;
58
+ assignmentCoverageMap . Add ( assignment , [ ] ) ;
59
+ foreach ( var kv in vectorMap . Where ( kv => kv . Value . All ( assignmentMap [ assignment ] . Contains ) ) )
60
+ assignmentCoverageMap [ assignment ] . Add ( kv . Key ) ;
17
61
}
62
+
63
+ return assignmentCoverageMap ;
64
+ }
65
+
66
+ private static List < int > GreedyCoverageExplore ( Dictionary < string , int > universe ,
67
+ List < Dictionary < string , int > > assignmentList , int twise )
68
+ {
69
+ var assignments = Enumerable . Range ( 0 , assignmentList . Count ) . ToList ( ) ;
70
+ if ( twise == universe . Count ) return assignments ;
71
+ var vectorMap = MakeVectorMap ( universe , twise ) ;
72
+ var assignmentMap = EnumerableToIndexDict ( assignmentList , x => x ) ;
73
+ var assignmentCoverageMap = MakeAssignmentCoverageMap ( assignmentMap , vectorMap , assignments ) ;
74
+ var obligationSet = vectorMap . Keys . ToHashSet ( ) ;
75
+ obligationSet . IntersectWith ( assignmentCoverageMap . SelectMany ( kv => kv . Value ) ) ;
76
+ foreach ( var kv in assignmentCoverageMap ) assignmentCoverageMap [ kv . Key ] . IntersectWith ( obligationSet ) ;
77
+ var result = new List < int > ( ) ;
78
+ while ( obligationSet . Count != 0 )
79
+ {
80
+ var ( ass , coverage ) = assignmentCoverageMap . MaxBy ( kv => kv . Value . Count ) ;
81
+ obligationSet . ExceptWith ( coverage ) ;
82
+ assignmentCoverageMap . Remove ( ass ) ;
83
+ foreach ( var kv in assignmentCoverageMap ) assignmentCoverageMap [ kv . Key ] . ExceptWith ( coverage ) ;
84
+ result . Add ( ass ) ;
85
+ }
86
+
87
+ return result ;
88
+ }
89
+
90
+ private static Dictionary < string , IPExpr > Dic2StrDic ( Dictionary < Variable , IPExpr > dic )
91
+ {
92
+ var dicAux = new Dictionary < string , IPExpr > ( ) ;
93
+ foreach ( var ( k , i ) in dic ) dicAux [ k . Name ] = i ;
18
94
return dicAux ;
19
95
}
20
96
21
- private static Dictionary < Variable , IPExpr > IndexDic2Dic ( List < Variable > globalParams , IDictionary < string , List < IPExpr > > paramExprDic , IDictionary < string , int > indexDic )
97
+ private static Dictionary < Variable , IPExpr > IndexDic2Dic ( List < Variable > globalParams ,
98
+ IDictionary < string , List < IPExpr > > paramExprDic , IDictionary < string , int > indexDic )
22
99
{
23
100
var dic = new Dictionary < Variable , IPExpr > ( ) ;
24
101
foreach ( var ( k , i ) in indexDic )
25
102
{
26
103
var values = paramExprDic [ k ] ;
27
104
var variable = globalParams . First ( v => v . Name == k ) ;
28
- if ( i >= values . Count )
29
- {
30
- throw new ArgumentException ( "Index out of range in global variable config." ) ;
31
- }
105
+ if ( i >= values . Count ) throw new ArgumentException ( "Index out of range in global variable config." ) ;
32
106
dic [ variable ] = values [ i ] ;
33
107
}
108
+
34
109
return dic ;
35
110
}
36
-
111
+
37
112
public static string RenameSafetyTestByAssignment ( string name , Dictionary < Variable , IPExpr > dic )
38
113
{
39
114
var postfix = $ "{ string . Join ( "__" , Dic2StrDic ( dic ) . ToList ( ) . Select ( p => $ "{ p . Key } _{ p . Value } ") ) } ";
@@ -45,26 +120,29 @@ private static bool Next((string, int)[] indexArr, IDictionary<string, List<IPEx
45
120
for ( var i = 0 ; i < indexArr . Length ; i ++ )
46
121
{
47
122
indexArr [ i ] = ( indexArr [ i ] . Item1 , indexArr [ i ] . Item2 + 1 ) ;
48
- // Console.WriteLine($"globalParams[globalVariables[{i}].Name].Count = {globalParams[globalVariables[i].Name].Count}");
49
123
if ( indexArr [ i ] . Item2 < globalParams [ indexArr [ i ] . Item1 ] . Count ) return true ;
50
124
indexArr [ i ] = ( indexArr [ i ] . Item1 , 0 ) ;
51
125
}
126
+
52
127
return false ;
53
128
}
54
129
55
- public static void IterateAssignments ( SafetyTest safety , List < Variable > globalParams , Action < Dictionary < Variable , IPExpr > > f )
130
+ public static void IterateAssignments ( SafetyTest safety , List < Variable > globalParams ,
131
+ Action < Dictionary < Variable , IPExpr > > f )
56
132
{
57
- // Console.WriteLine($"safety.ParamExpr.Count = {safety.ParamExpr.Count}");
58
- var indexArr = safety . ParamExprMap . ToList ( ) . Zip ( Enumerable . Repeat ( 0 , safety . ParamExprMap . Count ) , ( x , y ) => ( x . Key , y ) ) . ToArray ( ) ;
133
+ var indexArr = safety . ParamExprMap . ToList ( )
134
+ . Zip ( Enumerable . Repeat ( 0 , safety . ParamExprMap . Count ) , ( x , y ) => ( x . Key , y ) ) . ToArray ( ) ;
135
+ var universe = safety . ParamExprMap . ToDictionary ( kv => kv . Key , kv => kv . Value . Count ) ;
136
+ var assignmentIndices = new List < Dictionary < string , int > > ( ) ;
59
137
do
60
138
{
61
139
var indexDic = indexArr . ToDictionary ( item => item . Item1 , item => item . Item2 ) ;
62
140
var dic = IndexDic2Dic ( globalParams , safety . ParamExprMap , indexDic ) ;
63
- // Console.WriteLine($"{string.Join(',', dic.ToList())} |- {safety.AssumeExpr}");
64
- // Console.WriteLine($"{string.Join(',', dic.ToList())} |- {safety.AssumeExpr} = {ForceBool(Eval(dic, safety.AssumeExpr))}");
65
141
if ( ! SimpleExprEval . ForceBool ( SimpleExprEval . Eval ( dic , safety . AssumeExpr ) ) ) continue ;
66
- // Console.WriteLine($"indexArr: {string.Join(',', indexArr)}");
67
- f ( dic ) ;
142
+ assignmentIndices . Add ( indexDic ) ;
68
143
} while ( Next ( indexArr , safety . ParamExprMap ) ) ;
144
+
145
+ foreach ( var i in GreedyCoverageExplore ( universe , assignmentIndices , safety . Twise ) )
146
+ f ( IndexDic2Dic ( globalParams , safety . ParamExprMap , assignmentIndices [ i ] ) ) ;
69
147
}
70
148
}
0 commit comments