Getting Parent Objects with Functions in Alloy - alloy

I am trying to learn alloy but i am having a hard time finding proper learning material.
So i am trying some models by myself and see if they works.
I wanted to find and return the clinics containing the given doctor with the function but it is not working. How can i do this without changing the Clinic and Doctor?
abstract sig Clinic {
doctors : set Doctor
}
abstract sig Doctor {}
fun getClinicsOfDoctor [ d : Doctor ] : set Clinic {
all c : Clinic | d in c.doctors
}

What material have you looked at? Try the Alloy book. Also see tutorials and papers on the Alloy website.
What's wrong with your model is that the body of your function is a formula. It should instead be an expression. Any of the following will work
doctors.d
d.~doctors
{c: Clinic | d in c.doctors}

Related

How do I see the returned value(s) of a function in Alloy?

I'm trying to understand how functions work in Alloy, and an important part of that is testing them. For example I've got this code:
open util/ordering[Time] // enforces total order on Time
sig Time {} // instances denote timestamps
sig File {
time : Time // every file has exactly one timestamp
}
fun getTime[F : set File] : Time {
{t : Time | some f : F | all x : F | f.time = t && gte[f.time,x.time]}
}
The getTime function is meant to return the time value of the file(s) with the greatest timestamp, out of the given set of files. I've made the function, and I believe it should work as intended, but I have no clue how to actually test that. I know I can run functions in Alloy, but I can't figure out how to create a sample set of files to use as input. Whenever I do manage to get something to run, nowhere in the resulting visualization does it show what the function outputted.
In the visualization, you can open the "Evaluator" with a button in the toolbar.
There you can enter stuff like:
univ
to get a list of all atoms. And:
getTime[File$0]
to evaluate a function.

Find all references to a supplied noun in StanfordNLP

I'm trying to parse some text to find all references to a particular item. So, for example, if my item was The Bridge on the River Kwai and I passed it this text, I'd like it to find all the instances I've put in bold.
The Bridge on the River Kwai is a 1957 British-American epic war film
directed by David Lean and starring William Holden, Jack Hawkins, Alec
Guinness, and Sessue Hayakawa. The film is a work of fiction, but
borrows the construction of the Burma Railway in 1942–1943 for its
historical setting. The movie was filmed in Ceylon (now Sri Lanka).
The bridge in the film was near Kitulgala.
So far my attempt has been to go through all the mentions attached to each CorefChain and loop through those hunting for my target string. If I find the target string, I add the whole CorefChain, as I think this means the other items in that CorefChain also refer to the same thing.
List<CorefChain> gotRefs = new ArrayList<CorefChain>();
String pQuery = "The Bridge on the River Kwai";
for (CorefChain cc : document.get(CorefCoreAnnotations.CorefChainAnnotation.class).values()) {
List<CorefChain.CorefMention> corefMentions = cc.getMentionsInTextualOrder();
boolean addedChain = false;
for (CorefChain.CorefMention cm : corefMentions) {
if ((!addedChain) &&
(pQuery.equals(cm.mentionSpan))) {
gotRefs.add(cc);
addedChain = true;
}
}
}
I then loop through this second list of CorefChains, re-retrieve the mentions for each chain and step through them. In that loop I show which sentences have a likely mention of my item in a sentence.
for (CorefChain gr : gotRefs) {
List<CorefChain.CorefMention> corefMentionsUsing = gr.getMentionsInTextualOrder();
for (CorefChain.CorefMention cm : corefMentionsUsing) {
//System.out.println("Got reference to " + cm.mentionSpan + " in sentence #" + cm.sentNum);
}
}
It finds some of my references, but not that many, and it produces a lot of false positives. As might be entirely apparently from reading this, I don't really know the first thing about NLP - am I going about this entirely the wrong way? Is there a StanfordNLP parser that will already do some of what I'm after? Should I be training a model in some way?
I think a problem with your example is that you are looking for references to a movie title, and there isn't support in Stanford CoreNLP for recognizing movie titles, book titles, etc...
If you look at this example:
"Joe bought a laptop. He is happy with it."
You will notice that it connects:
"Joe" -> "He"
and
"a laptop" -> "it"
Coreference is an active research area and even the best system can only really be expected to produce an F1 of around 60.0 on general text, meaning it will often make errors.

How to group "match" results

