The relationship/lookup type fields are two-way streets. Defined on the child object, they typically have a name from child to parent (e.g. Attachment.ParentId), and from parent to child (e.g. Attachments). Most standard relationships will follow the naming convention of pluralizing the child object name as the relationship name when querying from the parent.
There are a few standard lookup fields that have no relationship name (and thus cannot be queried as a sub-query), and a precious few actually don't use the pluralized form of the child object's name as the relationship name. I don't remember any examples off the top of my head, but I know they exist, as I've run across them before.
It's important to note that you're not querying against all versions of the that object, but only one specific field in the child object. There aren't many examples of this distinction in the standard API, since most child objects only have one lookup field to a particular type of parent, but you can observe this effect with custom relationships.
For example, let's say you create two custom lookup fields on Contact, one called "Mother" and one called "Father."
You'd now have two custom relationships. In order to get all of the contact records that call a specific parent record Mother or Father, you'd have to query both relationships to get all of the children, which would look like this:
Contact[] people = [SELECT (SELECT Name FROM MothersChildren__r),
(SELECT Name FROM FathersChildren__r)
FROM Contact];
This example should hopefully make it more obvious: we're getting two lists of contacts for each parent contact record, one where the Mother field points to that contact record, and one where the Father field points to that contact record.
Note that, because these are custom relationships, we can call them whatever we want (I simply chose MothersChildren and FathersChildren for illustrative purposes), and being custom, they always end in "__r", just has how custom field and object names end in "__c".