Why is edges plural in the relay specification? - facebook-graph-api

Here is an example of a graphql query.
A person has multiple hats,
person{
hats{
color
}
}
Using the relay specification, https://relay.dev/graphql/connections.htm, this query becomes
person{
hats{
edges{
node { color }
cursor
}
...
}
}
The idea to have in mind is the person has many hats, and you can draw a tree (this is not quite right, see below)
(person)
|||
|---------------|------------|
| | |
(hat1) (hat 2) (hat 3)
The lines going from person to a hat is an edge.
I have 2 questions about this:
Why is node inside of edges? This doesn't make graphical sense.
Why is the edges name plural, instead of being just a singular edge? I can't imagine a single use case for this. Please give an example if you know one.
For instance, here is the 'correct' diagram of the relay specification
(person)
_________|||____________________
|||-------------|||------------|||
|||-------------|||------------|||
||| ||| |||
(hat1) (hat 2) (hat 3)
Note that there are many edges going from a person to a hat. This doesn't make sense to me

A
/|\
e f g
/ | \
B C D
Consider this tree with the four nodes A, B, C, and D as well as the edges e, f, and g.
A has connections with B, C, and D.
A and B are connected through the edge e.
A therefore has 3 edges (plural) but from every edge (coming from A) I only get to a single other node (singular).
GraphQL is inspired by thinking about the connection between entities in a data set as graphs. The entities form the nodes, while the relationships between them can be considered edges in the graph. On the edge, we would store information about the relationship of the two entities.
I - personally - would not put too much thought into this whole naming from Relay. It is just one way to do pagination that worked very well for Facebook. Facebook is a company that probably has interviews that tend to favor computer science grads.
Here is my interpretation of the "correct" diagram according to your example:
(person)
_________|||____________________
| | |
| | |
| | |
(hat1) (hat 2) (hat 3)

Related

Trouble Understanding Haskell Trees

