1 |
On Wed, 14 Jun 2017 14:24:48 +0200 |
2 |
Michał Górny <mgorny@g.o> wrote: |
3 |
|
4 |
> On śro, 2017-06-14 at 11:06 +0200, Alexis Ballier wrote: |
5 |
> > On Wed, 14 Jun 2017 00:13:42 +0200 |
6 |
> > Michał Górny <mgorny@g.o> wrote: |
7 |
> > |
8 |
> > > On wto, 2017-06-13 at 12:27 +0200, Alexis Ballier wrote: |
9 |
> > > > On Mon, 12 Jun 2017 21:17:16 +0200 |
10 |
> > > > Michał Górny <mgorny@g.o> wrote: |
11 |
> > > > |
12 |
> > > > > I've actually started typing the initial specification |
13 |
> > > > > yesterday [1]. As you can see, banning the extra constraints |
14 |
> > > > > has made the algorithms much simpler. In particular: |
15 |
> > > > > |
16 |
> > > > > 1. You do not have to define 'falsify' for anything other than |
17 |
> > > > > pure flags -- which makes it easy to inline it. |
18 |
> > > > > |
19 |
> > > > > 2. ||, ??, ^^ groups are only flat lists of flags -- which |
20 |
> > > > > makes reordering and processing them trivial. |
21 |
> > > > > |
22 |
> > > > > 3. The algorithm is recursive only on USE-conditional groups. |
23 |
> > > > > This makes it trivial to make it iterative. Optimizations |
24 |
> > > > > become trivially possible. |
25 |
> > > > |
26 |
> > > > |
27 |
> > > > While you're right in one sense, you're mixing two different |
28 |
> > > > things here. What you wrote *is* recursive. It does not recurse |
29 |
> > > > just because you're assuming a restricted syntax. You're only |
30 |
> > > > saving two things: you don't need to define how to enforce to |
31 |
> > > > false (that is 3 lines not 3 pages :=) ) and you're avoiding |
32 |
> > > > the nested use conditionals that are already ill defined per |
33 |
> > > > the current spec (foo? bar is equivalent to && ( foo bar ) when |
34 |
> > > > nested) which I believe is already another problem. |
35 |
> > > > |
36 |
> > > > Then, remember how I wanted to be much more drastic than you in |
37 |
> > > > the beginning by killing all ||,&&,^^ etc. and keep only use |
38 |
> > > > conditionals in REQUIRED_USE ? Well, that's where the |
39 |
> > > > complexity comes. The whole deal then is to define rewriting |
40 |
> > > > rules for the AST so that the algorithm you describe executes |
41 |
> > > > the exact same instructions but the new AST only has use |
42 |
> > > > conditionals. This is more like writing a compiler for the |
43 |
> > > > spec, so this does not belong to the spec and there is no issue |
44 |
> > > > here. |
45 |
> > > |
46 |
> > > I'm looking for a compromise here. Killing those groups |
47 |
> > > completely is going to make things harder for users. Keeping them |
48 |
> > > with functionality limited to what's used in ~99.9% ebuilds |
49 |
> > > (based on your numbers) is IMO a better choice. |
50 |
> > |
51 |
> > I already said I see the limited syntax as a good thing because it |
52 |
> > forces devs to write constraints that have a natural interpretation |
53 |
> > in how it is solved. However, you can't limit the syntax without a |
54 |
> > new EAPI, and more importantly, properly solving does not even |
55 |
> > require limiting the syntax. |
56 |
> |
57 |
> Actually, you can, via a Gentoo policy. Since solving is not required |
58 |
> by the PMS, there is no rule saying it has to work for every |
59 |
> constraint allowed by the PMS. |
60 |
|
61 |
Indeed. But you're trying to make rules that it has *not* to work for |
62 |
some of them for reasons that look more like laziness in trying to |
63 |
understand the problem than anything else. |
64 |
|
65 |
> Much like, you can't force a particular ordering or forbid circular |
66 |
> constraints without a new EAPI. Yet you do it because it gives |
67 |
> a practical improvement. |
68 |
|
69 |
I don't see this being enforced by a new EAPI. It's more a matter of QA |
70 |
tools like repoman. The main difference is that there are real reasons |
71 |
for forbidding circular constraints: For true circular ones, no solver |
72 |
will ever be able to solve it... |
73 |
|
74 |
[...] |
75 |
> > |
76 |
> > > > [BTW: checking the rewrite rules behave properly is what I |
77 |
> > > > meant by rebasing solve() on top of it and being happy with |
78 |
> > > > it] |
79 |
> > > |
80 |
> > > Could you reiterate the current solving rules (trueify/falsify)? |
81 |
> > > Are they equal to the ones you listed last, or does the current |
82 |
> > > implementation change anything? |
83 |
> > |
84 |
> > Let's recap a bit. nsolve() is poorly named and does not solve |
85 |
> > anything. It translates to implications and checks whether the |
86 |
> > implications solver will always provide a valid result in one pass. |
87 |
> > So, if you only care about solving rules, read your spec man. For |
88 |
> > the more general case it should behave like those trueify/falsify |
89 |
> > with the change that nested implications are interpreted as && (so |
90 |
> > no more !(a -> b) crap to worry about). |
91 |
> |
92 |
> How are && ( a b... ) falsified now? Leftmost only? |
93 |
|
94 |
$ python3 to_impl.py '?? ( a ( b c ) )' |
95 |
Normalized: [|| [!b, !c, !a]] |
96 |
List of implications: |
97 |
[[c, a]? => !b] |
98 |
|
99 |
Sounds like it. This is the only "stable" way anyway. |
100 |
|
101 |
|
102 |
> > If you take solve() as an implementation of your spec, you have: |
103 |
> > solve(x) <=> solve(to_impl.convert_to_implications(x)) when solve(x) |
104 |
> > is defined; with the added benefit that |
105 |
> > 'solve(to_impl.convert_to_implications(x))' is defined and should |
106 |
> > provide proper results on the whole REQUIRED_USE syntax as currently |
107 |
> > defined (granted that nsolve(x) does not report anything wrong). |
108 |
> |
109 |
> The point is, solve() is supposed to work without any additional |
110 |
> transformations. |
111 |
|
112 |
Then I already explained how to make it work. |
113 |
|
114 |
Transformations are out of scope of the spec and more for improving |
115 |
code sharing: Those are required for checking that the solver will |
116 |
provide a proper solution; if there is some flaw or undefined behavior |
117 |
in the spec, then solve() might change, if both the solver and the |
118 |
checker work on the same input data then at least there won't be some |
119 |
desynchronization between them. |
120 |
|
121 |
[...] |
122 |
> > > > > [1]:https://wiki.gentoo.org/wiki/User:MGorny/GLEP:ReqUse |
123 |
> > > > |
124 |
> > > > I really don't like the reordering thing. Even the restricted |
125 |
> > > > syntax does not fix the issue with '^^ ( a b ) b? ( a )' already |
126 |
> > > > mentioned here. It'd be much better and simpler for the spec |
127 |
> > > > just to assign a fixed value and use the solving rules with |
128 |
> > > > those. |
129 |
> > > |
130 |
> > > You're not going to convince me by providing examples that are |
131 |
> > > utterly broken by design and meaningless ;-). |
132 |
> > |
133 |
> > Well... if it's so obvious that the example is broken by design that |
134 |
> > you don't even bother to explain why, I assume you have an |
135 |
> > algorithm for that. Where is the code ? What are the numbers ? How |
136 |
> > many ebuilds might fail after reordering ? How can this be |
137 |
> > improved ? |
138 |
> |
139 |
> Are you arguing for the sake of arguing here? I just presumed that |
140 |
> this example is so obviously broken there is no point wasting any |
141 |
> more time on it. The code of nsolve clearly detects that, so I don't |
142 |
> really understand what you're trying to prove here. |
143 |
|
144 |
Those are real questions. You should take breath, think a bit about |
145 |
it, and try to run the 2 possible orderings of the ^^ through nsolve or |
146 |
even solve.py. They both are very happy (and are right to be) with |
147 |
the above ordering. You might want to think a bit more about what is the |
148 |
relation between this broken 10 chars example and the 10 lines python |
149 |
targets one below. |
150 |
|
151 |
You should also realize that all the above questions have already been |
152 |
answered in length if you do as I suggest. |
153 |
|
154 |
[...] |
155 |
> > As for a real world example, I'll let you find some more interesting |
156 |
> > ones, but this one will probably be interesting to you and is a |
157 |
> > good start: |
158 |
> > |
159 |
> > app-text/wklej-0.2.1-r1 ^^ ( python_single_target_pypy |
160 |
> > python_single_target_pypy3 python_single_target_python2_7 |
161 |
> > python_single_target_python3_4 python_single_target_python3_5 |
162 |
> > python_single_target_python3_6 ) python_single_target_pypy? |
163 |
> > ( python_targets_pypy ) python_single_target_pypy3? |
164 |
> > ( python_targets_pypy3 ) python_single_target_python2_7? |
165 |
> > ( python_targets_python2_7 ) python_single_target_python3_4? |
166 |
> > ( python_targets_python3_4 ) python_single_target_python3_5? |
167 |
> > ( python_targets_python3_5 ) python_single_target_python3_6? |
168 |
> > ( python_targets_python3_6 ) vim? ( ^^ |
169 |
> > ( python_single_target_python2_7 ) ) |
170 |
> > |
171 |
> > |
172 |
> > Hint: It loops as written here. Reordering the ^^ in a proper way |
173 |
> > makes it solvable. Putting the 'vim? ( ... )' part first makes it |
174 |
> > solvable in one pass. |
175 |
> |
176 |
> And that's the exact case where I was considering the problem of |
177 |
> ebuild- eclass ordering. And yes, putting the 'vim?' first is an |
178 |
> acceptable solution here. What's the problem here? |
179 |
|
180 |
Forget about putting vim?() first, it just makes it require an extra |
181 |
pass in the best case and is not the real issue here. |
182 |
|
183 |
> Yes, without reordering you get more 'reliable' results. However, |
184 |
> AFAICS nsolve detects a problem in all of the cases: if py2.7 is |
185 |
> sorted first, it detects ordering issue; in all other cases, it |
186 |
> detects circular dep. Am I missing something? |
187 |
|
188 |
Again, where is the code to check those 'all other cases' ? |
189 |
This is a real question as you don't seem to get the combinatorial |
190 |
explosion that happens here. I fear that unless you experiment it first |
191 |
hands you'll still be doubting it. |
192 |
|
193 |
Also, it seems very wrong that PM will now happily toggle flags from USE |
194 |
but will completely fail if I configure it with "please prefer python3 |
195 |
over python2". |
196 |
|
197 |
Alexis. |