Closed xionluhnis closed 2 years ago
miss
exampleknit + f1 A ;A has logical position f1+ miss + f2 A ;A's logical position set to f2+ xfer f2 b2 ;A should be kicked right (or not at all)
Why should A be kicked right vs left? or not at all?
Because the user reset the logical carrier position with miss + f2 A
-- they are explicitly saying to the backend "please treat carrier A
as if it just knit right on f2
". In other words, any operation after that miss
should act as if the carrier is parked at f2+
. The user presumably did this because they wanted to transfer over the floating yarn between f1
and the carrier. (This isn't a crazy thing to do: I have seen this done to hold the end of an inlay yarn that you couldn't actually knit or tuck with; and as a way of "catching" yarns that have floated a long distance soas to avoid "knitting in" when an inserting hook is not available.)
(Extra note: the reason the spec says (or not at all)
is that a backend might know the carrier stopping distances for its target machine and, therefore, realize that no further kick is needed to get A
far enough right. But the backend certainly must make sure the carrier is right of f2
because that's what the user asked it to do.)
I feel that the text / comment should be changed to reflect that the first miss scenario is an ambiguous one and may trigger something bad.
I don't see the ambiguity here. The user has clearly stated what they want the machine to do (xfer
over yarn trailing between carrier A
[to the right of f2
] and the loop on f1
).
If implementing a backend for a knitting machine where this operation is known to be error-prone, I suggest having the backend emit a warning to let the user know that what they asked for may not be a good idea.
This seems to be becoming a common understanding bug in the spec. I will consider updating the language to make it clear that miss
exists to:
(1) compensate for a non-optimal compiler (by hoisting carrier moves) and
(2) as an escape hatch for automatic kickbacks when you want yarn/needle "interference".
Added NOTE: This discussion assumes an inset-from-the-edge increase [xfer the rightmost few stitches right, then fill the hole], not making new stitches at the edge.
When
knit D N CS
ordrop N
happen, a carrier not inCS
but anchored atN+
orN-
effectively sees its anchor loop drop from the bed. ... why the motion rule should still apply to such carrier?
Because its anchor loop is still connected (perhaps via a chain of loops) to the bed. When the chain is short, following the successor stitch (the stitch knit through the anchor loop) is a good approximation. When the chain is long, there isn't any particularly good approximation so knitout gives the programmer an easy-to-think-about rule and the ability to "fix" the logical position with miss
if they know better.
While this has no impact during the decreases (step 3), it would effectively require kickbacks when increasing back to the right (step 4)
I don't think this is the case.
A correct knitout backend makes code that causes a knitting machine to act "as if" the instructions were executed as described by the spec. Yarn carriers are almost never at their logical positions (owing to stopping distances), but kickbacks only need to occur when this mis-match is "observable" -- when it changes the finished product. In this case, I suspect that since A
ends up parked to the right of fN
after step 1, and none of the knitting or decreases or increases (steps 2-3) do anything that reveal that A
isn't parked just to the right of the right edge of the fabric, the backend is under no obligation to move A
elsewhere.
I have not tested what any current backends do here, but I suspect that at least one of the ones I have written acts more cautiously and will, in fact, kick A
repeatedly on step 4. This could be considered a performance bug, and could be worked around with a miss
as you describe.
What are the advantages of currently applying the motion rule even to carriers whose anchor has dropped from the bed?
Imagine adding a step 3.5 which knits with some new carrier C
at f(N-k+2)
(as part of making some separate fabric to the right of the A
/B
panel). If the logical position of A
does not follow the motion rule, the backend will not know to kick A
left to get it out of the way of C
, potentially resulting in the yarn trailing from A
becoming trapped in this other fabric.
(will say more pending testing)
Your understanding of when a carrier is "in action" is correct for this discussion. I do want to point out one subtle quirk in case others read this thread. Carriers aren't "in action" after in
/inhook
, they are after the first use of the carrier subsequent to the "in":
in
indicates that the given carrier set should be brought into action from the yarn grippers when next used.
(Particularly, this is important so that all in action carriers have logical positions.)
The backends are doing the right thing here by inserting misses since A
's logical position means that it should remain in the center of the cloth as B
casts on new stitches to the right. This is a visualizer bug.
(Thanks for finding this visualizer bug!)
Thank you for the detailed comments!
I think it gave me a hint at what I was misinterpreting. Small examples are only a partial description of a full topology such that there can be many valid interpretations without the full picture.
Because the user reset the logical carrier position with miss + f2 A -- they are explicitly saying to the backend "please treat carrier A as if it just knit right on f2". In other words, any operation after that miss should act as if the carrier is parked at f2+. The user presumably did this because they wanted to transfer over the floating yarn between f1 and the carrier. (This isn't a crazy thing to do: I have seen this done to hold the end of an inlay yarn that you couldn't actually knit or tuck with; and as a way of "catching" yarns that have floated a long distance soas to avoid "knitting in" when an inserting hook is not available.)
Indeed, now that you mention inlay, this is a common practice. I was not expecting such base example to have such intent as it is very specific. The following one was more obvious to me so I wrongly assumed that the first one was showcasing a "wrong" example, when it was a valid portion of a potentially bigger setup that was not further described.
This discussion assumes an inset-from-the-edge increase [xfer the rightmost few stitches right, then fill the hole], not making new stitches at the edge.
Indeed, that was the design intent.
When the chain is short, following the successor stitch (the stitch knit through the anchor loop) is a good approximation. When the chain is long, there isn't any particularly good approximation so knitout gives the programmer an easy-to-think-about rule and the ability to "fix" the logical position with miss if they know better.
My thought here was that as the dropped anchors go down, the angle gets closer to the vertical so that the path of the yarn between the dropped anchor stitch and the yarn carrier intersects the active region of the bed closer and closer to the initial location of the carrier itself.
However, this presupposed that the carrier stays near the location of the last anchor before dropping, which is not the only option (and effectively not the one described by the current motion rule).
For some reason, it appeared as the more natural expectation to me since if I want to move a carrier, then I would actually expect to actively do so with knit/tuck/split actions. But the argument of connectedness by default is convincing. And if one doesn't want connectedness, then it makes sense to include a miss
that explicitly represents that disconnection by introducing a margin away from the piece.
Imagine adding a step 3.5 which knits with some new carrier C at f(N-k+2) (as part of making some separate fabric to the right of the A/B panel). If the logical position of A does not follow the motion rule, the backend will not know to kick A left to get it out of the way of C, potentially resulting in the yarn trailing from A becoming trapped in this other fabric.
This last example made me realize that the intent of where a carrier should be parked and stay is not always clear from the actions themselves (even assuming some limited look-ahead context).
The example with A
and B
I had in mind was intended to do color blocks / stripes: A
would have done an initial block, followed by some shaping with B
, before doing yet another stripe/block later with A
, while having the thread float on the side. But this is only one option and it could be more explicitly expressed by taking A
out
and then bringing it back in
(although that can be unideal in some scenarios such as with machines without insertion mechanism).
If we assume a single main connected component, then keeping A
next to the edge makes more sense than keeping A
floating on the side.
I think I see more clearly that there is no single correct behavior for the implicit kickbacks and it's mostly a matter of having one that works for many scenarios while being simple. In this setup, the purpose of the miss
action is as you wrote (1) to allow a low-level specification of the carrier motions when those of the compiler are not satisfying, and (2) to enable all "other" scenarios that are not implicitly represented by the chosen kickback behavior (although I would probably not label all of them as yarn / needle interferences).
Hi all,
I am trying to understand the ramifications of the motion rule for the implicit kickbacks. While the rule itself makes a lot of sense when an anchor stitch associated with a carrier is being moved across the beds, I am a little confused as to what should really be happening when carrier anchor loops drop from the bed.
Notion of active carrier
The introduction of the kickback section states:
Before discussing the motion rule, I wanted to verify my interpretation of the above statement. Notably, what refers to a carrier that is currently in action?
in
orinhook
) but has not yet been taken out (e.g. without
orouthook
)?My understanding is that it's the former (1) because carriers that are on the bed are physically in conflict with needle actuation, whether they have an anchored stitch on the bed or not. This seems to be confirmed, for example, by the implementation of
kickOthers
in the kniterate backend -- which triggers kicks for all the other carriers in conflict, unlesslast
needle (i.e., they have not knitted yet).The rest of the discussion assumes that my understanding is correct and an active carrier corresponds to (1).
Motion rule, current examples and
miss
The motion rule currently states:
The current first example for it showcases two active carriers X and Y, both of which have anchored stitches on the bed:
This scenario is unambiguous because X's loop from
knit + f3 X
is still on the bed, so we want to move its location to follow the loop.The second "basic example" showcases a need for kickback and is unambiguous:
However, the next
miss
example showcases an issue but is somewhat ambiguous as to what should happen:A priori, in that example, kicking right looks like a bad idea IMO because the carrier is at
f2+
, but the anchored loop is still atf1+
. In this setup, the transferxfer f2 b2
is likely going to interfere with the floating yarn betweenf1+
andf2+
. My impression is that neither suggestions (kick right or do nothing) is appropriate. Why shouldA
be kicked right vs left? or not at all?The reasonable option in this scenario is to effectively do what the follow-up
miss
example does:With the miss to the left, there is no conflict, so we are safe and what happens is clearly unambiguous.
Given the confusion, I feel that the text / comment should be changed to reflect that the first
miss
scenario is an ambiguous one and may trigger something bad. The sequence of examples makes it sound implicitly, but that example is confusing, so I feel that it deserves an explicit mention of its associated problem.Motion rule for past anchored stitches
I wonder whether there should not be an additional rule specific to
knit D N CS
anddrop N
to fix the location of a carrier that was active atN
but not part ofCS
. Whenknit D N CS
ordrop N
happen, a carrier not inCS
but anchored atN+
orN-
effectively sees its anchor loop drop from the bed.In this scenario, I am a bit confused as to why the motion rule should still apply to such carrier. Their anchor loop doesn't move with transfers or splits anymore. As a consequence, the connection between such carrier and its last loop doesn't follow the motions of loops on the bed, but only motions of the carrier due to kickbacks.
An example where this becomes odd to me is the following:
A
knits right (+) up tofN
B
knits right (+) up tofN
, effectively dropping the anchor ofA
f(N-k)
while knitting withB
fN
while knitting withB
With the motion rule still in action, the decrease transfers to the left effectively move the logical position of
A
toward the left. While this has no impact during the decreases (step 3), it would effectively require kickbacks when increasing back to the right (step 4), even though there is no potential conflict betweenB
increasing andA
that is located atfN+
while having a dropped anchor atfN+
.What do you think? Or am I misinterpreting something here?
In the above decrease-then-increase scenario, one solution from the current rules' perspective is to add
miss + f(N+1) A
before switching to carrierB
. This would effectively make the backend consider the carrierA
as separate from the decrease process withB
. But I was wondering if that was necessary at all if the motion rule was made more precise and only considered stitches moving carriers that are atN+
orN-
with a stitch anchored on the bed.What are the advantages of currently applying the motion rule even to carriers whose anchor has dropped from the bed?
Visualization vs backends
Attached are a base example that implements the decrease-increase problem of above, without and with additional
miss
at the end of step (1):While the knitout visualizer shows the same topology for both cases, the knitout backends introduce several kickbacks in the first case during the increase steps. Those kickbacks introduce a float of the first yarn to the left before the increases which appears to me like a conflict for the increase transfers.
What should I consider as wrong in this scenario: the knitout visualizer or the backends that implement the motion rule? Or is it that in this scenario the input without
miss
should be considered ambiguous? Or is it that those introduced floats are not considered a problem? Since the point of implicit kickbacks is to not have to worry about them, if the introduced floats can lead to issues, then this seems like a problem.