Closed izgzhen closed 5 years ago
I don't think this is a bug in Cozy. Instead, I think this specification is not the one you intended. You have a votes
member that is never read. The query selectStoryVotes
reads s.val.votes
, which is a different collection that never changes.
I have added a note to #23 that Cozy should warn you about unused abstract state variables.
I've made this PR example-only
The specification still has the unused votes
member. Is that really what you intended?
I don't think this is a bug in Cozy. Instead, I think this specification is not the one you intended. You have a votes member that is never read. The query selectStoryVotes reads s.val.votes, which is a different collection that never changes. The specification still has the unused votes member. Is that really what you intended?
In reflection, there is a problem that I don't understand -- I uses assume all [ v in votes | v <- s.val.votes ];
in insertStory
, which means at least after inserting, s
should depend on votes
. Accordingly, state stories
should depend on votes
, thus it seems buggy to me that votes is considered not used by Cozy.
or put it another way, I don't know how to enforce the fact that votes
in stories
are aliases of votes
in the spec states, by writing the spec in a particular way
Collections in Cozy are value types, not references like they are in Java. To make them references you would need to wrap them in a handletype BagRef = Bag<Vote>
and then use BagRef
in many places.
Collections in Cozy are value types, not references like they are in Java. To make them references you would need to wrap them in a handletype BagRef = Bag
and then use BagRef in many places.
But Vote
is already a reference type, isn't it? I don't need reference to this collection, instead, this collection holds references through which I can modify other values. Do I understand correctly?
I see. The individual Vote objects may alias, not the collections that contain them.
The ==
operator on handle types checks reference equality, like it does in Java. You should be able to express your requirement along the lines of "for all stories, every vote in its votes bag is also in the central votes collection" or something.
The == operator on handle types checks reference equality, like it does in Java. You should be able to express your requirement along the lines of "for all stories, every vote in its votes bag is also in the central votes collection" or something.
What do you mean? Do you mean that I should add an invariant?
Yes, I meant that you should add an invariant. However, I see now that you already have the invariant all [ v in votes | s <- stories, v <- s.val.votes ]
. So, disregard what I was saying.
Is it clear why insertVote
does not affect s.val.votes
for any story s
? If not, we might need to provide clearer documentation about how Cozy understands the effect of statements like votes.add(v)
.
The statement votes.add(v)
does not affect v
, nor does it affect any object that references v
. It only affects the votes
collection, inserting the pointer value v
. The invariant you wrote down says "every story's votes are a subset of votes
." That invariant is trivially preserved by votes.add(v)
, which expands the votes
collection but leaves every story's votes unchanged.
I see that you added the invariant I suggested (although GitHub declined to notify me). I am merging this now; thanks for adding this example!
the interesting thing is that:
votes
is optimized away by cozy -- I suspect that might be a bug.