1 |
On Wed, 31 May 2017 15:04:52 +0200 |
2 |
Michał Górny <mgorny@g.o> wrote: |
3 |
|
4 |
> On śro, 2017-05-31 at 10:38 +0200, Alexis Ballier wrote: |
5 |
> > > > What if I specifically set USE=-bar in make.conf ? Do we really |
6 |
> > > > want PM to override that without telling me ? |
7 |
> > > |
8 |
> > > Yes. Unless you specifically and explicitly disable that |
9 |
> > > (globally or for USE=bar), in which case the PM would just reject |
10 |
> > > to proceed. |
11 |
> > |
12 |
> > |
13 |
> > Then could you please explain how to get the list of useflags the |
14 |
> > solver is allowed to toggle ? Preferably in a PMS-friendly way (aka |
15 |
> > no USE=foo emerge). It's not clear to me what this would be and is |
16 |
> > mandatory for determinism. |
17 |
> > |
18 |
> > Note that most definitions are acceptable, but there must be one. |
19 |
> |
20 |
> If we *really* want to set this for the users, it would simply be |
21 |
> a variable defined in make.profile, e.g.: |
22 |
> |
23 |
> REQUIRED_USE_STRICT="foo bar" |
24 |
> |
25 |
> which would mean the solver is globally forbidden from touching those |
26 |
> flags, i.e. if the solution would involve touching them, PM must fail |
27 |
> and request user to manually resolve it. |
28 |
> |
29 |
> However, as far as I'm concerned we'd be good at keeping this purely |
30 |
> as user configuration, alike FEATURES=i-do-not-want-automatic-solving. |
31 |
|
32 |
Ok, why not. |
33 |
|
34 |
> > > > I believe that, from the ebuild POV, the ternary useflag model |
35 |
> > > > is more appropriate: You have a whole bunch of ways to specify |
36 |
> > > > useflags with portage (make.conf, package.use, profiles, command |
37 |
> > > > line, ...). From the ebuild those are collapsed into 'user |
38 |
> > > > input'. You only have IUSE (with its defaults) and that's what |
39 |
> > > > the auto-solver should play with: those are the flags that can |
40 |
> > > > be toggled. |
41 |
> > > |
42 |
> > > I see your point. However, it's merely a preference problem and we |
43 |
> > > really don't want the constraints to become ternary and/or PM try |
44 |
> > > to force the reverse solutions. That's an easy way to lose |
45 |
> > > predictability. |
46 |
> > |
47 |
> > They're not ternary anymore after processing ebuild: IUSE="foo +bar" |
48 |
> > means instantiate foo as -foo if not specified, and bar as +bar. |
49 |
> > The way I see it, ternary model is useful in the sense that the 3rd |
50 |
> > undefined state is what the solver can toggle, the others are fixed |
51 |
> > (either by user input or e.g. use.mask). |
52 |
> > |
53 |
> > Basically, I see automatic solving of REQUIRED_USE as dynamic IUSE |
54 |
> > defaults. But see above, this might not be the best way. |
55 |
> |
56 |
> I'm lost on what you're trying to achieve here. Maybe give a full run- |
57 |
> out based on Portage behavior -- i.e. involving all the places USE |
58 |
> flags can be altered in Portage, and how they're going to affect the |
59 |
> result. Don't forget about USE_ORDER. |
60 |
|
61 |
What I'm suggesting is: Flags that can be toggled are the same that |
62 |
would be affected by IUSE defaults. Others are fixed and the |
63 |
REQUIRED_USE formula is instantiated & reduced with those values. If |
64 |
there is a contradiction already, fail hard. If not, apply the |
65 |
algorithm to determine a set of IUSE defaults that would make it |
66 |
work. Process the ebuild as if it had those IUSE default. |
67 |
|
68 |
You seem to be going in another direction which is unclear to me. |
69 |
|
70 |
[...] |
71 |
> > > > > Now, this also means that every constraint that can't be |
72 |
> > > > > solved in this easy fashion is invalid. We want to detect |
73 |
> > > > > that, and warn the developer. Some of those could be tricky. |
74 |
> > > > > Simple example: |
75 |
> > > > > |
76 |
> > > > > foo? ( baz ) bar? ( !baz ) |
77 |
> > > > > |
78 |
> > > > > This one is invalid because USE='foo bar' requires both 'baz' |
79 |
> > > > > and '!baz' as a solution. Remember that we don't want to do |
80 |
> > > > > any changes besides what's explicitly written there, no |
81 |
> > > > > guessing. |
82 |
> > > > |
83 |
> > > > Besides that, what makes it invalid ? |
84 |
> > > |
85 |
> > > What makes it invalid is that you can't solve it in a predictable |
86 |
> > > way. |
87 |
> > |
88 |
> > You can fail in a predictable way and ebuild writer can adjust it to |
89 |
> > avoid that. |
90 |
> |
91 |
> If the point is to process constraints *automatically*, then failing |
92 |
> is not the desired result. Yes, we can consider that a minor |
93 |
> issue/warning level but it is still an issue. I named it 'invalid' |
94 |
> because it prevents the automatic solving from working which is the |
95 |
> purpose of this whole effort. |
96 |
|
97 |
Ok. I was assuming we do not want to change anything user-specified. |
98 |
When I set USE=foo, I want foo, not maybe foo. But why not: As you |
99 |
noted this can be a PM feature and there's not much to be checked in |
100 |
that case. |
101 |
|
102 |
As for how to check that, it is still completely unclear to me if |
103 |
there'd be anything better than enumerating all the possible inputs. |
104 |
|
105 |
|
106 |
> > Again, you *need* to process the constraints in order. '!a? |
107 |
> > ( b ) !b? ( a )' is not deterministic when none of a and b are |
108 |
> > enabled otherwise. |
109 |
> |
110 |
> You can't rely on any particular order of constraints, especially when |
111 |
> eclass stacking comes into play. You could try defining some |
112 |
> constraint- sorting algorithm but it's going to be complex and it's |
113 |
> usefulness will be limited anyway due to various kinds of grouping. |
114 |
|
115 |
|
116 |
Better have some order: If half of the above constraint comes from |
117 |
ebuild and the other half comes from eclass, then PM might toggle 'a' or |
118 |
'b' depending on the phase of the moon which is specifically what we're |
119 |
trying to avoid. |
120 |
|
121 |
eclass stacking is not a problem: specify if it's append or prepend and |
122 |
be done. |
123 |
|
124 |
Note that if you want to remove the need for an order, you'll need to |
125 |
ensure that all orderings of the constraints give the same result. It's |
126 |
not sufficient to "only" check all possible inputs. |
127 |
|
128 |
Also, what happens if we applied all the constraints and obtained some |
129 |
useflags setting that still fails REQUIRED_USE check ? |
130 |
|
131 |
|
132 |
> > You'll get a message like: |
133 |
> > " |
134 |
> > The constraint bar? ( !baz )' is violated. |
135 |
> > bar is enabled because $reason (say, make.conf) |
136 |
> > baz is enabled because of the constraint 'foo? ( baz )' |
137 |
> > foo is enabled because $reason |
138 |
> > " |
139 |
> |
140 |
> You = user or ebuild author? Because per my proposal, this construct |
141 |
> should result in QA error/warning, telling the ebuild writer to use |
142 |
> predictable constraints. |
143 |
> |
144 |
> Of course, we could still accept the ebuild and just fail hard on user |
145 |
> side (alike REQUIRED_USE). But that's really getting out of scope. |
146 |
|
147 |
you = user because he asked for an invalid combination. Note that you |
148 |
have not yet given a proper definition of predictable constraint. |
149 |
|
150 |
|
151 |
[...] |
152 |
> > |
153 |
> > > which gives a single predictable solution: |
154 |
> > |
155 |
> > Then ebuild writer should not write 'foo? ( baz ) bar? ( !baz )' but |
156 |
> > rather: 'foo? ( !bar baz ) bar? ( !baz )', which should cover more |
157 |
> > cases. With USE="foo bar", the message would then be: |
158 |
> > " |
159 |
> > The constraint 'foo? ( !bar )' is violated. |
160 |
> > foo is enabled because $reason |
161 |
> > bar is enabled because $reason |
162 |
> > " |
163 |
> > which is similar to the above except there's one less step for |
164 |
> > explaining the reasons. It's not dramatic but it is, indeed, |
165 |
> > desirable to have simple & clear reasons. I'd say that's more to |
166 |
> > the argument for specifying completely how to solve that and leave |
167 |
> > those small improvements to ebuild writers and/or QA. |
168 |
> |
169 |
> Is this message meant to be disabled for the purpose of explaining |
170 |
> automatic decisions, or as an error? |
171 |
|
172 |
As an error because user specified invalid combination, but now I see |
173 |
your point: You want to override user settings too. |
174 |
|
175 |
> Also, your example (unlike the one I gave in the original mail) |
176 |
> prefers foo over bar. That's the only difference. |
177 |
|
178 |
Yes, I realize that now :) |
179 |
|
180 |
> > |
181 |
> > [...] |
182 |
> > > > > However, the |
183 |
> > > > > following should be valid: |
184 |
> > > > > |
185 |
> > > > > foo? ( baz ) bar? ( !foo !baz ) |
186 |
> > > > > |
187 |
> > > > > Because now we clearly indicate that USE=bar disables USE=foo, |
188 |
> > > > > and therefore makes the first constraint inapplicable. It |
189 |
> > > > > clearly indicates course of action for all combinations: |
190 |
> > > > |
191 |
> > > > Ok, I now think you're aiming for giving full power to the |
192 |
> > > > solver, overriding user inputs if necessary. Before going |
193 |
> > > > further, I think we should first agree on what are the useflags |
194 |
> > > > such a solver can toggle. I'm not sure 'USE=foo emerge blah' |
195 |
> > > > should disable foo instead of failing for example. |
196 |
> > > > |
197 |
> > > |
198 |
> > > As I said, it's a matter of configuration to decide which flags |
199 |
> > > should be touched, and which not. Of course if we find that |
200 |
> > > necessary, we may go into defining a specific set in the profiles |
201 |
> > > or metadata. |
202 |
> > > |
203 |
> > > However, I would rather focus on getting a PoC solver and checker |
204 |
> > > first, and play with existing constraints to see how it all |
205 |
> > > works. |
206 |
> > |
207 |
> > The solver seems on good tracks, at least from the algorithmic POV. |
208 |
> > The checker, however, is not clear at all to me. The main reason is |
209 |
> > that to determine if the solver will be able to solve it, it needs |
210 |
> > to know what the solver can toggle and what not. |
211 |
> > |
212 |
> |
213 |
> The point would be: by definition, the solver should be able to touch |
214 |
> *any* USE flag. If it can't, it mostly implies that you can't use |
215 |
> the automatic solver, and so the case is irrelevant for checking. |
216 |
> Attempting to go beyond that is going to give a lot of complexity |
217 |
> and most likely kill the whole idea. |
218 |
> |
219 |
> One thing we need to worry about are masks. We need to think about |
220 |
> them. |
221 |
|
222 |
It makes zero difference for any solver if you replace variables |
223 |
(useflags) by 'true' or 'false' constants (masked/forced/user-forced |
224 |
useflags). It's even simpler actually. Whether the formula is not |
225 |
constantly 'true' (ie REQUIRED_USE is useless) or constantly |
226 |
'false' (ie there's no way to solve it) is equivalent to solving SAT. |
227 |
We likely don't want that for repoman running on php. |
228 |
|
229 |
Alexis. |