[Question]
  [
# A little genetics lesson
When you only have access to someone's visible traits or *phenotype*, a pedigree of their family history is often used to figure out the actual genetic information or, *genotype* of each family member. 
When dealing with [simple dominance](http://study.com/academy/lesson/simple-dominance-definition-lesson-quiz.html) as we will be, a simple pedigree chart will be enough to figure out the alleles, or the version of the genes that they have, of each person. In simple dominance a person with a dominant allele (denoted with a capital letter) will always have the trait that that version represents, no matter the other allele. It takes two recessive alleles (denoted with a lowercase letter) to have that version expressed. In other words the dominant allele always masks the recessive version of that gene. Here is an example of a pedigree chart:
![PEDIGREE CHART](https://i.stack.imgur.com/oe5b2.gif)
Each row here is a generation. Circles are female, males squares, horizontal lines are marriage, vertical lines children. Pretty simple. Black means recessive phenotype, white, dominant. Starting from the top, (assume the alleles are `A` and `a`), we know person 2 has `aa`, homozygous recessive because that is the only possible option for the recessive phenotype. Now even though person one could be either `Aa` or `AA` to be dominant phenotype, because he has a recessive child, he must be `Aa`, or heterozygous. You can do this for all the other people. In the event you don't have any information that enables you to figure out the second allele, it can be done like so: `A_`.
# Your Task
* You will receive a pedigree chart in the form of a list of generations like `[GenI, GenII, etc.]` in any sane format.
* Each generation will be a list of strings, each string representing a person.
* The people are made up of three parts - an ID, their phenotype, and their "connections".
* Their ID is a single printable ascii character that is unique in the entire tree other than `A` or `a`. (No, there won't be more than 95 people in the chart).
* Their phenotype is one of `A` or `a`, `A` being the dominant allele, and `a` being recessive.
* Their connections are a sequence of ID's of other people that they have connections with.
* A connection in the same generation is marriage, in different generations is child and parent.
* The connections are repeated on both sides (i.e. the husband has say he is a husband of wife, and wife says she is husband of wife).
* You have to figure out the genotypes of everyone as much as possible.
* Return the same list, except instead of people, put their genotypes in the same position.
* The genotype has to be outputted in order so `Aa` instead of `aA`.
* A little leeway on the input format is fine.
* This is code-golf so shortest answer in **bytes** wins.
# Examples
```
[["0A1234", "1a0234"], ["2A01", "3a01", "4A015678",
"5a4678"], ["6a45", "7A45","8A45"]] (The one above)   ->
[["Aa", "aa"], ["Aa", "aa", "Aa", "aa"], ["aa", "Aa", "Aa"]]
[["0A12", "1A02"], ["2A301", "3a2"]]    ->
[["A_", "A_"], ["A_", "aa"]]
```
# Bonus
* **-30 bytes** if you deal with [incomplete and co-dominance](http://www.hobart.k12.in.us/jkousen/Biology/inccodom.htm) also. On the detection of three phenotypes instead of two in the entire chart, apply incomplete/co dominance to your algorithm.
  
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 39 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
εNUε'aåi„aaë¯.øX<X>‚è˜y2£lSδåPài„Aaë„A_
```
Port of [my Java answer](https://codegolf.stackexchange.com/a/156874/52210).
[Try it online](https://tio.run/##yy9OTMpM/f//3Fa/0HNb1RMPL8181DAvMfHw6kPr9Q7viLCJsHvUMOvwitNzKo0OLc4JPrfl8NKAwwtAihyBikBU/P//0dFKBo6GRsYmSjpKhokGIEasTrSSkaOBIVDEOBFMmQB5pmbmFkCmaaIJiAFSY5ZoYgoUMXcEUxYgKjYWAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V@m5JlXUFpipaBkX6nDpeRfWgLjHVr5/9xWv9BzW9UTDy/NfNQwLzHx8OpD6w6t1zu8I8Imwu5Rw6zDK07PqTQ6tDgn@NyWw0sDDi8AKXMEKgNR8f9rgUDn0Db7/9HR0UoGjoZGxiZKOkqGiQYgRqxOtJKRo4EhUMQ4EUyZAHmmZuYWQKZpogmIAVJjlmhiChQxdwRTFiAqNlZHAWoiyDxHAyOoacZQ44D82FgA).
**Explanation:**
```
ε                     # Map over the rows of the (implicit) input-list:
 NU                   #  Store the outer-map index in variable `X`
   ε                  #  Map over the strings `y` of the current row:
    'aåi             '#   If the current string contains an "a":
        „aa           #    Push string "aa"
       ë              #   Else (it contains an "A" instead):
        ¯.ø           #    Surround the (implicit) input-list with two empty lists
                      #    (05AB1E has automatic wrap-around when indexing lists,
                      #     so this is to prevent that)
           X<X>‚      #    Push `X-1` and `X+1` and pair them together
                è     #    Index both into the list to get (potential) parent and child rows
                 ˜    #    Flatten it to a single list
        y             #    Push the current string we're mapping again
         2£           #    Only leave the first 2 characters (its id and the letter "A")
           l          #    Lowercase the "A" to "a"
            S         #    And convert it to a list of characters: [id, "A"]
             δå       #    Check in each string whether it contains the id and "A"
               P      #    Check for each whether it contained BOTH the id AND "A"
                ài    #    If a child/parent is found for which this is truthy:
                  „Aa #     Push string "Aa"
                 ë    #    Else:
                  „A_ #     Push string "A_"
                      # (after which the mapped result is output implicitly)
```
[Answer]
# Java 10, ~~356~~ ~~349~~ 340 bytes
```
a->{int i=0,j,k,f,z=a.length;var r=new String[z][];for(;i<z;i++)for(r[i]=new String[j=a[i].length];j-->0;)if(a[i][j].contains("a"))r[i][j]="aa";else{var t=".a.*"+a[i][j].charAt(0)+".*";for(f=k=0;i>0&&k<a[i-1].length;)f=a[i-1][k++].matches(t)?1:f;for(k=0;i+1<z&&k<a[i+1].length;)f=a[i+1][k++].matches(t)?1:f;r[i][j]=f>0?"Aa":"A_";}return r;}
```
[Try it online.](https://tio.run/##fVLbbqMwEH3vV1h@qMwClsmlreo4FR@wfem@IbSaEtMYiBMZJ1WD@PasTUiFVtqVEJ45njPHc6ngBHG1qS9FA22LfoLS3R1CSltpSigkevUuQm/WKP2R5VmOCjJxIODuvr9zv9aCVQV6RRoJdIF43bksSAkWVVEdldFZAG2k/rBbfgKDjNDy85b37HLxcm8IV6szV2EYeMdkKp9GVQIcMibJeRXHa8YDVRIPZ1VOi722roKWYMBBYK6owACYy6aVnde1AlOgP3D4TdqCSS1hQYgdPLyiFLVgXK3Z/X29cnFxclPlQSmuQFaHYU53YIutbIkNXpLnciAP1DBZnUdy@Dc5/Af59t5yzV5wCvgZp78x7420R6OR4f3F99p9h@N74zo9Nvy0Vxu0c2V/zwWC69CsbC2Z9M81ueswS5PZfIEjnADzRh91eJayxCFzGI6F85YPj0/OXMLCGz7mARZLhzymw/Hkj74fxv8/Ja@TstmoMh9lZjfqdHOGQoZMkwXz/ljO21dr5Y7uj5Ye3L1tNKnc@tKjVQ1NjYGvlm6kPPzaX/lE04IM/GDU6i9/AA)
**General explanation:**
1) Any `a` will always become `aa`
2a) If a child `A` has parents `aa` and `A`, it will become `Aa`  
2b) If a child `A` has parents `A` and `A`, it will become `A_`  
2c) (It is not possible for a child `A` to have parents `aa` and `aa`)
3a) If a parent `A` has at least one child `a`, it will become `Aa`  
3b) If a parent `A` only has children `A`, it will become `A_` 
**Code explanation:**
```
a->{                     // Method with 2D String array as both parameter and return-type
  int i=0,j,k,           //  Index-integers
      f,                 //  Flag-integer
      z=a.length;        //  Length-integer
  var r=new String[z][]; //  Result 2D String array
  for(;i<z;i++)          //  Loop over the rows:
    for(r[i]=new String[j=a[i].length];
                         //   Create the inner String-array of the result
        j-->0;)          //   Loop over the columns:
      if(a[i][j].contains("a"))
                         //    If the current node contains "a":
        r[i][j]="aa";    //     Set the result at this node to "aa"
      else{              //    Else(-if the current node contains "A" instead):
        var t=".a.*"+a[i][j].charAt(0)+".*";
                         //     Set a temp String to a regex to check relations and "a"
        for(f=k=0;       //     Set the flag to 0
            i>0&&        //     If the current node has parents:
            k<a[i-1].length;)
                         //      Loop over the row above:
          f=a[i-1][k++].matches(t)?
                         //       If a parent with "a" is found:
            1:f;         //        Set the flag to 1 (else: leave it unchanged)
        for(k=0;i+1<z&&  //     If the current node has children:
            k<a[i+1].length;) 
                         //      Loop over the row below:
          f=a[i+1][k++].matches(t)?
                         //       If child with "a" is found:
            1:f;         //        Set the flag to 1 (else: leave it unchanged)
        r[i][j]=f>0?     //     If the flag is 1:
                 "Aa"    //      Current node changes from "A" to "Aa"
                :        //     Else (flag is still 0):
                 "A_";}  //      Current node changes from "A" to "A_"
  return r;}             //  Return the result
```
]