/*
related_spouses - a LifeLines program to identify related spouses
        by Jim Eggert (eggertj@atc.ll.mit.edu)
        Version 1,  31 March 1993 (first release)

This program identifies spouses with known common ancestors.  For each
marriage of related spouses, the spouses' names are printed, along
with the first common ancestor in each branch of the ancestry tree.

*/

proc main() {
    indiset(husb_ancestors)
    indiset(wife_ancestors)
    indiset(common_ancestors)
    list(lowest_common_ancestors)
    forfam(family,fnum) {
        if (hubby,husband(family)) {
            if (wifey,wife(family)) {
/* find common ancestors */
                indiset(oneset)
                addtoset(oneset,hubby,0)
                set(husb_ancestors,ancestorset(oneset))
                indiset(oneset)
                addtoset(oneset,wifey,0)
                set(wife_ancestors,ancestorset(oneset))
                set(common_ancestors,intersect(husb_ancestors,wife_ancestors))
/* find common ancestors of common ancestors */
                set(cnum,0)
                indiset(too_common_ancestors)
                forindiset(common_ancestors,cancestor,zero,cnum) {
                    indiset(oneset)
                    addtoset(oneset,cancestor,0)
                    set(too_common_ancestors,
                        union(too_common_ancestors,ancestorset(oneset)))
                }
/* find lowest common ancestors (common_ancestors - too_common_ancestors) */
                if (cnum) {
                    set(lca_length,0)
                    forindiset(common_ancestors,cancestor,zero,cnum) {
                        indiset(oneset)
                        addtoset(oneset,cancestor,0)
                        set(oneset,intersect(oneset,too_common_ancestors))
                        set(dnum,0)
                        forindiset(oneset,one,zero,dnum) { "" }
                        if (eq(dnum,0)) {
                            enqueue(lowest_common_ancestors,key(cancestor))
                            set(lca_length,add(lca_length,1))
                        }
                    }
/* print out lowest common ancestors */
                    key(family) " " key(hubby) " " name(hubby) " and "
                    key(wifey) " " name(wifey) "\n have " d(lca_length)
                    " lowest common ancestor"
                    if (gt(lca_length,1)) { "s" }
                    ":\n"
                    while(lca_key,dequeue(lowest_common_ancestors)) {
                        "  " lca_key " " name(indi(lca_key) ) "\n"
                    }
                }
            }
        }
    }
}
