Skip to content

Commit

Permalink
Merge pull request #2 from alyst/tuple_closure
Browse files Browse the repository at this point in the history
Allow tuples in ascendants()/descendants()
  • Loading branch information
maximsch2 authored May 11, 2017
2 parents 7c33e1e + aac461d commit 3960f66
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
17 changes: 11 additions & 6 deletions src/ontology.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ Base.length(ontology::Ontology) = length(ontology.terms)
parents(ontology::Ontology, term::Term, rel::Symbol = :is_a) = ontology[relationship(term, rel)]
children(ontology::Ontology, term::Term, rel::Symbol = :is_a) = ontology[rev_relationship(term, rel)]

# FIXME use const when 0.5 compatibility is dropped
typealias VecOrTuple{T} Union{Vector{T}, Tuple{Vararg{T}}}

# return the set of all nodes of the ontology DAG that could be visited from `term`
# node when traveling along `rel` edges using `rev` direction
function transitive_closure{T}(ontology::Ontology, term::Term, rels::Vector{Symbol}, rev::Type{Val{T}} = Val{false})
# node when traveling along `rels` edges using `rev` direction
function transitive_closure{T}(ontology::Ontology, term::Term,
rels::VecOrTuple{Symbol},
rev::Type{Val{T}} = Val{false})
# TODO: check if transitive & non-cyclical before doing so?
res = Set{TermId}()
frontier_ids = Set{TermId}((term.id,))
Expand All @@ -59,10 +64,10 @@ function transitive_closure{T}(ontology::Ontology, term::Term, rels::Vector{Symb
return res
end

descendants(ontology::Ontology, term::Term, rels::Vector{Symbol}) = ontology[transitive_closure(ontology, term, rels, Val{true})]
descendants(ontology::Ontology, term::Term, rel::Symbol = :is_a) = descendants(ontology, term, [rel])
ancestors(ontology::Ontology, term::Term, rels::Vector{Symbol}) = ontology[transitive_closure(ontology, term, rels, Val{false})]
ancestors(ontology::Ontology, term::Term, rel::Symbol = :is_a) = ancestors(ontology, term, [rel])
descendants(ontology::Ontology, term::Term, rels::VecOrTuple{Symbol}) = ontology[transitive_closure(ontology, term, rels, Val{true})]
descendants(ontology::Ontology, term::Term, rel::Symbol = :is_a) = descendants(ontology, term, (rel,))
ancestors(ontology::Ontology, term::Term, rels::VecOrTuple{Symbol}) = ontology[transitive_closure(ontology, term, rels, Val{false})]
ancestors(ontology::Ontology, term::Term, rel::Symbol = :is_a) = ancestors(ontology, term, (rel,))

function satisfies(ontology::Ontology, term1::Term, rel::Symbol, term2::Term)
(term1 == term2) && return true # TODO: should check if relationship is is_reflexive
Expand Down
9 changes: 7 additions & 2 deletions test/test_graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function test_isa(onto, term1, term2)
@test !is_a(onto, term2, term1)
end

@testset "is_a relationship tests" begin
@testset "relationship tests" begin
GO = OBOParse.load("$testdir/data/go_mini.obo", "GO")

term1 = gettermbyid(GO, 1)
Expand Down Expand Up @@ -32,9 +32,14 @@ end

@test ancestors(GO, term1) == [term2]
@test Set(ancestors(GO, term5)) == Set([term2, term4])
@test Set(ancestors(GO, term6, :part_of)) == Set([term5])
@test Set(ancestors(GO, term6, (:is_a, :part_of))) == Set([term2, term4, term5])
@test Set(ancestors(GO, term6, [:is_a, :part_of])) == Set([term2, term4, term5])

@test Set(descendants(GO, term2)) == Set([term1, term4, term5])
@test descendants(GO, term5) == []


@test Set(descendants(GO, term5, :part_of)) == Set([term6])
@test Set(descendants(GO, term2, (:is_a, :part_of))) == Set([term1, term4, term5, term6])
@test Set(descendants(GO, term2, [:is_a, :part_of])) == Set([term1, term4, term5, term6])
end

0 comments on commit 3960f66

Please sign in to comment.