I'm having a few issues with trees, I was trying to make a simplified Family tree (genealogy tree) where I start with only 1 person, let's say Grandpa Bob, I'll try my best drawing this:
BOB
|
/ \
SIMON RUDY
/ \ / \
ROBBIE MARTHA TOM ISABEL
So, Grandpa Bob had 2 kids with Grandma(which doesn't matter here), Simon and Rudy, then Simon and Rudy both had 2 kids each (only 1 parent matters again), note that this is not necessarily the tree I want to make but only an example which can be used by you guys to help me out. I want to have it as a data Family, then have a function that initiates the "root" which will be Grandpa Bob and then have another function that will let me add someone to the tree, as in add Simon descending from Bob.
So far this is what I have atm(I've tried other things and changed it all over):
module Geneaology where
data Family a = Root a [Family a] | Empty deriving (Show, Read)
main :: IO()
main = do
root :: String -> Family
root a = ((Root a) [Empty])
Now, this doesn't work at all and gives me a parse error:
t4.hs:9:10: parse error on input ‘=’
I've tried to fix this and change the code around looking for other ways, and saw other posts as well, but didn't make any progress...
I think I made myself clear, thanks in advance xD
You have a syntax error, you can create a function in the main with a let and a lambda, and then use it
data Family a = Root a [Family a] | Empty deriving (Show, Read)
main :: IO()
main = do
let root = (\a -> Root a [Empty])
print(root "Bob")
But you can also define functions outside the main and call them latter:
root :: String -> Family String
root a = Root a [Empty]
main :: IO()
main = do
print(root "Bob")

pyparsing using both OneOrMore and ZeroOrMore regardless of order

I am trying to get into pyparsing, I want to create what I think is a simple grammar for say a shopping basket. The following illustrates
basket=['metal basket','wicker basket','plastic basket']
fish=['haddock','plaice','dover sole']
meat=['beef','lamb','pork']
vegetable=['tomatoe','onion','cabbage','carrot']
fruit=['apple','mango','orange','strawberry']
So the rule for shopping is you must have
1 Shopping basket
1 or more vegetables
zero or more fruits
fish are optional
The resulting parser must enforce the list of requirements above. It should not matter what order the items are placed in the basket, i.e a list
of
metal basket
haddock
tomatoe
apple
cabbage
orange
is just as valid as
wicker basket
tomatoe
apple
orange
apple
The one that should fail however is
- lamb
- tomatoe
- apple
- wicker basket
- apple
Because the basket must always be first in the list. I am at a loss as to how to do this
I have tired:
basket + OneOrMore(vegetable) + ZeroOrMore(fruit) + StringEnd()
But doesn't seem to work. I'm using pyparsing on python 2.7 on Windows 7. Thanks
Each is the pyparsing class for specifying "all of these things, but in any order". Think of it as a special form of And. And in fact, the operator for Each is &.
You want to define various valid combinations of basket contents, after the basket is given first.
basket + (OneOrMore(vegetable) & ZeroOrMore(fruit) & ZeroOrMore(fish))
You can leave off the StringEnd() at the end - just specify parseAll=True in your call to parseString.
Alternatively, you could just put all the ingredients into a single clump like:
basket + ZeroOrMore(vegetable | fruit | fish)
and then put the validation into a parse action. I'm actually more in favor of this second approach than of using Each in the parser itself. For one thing, a parse action, implemented in Python code, can contain much more complex rules ("more vegetables than fruit", "at least as many vegetables as fish", "oysters only in months containing an 'R'", etc.). Also, I think these rules are more likely to change over time, and all such changes will be localized to the parse action, instead of forcing changes in the parser itself.

Prolog list not printing all the elements on console

I am using SWI-PROLOG version 6.6.6
I want to print all the attributes of a particular predicate type.
I have a predicate called law with arity 2.
Some of the facts are
law(borrow,'To borrow Money on the credit of the United States').
law(commerce,'To regulate Commerce with foreign Nations, and among the several States, and with the Indian Tribes').
law(unifomity,'To establish an uniform Rule of Naturalization, and uniform Laws on the subject of Bankruptcies throughout the United States').
law(money,'To coin Money, regulate the Value thereof, and of foreign Coin, and fix the Standard of Weights and Measures').
law(punishment,'To provide for the Punishment of counterfeiting the Securities and current Coin of the United States').
law(establishment,'To establish Post Offices and post Roads').
law(exclusiverights,'To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries').
law(court,'To constitute Tribunals inferior to the supreme Court').
etc.
Now I want to access a law by entering its type.
Such as,
power(X) :- law(X,Y), display('\nCongress has the power : '),display(Y).
powers(ALL) :- display('\nCongress has the powers : '), law(_,Y), display('\n'), display(Y).
This works perfectly. Now, I also want the user to know what all types of laws are there so that the user can enter it as a query to get the corresponding law.
ex power(money).
For this, I made a query to get all these keywords and add them to a list and display the list.
But the list that is finally printed is not complete.
powerList(L) :- findall(X,law(X,_), L).
I use this code to get the list.
But the output on the console is
L = [borrow, commerce, unifomity, money, punishment, establishment, exclusiverights, court, piracyfelony|...].
But, there are more law types even after piracyfelony and they are not getting printed to the console. How do I get them printed?
This is a feature of Prolog's toplevel loops that tries to keep the output short.
To find out how you might change it, ask which Prolog flags your Prolog supports that have a value being a list of at least two elements:
?- current_prolog_flag(F,Options), Options = [_,_|_].
F = debugger_print_options,
Options = [quoted(true), portray(true), max_depth(10), attributes(portray), spacing(next_argument)] ;
F = toplevel_print_options,
Options = [quoted(true), portray(true), max_depth(10), spacing(next_argument)] ;
F = argv,
Options = [swipl, '-f', none] ;
false.
Now modify it accordingly:
?- length(L,10).
L = [_G303, _G306, _G309, _G312, _G315, _G318, _G321, _G324, _G327|...].
?- set_prolog_flag(toplevel_print_options,[quoted(true), portray(true), max_depth(0), spacing(next_argument)]).
true.
?- length(L,10).
L = [_G303, _G306, _G309, _G312, _G315, _G318, _G321, _G324, _G327, _G330].
(In newer versions starting with SWI 7 there is another flag value, answer_write_options.)

Clingo: assert partial constraints

I am trying to implement a program in clingo that solves one of those classic riddles where you have a series of assertions of facts and constraints and you have to deduce other facts. Here goes the problem:
Five men of different nationalities live in five side-by-side houses, each of a different color; they all have different jobs, a different favourite animal and favourite beverages. We know that:
The English man lives in the red house.
The Spanish man's favourite animal is the dog.
The Japanese man is a painter.
The Italian man drinks tea.
The Norwegian man lives in the first house from the left. (number_norw = 1)
The person living in the green house drinks coffee.
The green house is immediately right of the white one. (number_green = number_white + 1)
The clerk loves cats.
The salesman lives in the yellow house.
Milk is the favourite drink in the center house. (number_milk = 3)
The Norwegian's house is adjacent to the blue one. (number_norw = number_blue ± 1)
The cook likes juice.
The man living in the house next to the doctor's loves foxes.
The man who loves horses lives next door to the salesman.
The assignment is to find out who likes zebras.
So I set forth asserting:
% Number (the number of the house, 1 being the leftmost of the block, 5 the rightmost)
number(1..5).
% Color
color(red;green;white;yellow;blue).
% Nationality
nationality(english;spanish;japanese;italian;norwegian).
% Animal
animal(dog;cat;fox;horse;zebra).
% Job
job(painter;clerk;salesman;cook;doctor).
% Beverage
beverage(tea;coffee;milk;juice;coke).
% House
house(X, C, N, A, J, B) :-
number(X),
color(C),
nationality(N),
animal(A),
job(J),
beverage(B).
Now I'm stuck on asserting the constraints; how do I go about coding assertions 1. through 14.? I just need to understand the proper syntax, so if someone could please set me on the right track with one or two examples I can figure out the rest.
Thanks.
N.B. Notice I could have inferred, from 5. and 11., that the second house is the blue one because 11. number_blue = number_norw ± 1, 5. number_norw = 1, and 0 is not in the range of possible numbers, but I don't want to manually add it to the constraints because I expect clingo to figure it out itself.
One way to add the constraint for the first assertation:
% 1. The English man lives in the red house.
% S: english --> red house <==> red house OR not english
% not S: not (red house OR not english) <==> not red house AND english
% ie. it is not so, that the english man doesn't live in the red house
:- not 1 { house(X, red, english, A, J, B) :
number(X) : animal(A) : job(J) : beverage(B) }.
and as another example the seventh assertation:
% 7. The green house is immediately right of the white one.
% (number_green = number_white + 1)
:- house(NG, green, _, _, _, _), house(NW, white, _, _, _, _), NG!=NW+1.
This will however lead to long solving times and large memory requirements (gigabytes), because the grounded program (output of gringo) is massive. You can see this with gringo -t yourcode.asp. This is because the "do not care" variables _ (and X, A, J, B in the constraint for the first assertation above). Each rule will be written in at least 5*5*5*5 ways.
M. Gebser adviced me that the predicates (relations) should be kept short. The problem with this encoding of the instance is that house/6 is so long. One way to combat this would be to encode it in the following style:
house(1..5).
elem(color, red;green;white;yellow;blue).
elem(nationality, english;spanish;japanese;italian;norwegian).
...
and start from there. Now the arity of elem is only 2. When the instance is defined this way, the program becomes simpler eg. the constraints for the assertations do not need aggregates (the 1{ ... }N syntax).
:- not chosen(H, nationality, english), chosen(H, color, red).
M. Gebser also suggested that the solver (clasp) might benefit form the rule being written in the other way too:
:- not chosen(H, nationality, english), chosen(H, color, red).
:- chosen(H, nationality, english), not chosen(H, color, red).
You also need some additional restrictions, like that two different elements of the same type shouldn't be mapped to one house.
For nicer output, you can make a relation that gives the output like house/6 did.
Note that I used gringo3 and clasp2, which are not the newest versions. If you have the new clingo, there might be modifications that are needed.

How do I combine COUNTIF with OR

In Google Spreadsheets, I need to use the COUNTIF function on a range with multiple criteria. So in the table below, I would need to have something like =COUNTIF(B:B,"Mammal"or"Bird") and return a value of 4.
A |B
-------------------
Animal | Type
-------------------
Dog | Mammal
Cat | Mammal
Lizard | Reptile
Snake | Reptile
Alligator | Reptile
Dove | Bird
Chicken | Bird
I've tried a lot of different approaches with no luck.
One option:
=COUNTIF(B:B; "Mammal") + COUNTIF(B:B; "Bird")
According to the documentation:
Notes
COUNTIF can only perform conditional counts with a single criterion.
To use multiple criteria, use COUNTIFS or the database functions
DCOUNT or DCOUNTA.
COUNTIFS: This function is only available in the new Google Sheets.
Example:
=DCOUNTA(B:B; 2; {"Type"; "Mammal"; "Bird"})
You can also use ArrayFormula around a SUM(COUNTIFS()) construct:
=ArrayFormula(SUM(COUNTIF(B:B,{"Mammal", "Bird"}))
Source: Google Docs Product Forum
you can use regex like this:
=ARRAYFORMULA(SUM(N(REGEXMATCH(B:B, "Mammal|Bird"))))
You can use QUERY which can be very powerful (and is generally easier to remember, particularly if you came from the DB world) :
QUERY(A:B;"SELECT COUNT(B) WHERE B='Mammal' OR B='Bird'";0)
(0 at the end is used to avoid including header rows if you have such in your range)
Documentation about the QUERY function here : https://support.google.com/docs/answer/3093343?hl=en