DisjointSet in Inform 7 - inform7

A DisjointSet is a kind of Object.
A DisjointSet is a part of every DisjointSet.
Trying to start a DisjointSet Object in Inform 7, but even though I know it could cause a infinite loop, I want to do it anyway for the obvious reason that it is part of the algorithm.
Here is the error
You wrote 'A DisjointSet is a part of every DisjointSet' : but this
generalisation would be too dangerous, because it would lead to
infinite regress in the assembly process. Sometimes this happens if
you have set up matters with text like 'A container is in every
container.'.
I suppose it would be easier to do something like this in Inform 6, but I don't have any knowledge of it so I am trying to avoid it. But will accept help in Inform 6 too.
Edit following #jeroen-mostert advice:
Maybe I'm doing it wrong, but maybe some sample code might help.
A DisjointSet is a kind of Container.
A DisjointSet always contains a DisjointSet called the Parent.
The First Decl is a DisjointSet.
The Second Decl is a DisjointSet.
The Parent of the First Decl is the Second Decl. [This line doesn't work.]
The sentence 'The Parent of the First Decl is the Second Decl'
appears to say two things are the same - I am reading 'Parent of the
First Decl' and 'Second Decl' as two different things, and therefore
it makes no sense to say that one is the other: it would be like
saying that 'St Peter is St Paul'. It would be all right if the second
thing were the name of a kind, perhaps with properties: for instance
'Pearly Gates is a lighted room' says that something called Pearly
Gates exists and that it is a 'room', which is a kind I know about,
combined with a property called 'lighted' which I also know about.

I'll give two answers. First, the question you asked:
Linked lists in Inform 7
The problem is that contains and is a part of indicate physical concepts. When you use those words, Inform thinks you're talking about matter in the fictional universe, as if you said, "every bucket contains a bucket".
Instead, define your own property that has nothing to do with Inform's physical world model:
Every DisjointSet has a DisjointSet called the Parent.
With this change, your code works.
Now on to the question you didn't ask:
Relations in groups
If what you want is a bunch of sets of objects, where the sets are all disjoint, use an equivalence relation:
Friendship relates people to each other in groups.
This defines a relation called "friendship" that divides all animals into disjoint sets, such that an animal is friends with the other animals in that set, and not friends with any other animal.
Then you must teach Inform a bit of vocabulary:
The verb to be friends with means the friendship relation.
After that, the phrase "X is friends with Y" means that X and Y are in the same friendship set. You can say things like "Now the badger is friends with the giant squid" to update the sets.
See "Relations in groups" in the manual.

Related

Inform7: Working with properties of rooms

I'm very, very new to this language, and wrapping my head around "how to do things with stuff" is proving to be a very frustrating endeavor.
My goal here is to create a mechanic where certain rooms are dangerous, and become more dangerous the longer the player stays in them. If the player stays in a dangerous room for too long, a death scene is triggered.
I've got code that looks like this:
[The "danger rule"]
A room has a number called danger level. The danger level of a room is usually 0.
Definition: A room is dangerous if its danger level is 1 or more.
Definition: A room is deadly if its danger level is 9 or more.
Every turn (this is the increasing danger rule):
If the player is in a dangerous room:
Increase danger level by 1.
Every turn (this is the death by danger rule):
If the room is deadly:
do nothing.[Later...]
Every turn (this is the danger explanation rule):
say danger level.
[further down]
The Feeding Chamber is south of the dungeon."You enter a large, dimly lit room with straw on the floor, surrounded by various cages embedded in the wall.[line break]Blood spatters are all over the floor, and it looks as if there's been a fight recently". After going to the feeding chamber for the first time:
try looking;
say "It smells like grues around here. I would be careful if I were you..";
The Feeding Chamber has danger level 5.
I can't seem to figure out how to properly work with the "danger level of a room". The explanation rule I defined causes a runtime error when entering a dangerous room:
`*** Run-time problem P31: Attempt to use a property of the 'nothing' non-object: property danger level`
..And attempts to re-word the rule to something like the danger level of the room or the danger level of this room lead to perplexing compilation messages such as:
`In the sentence 'say the danger level of the room' , it looks as if you intend 'danger level of the room' to be a property, but 'a room' is not specific enough about who or what the owner is.`
What is the "right" way to reference properties of objects in this way?
The magic words here were "of the location". If we pretend that that this was another programming language for a moment, the way I was writing this was as if I was referring to a class "the room" rather than an instance of the class currently being referenced "the location".
The working rule is as follows:
Every turn while the player is in a dangerous room:
Increase danger level of the location by 1.
The trick is to give Inform enough information to know which particular thing you're referring to. The problematic sentence in the original question is perfectly valid english that a human could parse, but the computer needs a bit more help in determining what room we mean when we say "the room".

Chicken or egg in functions/actors processing WorldState

I have read the series "Purely Functional Retrogames"
http://prog21.dadgum.com/23.html
It discusses some interesting techniques to build a (semi-)pure game world update loop.
However, I have the following side remark, that I cannot seem to get my head around:
Suppose you have a system, where every enemy, and every player are separate actors, or separate pure functions.
Suppose they all get a "WorldState" as input, and output a New WorldState (or, if you're thinking in actor terms, send the new WorldState to the next actor, ending with for instance a "Game Render" actor).
Then, there's two ways to go with this:
Either you start with one actor, (f.i. the player), and feed him the "current world".
Then, you feed the new world, to the next enemy, and so on, until all actors have converted the worlds. Then, the last world is the new world you can feed to the render loop. (or, if you followed the above article, you end up with a list of events that have occurred in the world, which can be processed).
A second way, is to just give all actors the current WorldState at the same time. They generate any changes, which may conflict (for instance, two enemies and the player can take a coin in the same animation frame) -> it is up to the game system to solve these conflicts by processing the events. By processing all events, the Game actor creates the new world, to be used in the next update frame.
I have a feeling I'm just confronted with the exact same "race condition" problem I wished to avoid by using pure functions with immutable data.
Any advice here?
I didn't read the article, but with the coin example you are creating a kind of global variable: you give a copy of the world state to all actors and you suppose that each actor will evaluate the game, take decision and expect that their action will succeed, regardless of the last phase which is the conflict solving. I would not call this a race condition but rather a "blind condition", and yes, this will not work.
I imagine that you came to this solution in order to allow parallelism, not available in solution 1. In my opinion, the problem is about responsibility.
The coin must belong to an actor (a server acting as resource manager) as anything in the application. This actor is the only responsible to decide what will happen to the coin.
All requests (is there something to grab, grab it, drop something...) should be sent to this actor (one actor per cell, or per map, level or any split that make sense for the game).
The way you will manage it is then up to you: serve all requests in the receive order, buffer them until a synchro message comes and make a random decision or priority decision... In any case the server will be able to reply to all actors with success or failure without any risk of race condition since the server process is run (at least in erlang) on a single core and proceed one message at a time.
In addition to Pascal answer, you can solve parallelization by splitting (i assume huge map) to smaller chunks which depend on last state (or part of it, like an edge) of its neighbours. This allows you to distribute this game among many nodes.

Modeling an HTTP transition system in Alloy

I want to model an HTTP interaction, i.e. a sequence of HTTPRequest/HTTPResponse, and I am trying to model this as a transition system.
I defined an ordering on a class State by using:
open util/ordering[State]
where a State is simply a set of Messages:
sig State {
msgSet: set Message
}
Each pair of (HTTPRequest->HTTPResponse) and (HTTPResponse->HTTPRequest) is represented as a rule in my transition system.
The rules are expressed in Alloy as predicates that let one move from one state to another.
E.g., this is a rule generating an HTTPResponse after a particular HTTPRequest is received:
pred rsp1 [s, s': State] {
one msg: Request, msg':Response | (
// Preconditions (previous Request)
msg.method=get &&
msg.address.url=sample_com &&
// Postconditions (next Response)
msg'.status=OK_200 &&
// previous Request has to be in previous state
msg in s.msgSet &&
// Response generated is added to next state
s'.msgSet = s.msgSet + msg'
}
Unfortunately, the model created seems to be too complex: we have a dozen of rules (more complex than the one above but following the same pattern) and the execution is very slow.
EDIT: In particular, the CNF generation is extremely slow, while the solving takes a reasonable amount of time.
Do you have any suggestion on how to model a similar transition system?
Thank you very much!
This is a model with an impressive level of detail; thank you for sharing it!
None of the various forms of honestAction by itself takes more than two or three minutes to find an instance (or in some cases to fail to find any instance), except for rsp8, which takes quite a while by itself (it ran for fifteen minutes or so before I stopped it).
So the long CNF preparation times you are observing are apparently caused by either (a) just predicate rsp8 that's causing your time issues, or (b) the size of the disjunction in the honestAction predicate, or (c) both.
I suspect but have not proved that the time issue is caused by combinatorial explosion in the number of individuals required to populate a model and the number of constraints in the model.
My first instinct (it's not more than that) would be to cut back on the level of detail in the model, in particular the large number of singleton signatures which instantiate your abstract signatures. These seem (I could be wrong) to be present either for bookkeeping purposes (so you can identify which rule licenses the transition from one state to another), or because the modeler doesn't trust Alloy to generate concrete instances of signatures like UserName, Password, Code, etc.
As the model now is, it looks as if you're doing a lot of work to define all the individuals involved in a particular example, instead of defining constraints and letting Alloy do the work of finding examples. (Using Alloy to check the properties a particular concrete example can be useful, but there are other ways to do that.)
Since so many of the concrete signatures in the model are constrained to singleton cardinality, I don't actually know that defining them makes the task of finding models more complex; for all I know, it makes it simpler. But my instinct is to think that it would be more useful to know (as well as possibly easier for Alloy to establish) that state transitions have a particular property in general, no matter what hosts, users, and URIs are involved, than to know that property rsp1 applies in all the cases where the host is named examplecom and the address URI is example_url_https and whatnot.
I conjecture that reducing the number of individuals whose existence and properties are prescribed, and the constraints on which individuals can be involved in which state transitions, will reduce the CNF generation time.
If your long-term goal is to test long sequences of state transitions to test whether from a given starting point it's possible or impossible to arrive at a particular state (or kind of state), you may need to re-think the approach to enable shorter sequences of state transitions to do the job.
A second conjecture would involve less restructuring of the model. For reasons I don't think I understand fully, sometimes quantification with one seems to hurt rather than help performance, as in this example, where explicitly quantifying some variables with some instead of one turned out to make a problem tractable instead of intractable.
That question involves quantification in a predicate, not in the model overall, and the quantification with one wasn't intended in the first place, so it may not be relevant here. But we can test the effect of the one keyword on this model in a simple way: I commented out everything in honestAction except rsp8 and ran the predicate first != last in a scope of 8, once with most of the occurrences of one commented out and once with those keywords intact. With the one keywords commented out, the Analyser ran the problem in 24 seconds or so; with the one keywords in place, it ran for 500 seconds so far before I decided the point was made and terminated it.
So I'd try removing the keyword one from all of the signatures with instance-specific individuals, leaving it only on get, post, OK_200, etc., and appData. I would also try doing without the various subtypes of Key, SessionID, URL, Host, UserName, and Password, or at least constraining their cardinality in the run command.

Unable to understand sentence in the book of operating system

"The events depicted are artificial in that processes do not always experience them, but they illustrate various state transitions."
I am unable to understand the perfect meaning of this sentence. I assume this is because of I am not native English speaker or I don't have much experience about processes and their states. What the above sentence tries to convey? Is it saying that The process which is first time experiencing the state will consider it as artificial or some thing more. Kindly guide me so that I am able to clear what is the meaning of this sentence. Following is the some more information about the line. Following will help you to find the line in book if you want to read the other sentences with this sentences.
Name of the Book: "The Design of the UNIX operating system"
Author : "M.J.Bach"
Chapter : " 6 - The Structure of Processes"
Page number : "147"
Topic : "6.1 - Process states and transitions"
paragraph number : "2 from the beginning of the page"
Line number related to paragraph : "2 line in paragraph."
I don't have my copy of Bach handy at the moment, so I may be a bit off base on what I remember, but I think what it is trying to say is that it may help conceptually to think of a process going from state A to state B and then to state C, but a real-world OS may choose to go directly from A to C and just perform the steps for both transitions at once, because there may not be any real reason to actually have a state B and allow processes to live in that state.

What is a destructive update?

I see a lot of functional programming related topics mention destructive updates. I understand that it is something similar to mutation, so I understand the update part. But what is the destructive part? Or am I just over-thinking it?
You're probably overthinking it a bit. Mutability is all there is to it; the only thing being "destroyed" is the previous value of whatever you mutated.
Say you're using some sort of search tree to store values, and you want to insert a new one. After finding the location where the new values goes, you have two options:
With an immutable tree, you construct new nodes along the path from the new value's location up to the root. Subtrees not along the path are reused in the new tree, and if you still have a reference to the original tree's root you can use both, with the common subtrees shared between them. This economizes on space with no extra effort if you have lots of slightly-different copies floating around, and of course you have all the usual benefits of immutable data structures.
With a mutable tree, you attach the new value where it belongs and that's that; nothing else has to be changed. This is almost always faster, and economizes on memory allocation if you only ever have one copy around, but anything that had a reference to the "old" tree now has a reference to the new one. The original has been destroyed; it's gone forever. If you need to keep the original around, you have to go to the expense of creating an entirely new copy of the whole thing before changing it.
If "destruction" seems an unnecessarily harsh way to describe a simple in-place update, then you've probably not spent as much time as I have debugging code in order to figure out where on Earth some value is being changed behind your back.
The imperative programming languages allow variables to be redefined, e.g
x = 1
x = 2
So x first has the value 1 then, later, it has the value 2. The second operation is an destructive update, because x looses its initial definition as being equal to 1.
This is not how definition is handled in common mathematics. Once defined, a variable keeps its value.
The above, seen as system of equations, would allow to subtract the first from the second equation, which would give
x - x = 2 - 1 <=> 0 = 1
which is a false statement. It is assumed that once introduced, x is the same.
A familiar statement like
x = x + 1
would lead to the same conclusion.
The functional languages have the same use of variables, once they are defined it is not possible to reassign them. The above statement would turn into
x2 = x + 1
and we would have no for or while loop but rather recursion or some higher order function.

Resources