[m-users.] inst question
zoltan.somogyi at runbox.com
Thu Jul 28 13:51:44 AEST 2022
2022-07-28 13:34 GMT+10:00 "M McDonough" <foolkingcrown at gmail.com>:
>> What I don't understand, is why is the instantiatedness of LinkParts in line
>> 35 "bound(link_parts(ground))" and not
> "bound(link_parts(bound(left(ground)))" ?
> You need to declare a mode which uses the inst you defined.
He did, because ...
> :- mode lpleft_in == lpleft >> lpleft.
> :- pred fsf2(link_parts::lpleft_in, io.io::di, io.io::uo) is det.
... the mode "in(lpleft)" in Volker's code expands to "lpleft >> lpleft".
> A pred that requires a certain input inst which works this
> way can be annoying to use, as to go from an `in` link_parts in this
> example you would need to write a disjunction and then destructure and
> construct a new link_parts with an either of left, there isn't an
> automatic way to do this without writing it out.
I think this "destructure and construct" is what Volker is missing.
The root cause of Volker's issue is the fact that the Mercury compiler
does not track aliases (which has been the topic more than once
on m-users). In this case, the code that Volker wrote
LinkParts = link_parts(left(_)),
is seen by the compiler as
LinkParts = link_parts(V1),
V1 = left(...),
(The compiler breaks down all unifications into primitive forms,
none of which contain more than one function symbol, before doing
any semantic checking on the program.)
After mode analysis processes V1 = left(...), the compiler obviously
knows that V1 is bound to left/1. But, by then the compiler has
already forgotten that V1 is an alias for the first argument of link_parts
in LinkParts, so it does not know that the success of the V1 = left(...)
unification affects the inst of LinkParts in any way. However, if you
construct a new version of LinkParts, called say LinkParts2, from V1,
the compiler *will* know that LinkPart2's first arg is bound to left.
More information about the users