My question is "how to group the match results" of select-ed items ?
Here is the structure and data I have in my graph :
Structure :
5 kind of vertices : user / experience / school / company / tag
5 kind of edges : studied / worked /school / company / speaks
Data :
user --[worked]--> experience --[company]--> company
user --[worked]--> experience --[company]--> company
user --[stidued]--> experience --[school]--> school
user --[stidued]--> experience --[school]--> school
user --[speaks (level: x)]--> language
user --[speaks (level: x)]--> language
I already wrote something close to what I need with match, dedup and unfold
g.V(16520).match(
__.as('user'),
__.as('user').out('worked').as('workExperiences'),
__.as('user').out('studied').as('schoolExperiences'),
__.as('workExperiences').out('company').as('company'),
__.as('schoolExperiences').out('school').as('school'),
__.as('user').outE('speaks').as('a').values('level').as('level').select('a').inV().values('name').as('language').select('level', 'language').as('languages')
).select('user', 'schoolExperiences', 'school', 'workExperiences', 'company', 'languages')
.unfold().dedup()
Here is what this query gives me :
==>user=v[16520]
==>schoolExperiences=v[4184]
==>school=v[4232]
==>workExperiences=v[12496]
==>company=v[8320]
==>languages={level=6, language=DEU}
==>languages={level=3, language=FRA}
==>schoolExperiences=v[16424]
==>school=v[4136]
==>workExperiences=v[16512]
==>company=v[4176]
I need to find a query that return this kind of result :
==>user=[v[16520]]
==>languages=[{level=6, language=DEU},{level=3, language=FRA}]
==>workExperiences=[v[12496], v[16512]]
==>schoolExperiences=[v[4184], v[16424]]
==>company=[v[4176], v[8320]]
==>school=[v[4136], v[4232]]
I can't manage to find a solution.
Any advice would be appriciated :)
Thanks for reading
F.
PS : I'm running a v3.0.1-incubating Tinkerpop version
Thanks to #DanielKuppitz here is the solution I needed :
g.V(16520).as('user').match(
__.as('user').out('worked').as('experience').out('company').as('companyId').select('experience', 'companyId').fold().as('tmpWorkExperiences'),
__.as('user').out('studied').as('experience').out('school').as('schoolId').select('experience', 'schoolId').fold().as('tmpSchoolExperiences'),
__.as('user').outE('speaks').as('level').inV().as('language').select('level', 'language').by('level').by('name').fold().as('languages')
).select('tmpWorkExperiences').map(unfold().select('experience', 'companyId').by().by(id).fold()).as('workExperiences').
select('tmpWorkExperiences').map(unfold().select('companyId').fold()).as('company').
select('tmpSchoolExperiences').map(unfold().select('experience', 'schoolId').by().by(id).fold()).as('schoolExperiences').
select('tmpSchoolExperiences').map(unfold().select('schoolId').fold()).as('school').
select('workExperiences', 'schoolExperiences', 'company', 'school', 'languages').unfold()
And here is the result :
==>workExperiences=[{experience=v[12496], companyId=8320}, {experience=v[16512], companyId=4176}]
==>schoolExperiences=[{experience=v[4184], schoolId=4232}, {experience=v[16424], schoolId=4136}]
==>company=[v[8320], v[4176]]
==>school=[v[4232], v[4136]]
==>languages=[{level=6, language=DEU}, {level=3, language=FRA}]

Yii2 : Getting class name from relation attribute

I went through all API documentation of Yii 2.0 to find a way to reverse back to relation class name from a model attribute.
let us suppose that class Customer has a relation
$this->hasOne(Country::className(), ['id' => 'countryId']);
and in a controller function the parameter was the attribute "countryId". How is it possible to detect the class name for the related model
Get the name of the class by removing Id from the end of the variable and capitalize it. But I cannot image any situation where this would be a normal development practice. You can also define am array to make this translation for the model.
You can try to use http://php.net/manual/en/intro.reflection.php to get the names of all the functions and try to guess the name of the relation / model based on the name of the field. If you name your classes and relation fields in a proper name then you should be able to try to again guess the model.
This still feels like a hack, create a function that returns the name of the model based on the field... easiest solution. I know you try to be lazy but this is a hacky way of programming.
I'm not very clear on what data you have to start with here. If you only have a column countryId I am not sure. But say you have the relation name 'country' and the following code in your Customer model:
public function getCountry()
{
return $this->hasOne(Country::className(), ['id' => 'countryId']);
}
This is what I would do:
$relationName = 'country';
$customer = new Customer;
$relation = $customer->getRelation($relationName);
$relationModelClass = $relation->modelClass;
You could look at \yii\db\ActiveQuery::joinWithRelations() for how they do it.

Gorm find subset in HasMany

I have the following relation in which I want to search
class Order {
static hasMany = [articles:Article]
}
class Article {
}
In my search I select N articles and I want to find all Orders that contain all the N selected articles. So far I was only able to find all Orders that contain one of the selected Articles. It would be great if anyone can help me on this.
Order.executeQuery("select o from Order o join o.articles as a where a in (:articleList)", [articleList: articleList])

Resources