1 |
On śro, 2017-06-14 at 11:06 +0200, Alexis Ballier wrote: |
2 |
> On Wed, 14 Jun 2017 00:13:42 +0200 |
3 |
> Michał Górny <mgorny@g.o> wrote: |
4 |
> |
5 |
> > On wto, 2017-06-13 at 12:27 +0200, Alexis Ballier wrote: |
6 |
> > > On Mon, 12 Jun 2017 21:17:16 +0200 |
7 |
> > > Michał Górny <mgorny@g.o> wrote: |
8 |
> > > |
9 |
> > > > I've actually started typing the initial specification yesterday |
10 |
> > > > [1]. As you can see, banning the extra constraints has made the |
11 |
> > > > algorithms much simpler. In particular: |
12 |
> > > > |
13 |
> > > > 1. You do not have to define 'falsify' for anything other than |
14 |
> > > > pure flags -- which makes it easy to inline it. |
15 |
> > > > |
16 |
> > > > 2. ||, ??, ^^ groups are only flat lists of flags -- which makes |
17 |
> > > > reordering and processing them trivial. |
18 |
> > > > |
19 |
> > > > 3. The algorithm is recursive only on USE-conditional groups. This |
20 |
> > > > makes it trivial to make it iterative. Optimizations become |
21 |
> > > > trivially possible. |
22 |
> > > |
23 |
> > > |
24 |
> > > While you're right in one sense, you're mixing two different things |
25 |
> > > here. What you wrote *is* recursive. It does not recurse just |
26 |
> > > because you're assuming a restricted syntax. You're only saving two |
27 |
> > > things: you don't need to define how to enforce to false (that is 3 |
28 |
> > > lines not 3 pages :=) ) and you're avoiding the nested use |
29 |
> > > conditionals that are already ill defined per the current spec |
30 |
> > > (foo? bar is equivalent to && ( foo bar ) when nested) which I |
31 |
> > > believe is already another problem. |
32 |
> > > |
33 |
> > > Then, remember how I wanted to be much more drastic than you in the |
34 |
> > > beginning by killing all ||,&&,^^ etc. and keep only use |
35 |
> > > conditionals in REQUIRED_USE ? Well, that's where the complexity |
36 |
> > > comes. The whole deal then is to define rewriting rules for the AST |
37 |
> > > so that the algorithm you describe executes the exact same |
38 |
> > > instructions but the new AST only has use conditionals. This is |
39 |
> > > more like writing a compiler for the spec, so this does not belong |
40 |
> > > to the spec and there is no issue here. |
41 |
> > |
42 |
> > I'm looking for a compromise here. Killing those groups completely is |
43 |
> > going to make things harder for users. Keeping them with functionality |
44 |
> > limited to what's used in ~99.9% ebuilds (based on your numbers) is |
45 |
> > IMO a better choice. |
46 |
> |
47 |
> I already said I see the limited syntax as a good thing because it |
48 |
> forces devs to write constraints that have a natural interpretation in |
49 |
> how it is solved. However, you can't limit the syntax without a new |
50 |
> EAPI, and more importantly, properly solving does not even require |
51 |
> limiting the syntax. |
52 |
|
53 |
Actually, you can, via a Gentoo policy. Since solving is not required by |
54 |
the PMS, there is no rule saying it has to work for every constraint |
55 |
allowed by the PMS. |
56 |
|
57 |
Much like, you can't force a particular ordering or forbid circular |
58 |
constraints without a new EAPI. Yet you do it because it gives |
59 |
a practical improvement. |
60 |
|
61 |
> BTW, I don't know how you get that info from my data because I never |
62 |
> voluntarily checked for a restricted syntax :) |
63 |
|
64 |
I took the totals from your data, and subtracted the counts for invalid |
65 |
constraints from mine ;-). |
66 |
|
67 |
> |
68 |
> > > [BTW: checking the rewrite rules behave properly is what I meant by |
69 |
> > > rebasing solve() on top of it and being happy with it] |
70 |
> > |
71 |
> > Could you reiterate the current solving rules (trueify/falsify)? Are |
72 |
> > they equal to the ones you listed last, or does the current |
73 |
> > implementation change anything? |
74 |
> |
75 |
> Let's recap a bit. nsolve() is poorly named and does not solve |
76 |
> anything. It translates to implications and checks whether the |
77 |
> implications solver will always provide a valid result in one pass. |
78 |
> So, if you only care about solving rules, read your spec man. For the |
79 |
> more general case it should behave like those trueify/falsify with |
80 |
> the change that nested implications are interpreted as && (so no |
81 |
> more !(a -> b) crap to worry about). |
82 |
|
83 |
How are && ( a b... ) falsified now? Leftmost only? |
84 |
|
85 |
> If you take solve() as an implementation of your spec, you have: |
86 |
> solve(x) <=> solve(to_impl.convert_to_implications(x)) when solve(x) |
87 |
> is defined; with the added benefit that |
88 |
> 'solve(to_impl.convert_to_implications(x))' is defined and should |
89 |
> provide proper results on the whole REQUIRED_USE syntax as currently |
90 |
> defined (granted that nsolve(x) does not report anything wrong). |
91 |
|
92 |
The point is, solve() is supposed to work without any additional |
93 |
transformations. So the rules need to be consistent. As a matter of |
94 |
fact, I want to add a little extra test to solve.py that verifies that |
95 |
the result without and with transformation is the same. |
96 |
|
97 |
> > > > [1]:https://wiki.gentoo.org/wiki/User:MGorny/GLEP:ReqUse |
98 |
> > > |
99 |
> > > I really don't like the reordering thing. Even the restricted |
100 |
> > > syntax does not fix the issue with '^^ ( a b ) b? ( a )' already |
101 |
> > > mentioned here. It'd be much better and simpler for the spec just to |
102 |
> > > assign a fixed value and use the solving rules with those. |
103 |
> > |
104 |
> > You're not going to convince me by providing examples that are utterly |
105 |
> > broken by design and meaningless ;-). |
106 |
> |
107 |
> Well... if it's so obvious that the example is broken by design that |
108 |
> you don't even bother to explain why, I assume you have an algorithm for |
109 |
> that. Where is the code ? What are the numbers ? How many ebuilds might |
110 |
> fail after reordering ? How can this be improved ? |
111 |
|
112 |
Are you arguing for the sake of arguing here? I just presumed that this |
113 |
example is so obviously broken there is no point wasting any more time |
114 |
on it. The code of nsolve clearly detects that, so I don't really |
115 |
understand what you're trying to prove here. |
116 |
|
117 |
> Extra question: Is there *really* a point in pushing user preferences |
118 |
> that way, esp. when developers can write '!b? ( a )' instead of '|| ( a |
119 |
> b )' and just kill any possibility of changing the order ? |
120 |
|
121 |
Yes, that is by design. If you use ||, ^^, ?? you do not explicitly |
122 |
enforce a particular order -- you give the user a choice. I know it |
123 |
ain't perfect but it's a simple enough solution to a few problems. |
124 |
|
125 |
> As for a real world example, I'll let you find some more interesting |
126 |
> ones, but this one will probably be interesting to you and is a |
127 |
> good start: |
128 |
> |
129 |
> app-text/wklej-0.2.1-r1 ^^ ( python_single_target_pypy |
130 |
> python_single_target_pypy3 python_single_target_python2_7 |
131 |
> python_single_target_python3_4 python_single_target_python3_5 |
132 |
> python_single_target_python3_6 ) python_single_target_pypy? |
133 |
> ( python_targets_pypy ) python_single_target_pypy3? |
134 |
> ( python_targets_pypy3 ) python_single_target_python2_7? |
135 |
> ( python_targets_python2_7 ) python_single_target_python3_4? |
136 |
> ( python_targets_python3_4 ) python_single_target_python3_5? |
137 |
> ( python_targets_python3_5 ) python_single_target_python3_6? |
138 |
> ( python_targets_python3_6 ) vim? ( ^^ ( python_single_target_python2_7 |
139 |
> ) ) |
140 |
> |
141 |
> |
142 |
> Hint: It loops as written here. Reordering the ^^ in a proper way makes |
143 |
> it solvable. Putting the 'vim? ( ... )' part first makes it solvable in |
144 |
> one pass. |
145 |
|
146 |
And that's the exact case where I was considering the problem of ebuild- |
147 |
eclass ordering. And yes, putting the 'vim?' first is an acceptable |
148 |
solution here. What's the problem here? |
149 |
|
150 |
Yes, without reordering you get more 'reliable' results. However, AFAICS |
151 |
nsolve detects a problem in all of the cases: if py2.7 is sorted first, |
152 |
it detects ordering issue; in all other cases, it detects circular dep. |
153 |
Am I missing something? |
154 |
|
155 |
-- |
156 |
Best regards, |
157 |
Michał Górny |