Nested Ask referencing different breeds in Netlogo - nested

I'm trying to get one type of breed to evaluate all the agents in another breed, and choose which one it likes best based on its own preferences of the characteristics of the other breed.
lets say i have two breeds, men and women. the women have random values for characteristics (variables generated at birth), lets say some value 0 to 10 for intelligence and attractiveness. The men have preferences (also variables generated at birth) about how much they care about those characteristics. I'd like the men to choose which woman they prefer most using a utility function, and move to them.
my code looks something like this:
men own [ pref-int pref-att ]
women own [ int att utility ]
to choose-mate
ask men [
let pref-int [pref-int] of myself
let pref-att [pref-att] of myself
ask women [
let int [int] of myself
let att [att] of myself
set utiilty pref-int*int + pref-att*att
]
move to max-one-of women [ utilty ]
]
end
but netlogo doesn't seem to be able to access the variable values of women one I've referenced men with ask.
Any advice?

I see a couple problems:
One problem is that your local variables pref-int and pref-att have the same name has the men-own variables. Variables need unique names in general.
myself refers to the agent that is calling the current agent (it's probably the most confusingly named primitive in NetLogo). self refers to the current agent. It looks like you're using myself where you should be using self. However, [ some-variable ] of self is the same as some-variable, so you rarely use self. NetLogo automatically figures out who's variable you're referring to from the context.
You need spaces around the *s.
move to should be move-to.
So here are two ways to do what you're trying to do.
Using local variables:
to choose-mate
ask men [
let mans-pref-int pref-int
let mans-pref-att pref-att
ask women [
set utiilty mans-pref-int * int + mans-pref-att * att
]
move-to max-one-of women [ utilty ]
]
end
Using myself:
to choose-mate
ask men [
ask women [
set utiilty ([pref-int] of myself) * int + ([pref-att] of myself) * att
]
move-to max-one-of women [ utilty ]
]
end
I prefer the myself version, but it's a matter of taste.
Also, another observation. utility is changing with every man. Its not a global attribute of a particular woman, but rather something specific to each man. As such, I wouldn't recommend storing it as a woman-own variable. Instead you can do:
to choose-mate
ask men [
move-to max-one-of women [
([pref-int] of myself) * int + ([pref-att] of myself) * att
]
]
end

Related

sig literals in Alloy

How can I write out a literal for a sig in Alloy? Consider the example below.
sig Foo { a: Int }
fact { #Foo = 1 }
If I execute this, I get
| this/Foo | a |
|----------|---|
| Foo⁰ | 7 |
In the evaluator, I know I can get a reference to the Foo instance with Foo$0 but how can I write a literal that represents the same value?
I've tried {a: 7}, but this is not equal to Foo$0. This is intentionally a trivial example, but I'm debugging a more complex model and I need to be able to write out literals of sigs with multiple fields.
Ah, this is one of the well hidden secrets! :-) Clearly in your model you cannot refer to atoms since the model is defining all possible values of those atoms. However, quite often you need your hands on some atom to reason about it. That is, you want to be able to name some objects.
The best way to get 'constants' is to create a predicate you call from a run clause. In this predicate, you define names for atoms you want to discuss. You only have to make sure this predicate is true.
pred collision[ car1, car2 : Car, road : Road ] {
// here you can reason about car1 and car2
}
run collision for 10
Another way is to create a quantification whenever you need to have some named objects:
run {
some car1, car2 : Car, road : Road {
// here you can reason about car1 and car2 and road
}
} for 10
There was a recent discussion to add these kinds of instances to the language so that Kodkod could take advantage of them. (It would allow faster solving and it is extremely useful for test cases of your model.) However, during a discussion this solution I presented came forward and it does not require any new syntax.
try to put a limitation for 'Integer' in the 'run' command. I mean :
sig Foo {a : Int}
fact{ #Foo = 1}
pred show {}
run show for 1 Foo, 2 Int

Haskell: How to delete the same function and concatenate two lists

I am the beginner of haskell. I want to delete some same functions in the same list and concatenate the two list get together.
For example:
db1 = ["David","worksfor.isa", "IBM" ]
db2 = ["David","isa'.worksfor'", "IBM"]
db3 = ["Tom","worksfor.isa", "IBM" ]
the program can be known that "isa'.worksfor' and "worksfor.isa" is the same String. And then use "Concat" to get the new db: db1 =["David","worksfor.isa", "IBM" ] and the others: db3 = ["Tom","worksfor.isa", "IBM" ]
(map (\(a,b,c) -> concat (map(\(a',b',c') -> if ( a b == b' a') then [] else [(a,b ++ "." ++ b',c')])))) ??????
I want to "split the string, if there are ' characters, reverse it, then remove ' characters and check for equivalence"
This should be a comment, but it is far too long:
I assume you find it hard to express yourself in English. I can relate to that; I find it hard myself. However, beyond English there are two other ways to communicate here:
Using precise technical terms.
Using several, diverse examples. A single example will not suffice, and several examples which are too similar give little information.
As for option 1, you are using the wrong terminology. It is not easy for me to see how can a list with 3 items can be considered a database (as hinted by the names db1, db2). Perhaps you wanted to use a list of triples?
[ ("David","isa'.worksfor'", "IBM") ]
You are not specific about what exactly do you want to concatenate, but the term concatenation always refers to an operation that must be "additive", i.e. length(x ++ y) == length(x) ++ length(y). This does not seem to be the case in your question.
Do you want a union of two databases (lists of triples) up to equivalence?
You want the program to understand that
"isa'.worksfor'" and "worksfor.isa" are the same string
But they are not. They might be equivalent strings. You can generally do that using a map operation, like you tried, but you should note that the character ' is not an operation over strings. So a b == b' a' does nothing close to what you want - it calls the function a on the variable b, and compares this with calling the function b' over the variable a'. I can only assume you want something like "split the string, if there are ' characters, reverse it, then remove ' characters and check for equivalence" but this is completely a guesswork.
To conclude:
Please explain in detail what is the general problem you are trying to solve. Try to find the precise terms; it is difficult, but this way you can learn.
Please add different examples of input and output
Please try to explain what have you tried and where are you stuck
As a last tip, maybe you want to solve this problem in a more forgiving language than Haskell (such as JavaScript, Python, Ruby, etc.)

Thinking Functionally. Building a New Array in Haskell / Purescript

I'm new to functional programming, and I've decided to build an app in Purescript. I've hit my first hurdle, and I'm not sure how to think about this conceptually.
I'm not looking for code as much as a way to think functionally about this problem.
I have a list of data. Specifically, something like
[ {a :: String, b :: String, c :: String} ]
I would like to create a list of Html (which is a purescript-halogen type) by using the record provided (with a list of the above types).
So, I would have a function
buildElements :: forall p i. MyRecordObject -> Array (HTML p i)
Now, I think I'm going to need to give this function result type a Monad computational context (purescript Eff is like Haskell IO)
So something like:
buildElements :: forall p i. MyRecordObject -> Eff (Array (HTML p i))
My first idea was vaguely around creating a list with something like
take $ length xs $ repeat ARecordObject
and then map the record over that list, but I wasn't really sure how to translate that into code. It seemed wrong anyway, since my plan involved mutating the state of ARecordObject, which is a no-no.
So then I found this function:
forEach :: forall e a. Array a -> (a -> Eff e Unit) -> Eff Unit
which looks almost perfect! I get an array, I give it a function that somehow assigns the properties in the record to this new array...but no, wait...I'm thinking non-functionally again.
I'm really at a bit of a loss here. Basically, I want to create something like a list of <li></li> elements, where I assign properties to each item.
E.g
I'm provided a record with:
[ { id: "id1", name: "name1", class: "class1", content: "content1" }
, { id: "id2", name: "name2", class: "class2", content: "content2" } ]
And I would like a function foo that returns an array:
[ li [ id_ rec.id, name_ rec.name, class_ rec.class ] [ text rec.content ]
, li [ id_ rec.id, name_ rec.name, class_ rec.lass ] [ text rec.content ] ]
where rec is the name of the recordObject (and obviously the two arrays are not identical, but actually mapped over the initial record).
(the dot syntax is a purescript record syntax notation similar to standard getter/setter notation)
My first idea was vaguely around creating a list with something like
take $ length xs $ repeat ARecordObject
and then map the record over that list, but I wasn't really sure how
to translate that into code. It seemed wrong anyway, since my plan
involved mutating the state of ARecordObject, which is a no-no.
Functional programmers don't just avoid mutation because it's a no-no (indeed, many functional programs make careful use of a controlled dose of mutability) - we do it because it produces safer, simpler code.
To wit: You're thinking in what I call "alloc-init mode", wherein you create some sort of "empty" value and then go about calculating its properties. Forgive my vehemency, but that's a fundamentally broken programming model, left over from the days of manual memory management; code which uses it will never be safe and abstractions relying on it will forever be leaky. The idiom doesn't fit into any language that's higher-level than C, and yet, if I had a pound for every time I see code like this...
var foo = new Foo();
foo.Bar = new Bar();
foo.Bar.Baz = new Baz();
...I would be a rich man (na na na). The default should be to create objects after you know what they're going to look like:
var foo = new Foo(new Bar(new Baz()));
This is simpler - you're just calculating a value, rather than reaching into the memory referenced by a pointer to update its contents - and more importantly it's safer because the type-checker ensures that you haven't forgotten a property and it allows you to make Foo immutable. The cleanest imperative code is functional code - you should only be imperative where necessary for performance (or when the language forces your hand).
Anyway, rant over. The point is that you're making life harder for yourself than necessary by thinking imperatively. Just write a function that calculates a single <li> from a single object...
toLi :: MyRecord -> HTML
toLi x = li [ id_ x.id, name_ x.name, class_ x.class ] [ text x.content ]
... (note that I'm not somehow creating an "empty" li and then populating its values), and then map it over your input list.
toLis :: [MyRecord] -> [HTML]
toLis = map toLi
This is how I'd do it in JS, too, even though I'm not required to by the language. No side-effects, no mutation, no need for Eff - just simple, safe, purely functional code.

Equality in alloy

I've got an Alloy model which contains the following :
abstract sig person{}
one sig john,Steve extends person {Gender: man}
sig man{}
fact {
all name: person, Gender: man |
name.Gender = name.Gender => person =person}
How can I make equality between two signatures?
It's not clear from your question what you want to do, and from your sample Alloy code it looks as if you may be suffering from some confusions.
First, the model you show uses the name Gender in two different ways, which is not illegal in itself but seems to suggest some confusion. (It certainly confuses the willies out of this reader.)
In the declaration for the two singleton signatures john and Steve, Gender denotes two binary relations, one holding between the signature john and the signature man, the other holding between Steve and man. To say the same thing in symbolic form, Gender denotes (a) some subset of john -> man, and (b) some subset of Steve -> man.
In the anonymous fact, however, Gender denotes a variable of type man.
Your model will be easier to understand if you find a way to rename one or the other of these. Since variable names in a quantified expression are arbitrary, your fact will mean the same thing if you reformulate it as
fact { all P : person, M : man | P.M = P.M => person = person }
If that's not what you meant to say, then you may have meant to say something like
fact { all P : person, M : man |
P.Gender = P.Gender => person = person
}
Renaming the variable forces you to choose one meaning or the other. This is a good thing. (It is an unfortunate fact that neither formulation is actually satisfactory in Alloy. But let's deal with one problem at a time; getting rid of the double use of the name Gender is the first step.)
A second issue is that whichever formulation of the fact you meant, it almost certainly doesn't mean what you wanted it to mean. Ignoring the specifics of the model for a moment, your fact takes the form
fact { all V1 : sig1, V2 : sig2 |
Expression = Expression => sig1 = sig1
}
where Expression is either V1.V2 or V1.Relation, for some Relation defined in the model. There are several things wrong here:
V1.V2 is meaningless where V1 and V2 are both names of signatures or variables ranging over given signatures: the dot operator is meaningful only if one of its arguments is the name of a relation.
If any expression E is meaningful at all, then a Boolean expression of the form E = E (for example, person.Gender = person.Gender) is true regardless of what E means. Anything denoted by E is naturally going to be equal to itself. So the conditional might as well be written
1 = 1 => person = person
For the same reason, person = person will always be true, regardless of the model: for any model instance the set of persons in the instance will be identical to the set of persons in the instance. So the conditional will always be true, and the fact won't actually impose any constraint on instances of the model.
It's not clear how best to help you move forward. Perhaps one way to start would be to ask yourself which of the following statements you are trying to capture in your model.
There is a set of persons.
Some persons are males (have gender = 'man'). Others are not males.
John is a male individual.
Steve is a male individual.
John and Steve are distinct individuals.
If x and y are individuals with the same gender, then x and y are the same individual. I.e. no two individuals have the same gender.
Note that these statements cannot all be true at the same time. (If that's not obvious, you might do worse than try to figure out why. Alloy can be helpful in that effort.)
Good luck.

Have an object in one set or another, but not both?

This is homework and I'm having a lot of trouble with it. I am using Alloy to model a library. Here are the definitions of the objects:
sig Library {
patrons : set Person,
on_shelves : set Book,
}
sig Book {
authors : set Person,
loaned_to : set Person,
}
sig Person{}
Then we need to have to have a fact that states, every book is either on the shelf, or taken out by a patron. However, they cannot be in both places.
// Every book must either be loaned to a patron or
// on the shelves.
fact AllBooksLoanedOrOnShelves {}
I have tried this...
fact AllBooksLoanedOrOnShelves {
some b : Book {
one b.loaned_to =>
no (b & Library.on_shelves)
else
b in Library.on_shelves
}
}
But it's not working... the books always are on the shelves. want to say, "For every book, if it is not being loaned, it is on the shelf. Otherwise, it's out."
Corrections, examples, and hints are greatly appreciated.
If every book must be either on loan to someone or on the shelves, then (a) no book will be both on loan and on the shelves (assuming you mean that "or" as exclusive), so the intersection of the onloan set and the onshelf set will be empty, and (b) the set of books will be equal to the union of the onloan and onshelf sets.
The set of books on loan at any time is the domain of the loaned_to relation. The set of books on the shelf in a given library L is the value of L.onshelves; the set of books on the shelves in all known libraries is Library.onshelves.
So you might say
fact in_or_out_not_both {
no Library.onshelves & loaned_to.Person
}
fact all_books_in_or_out {
Book = Library.onshelves + loaned_to.Person
}
Or you might need to say slightly different things, depending on just what you mean. Note that these constraints don't say that a book on loan must be on loan to a single borrower.
Your fact is wrong. You want to say something for all books (not "some"). And that something is basically an XOR.
Here's one that works:
fact AllBooksLoanedOrOnShelves{
all b : Book|
(b in Library.on_shelves and no p:Person | p in b.loaned_to)
or
(not b in Library.on_shelves and one p:Person | p in b.loaned_to)
}
Ok correct me if I'm wrong, but I believe this is the fact you're after:
fact {
disj[Library.on_shelves, Person.~loaned_to]
}
And a little explanation. Library.on_shelves is the set of books on the right side of the on_shelves relation, i.e. all the books that are on the shelves. ~loaned_to is the reverse relation of type Person -> Book and Person.~loaned_to is the set of books loaned to any person.
The disj predicate declares that the two sets have no common atoms (disjoint sets).
I am not very familiar with Alloy.
But I think this or something similar would work.
Every book is either on the shelves or is loaned to a a patron.
fact AllBooksLoanedOrOnShelves {
all b: Book | b in Library.on_shelves || b.loaned_to in Library.patrons
}
This question is 6 years old now, but I'm learning Alloy, and I wanted to offer my take on a solution.
fact AllBooksLoanedOrOnShelves {
no (Library.on_shelves & loaned_to.Person)
}
This can be read as "the intersection of the set of books that are on shelves and the set of books that are loaned out, is empty".

Resources