private TermType getCastTypeFromSubRule ( ImmutableTerm term , ImmutableList < Function > bodyDataAtoms , Map < Predicate , ImmutableList < TermType > > alreadyKnownCastTypes ) { if ( term instanceof Variable ) { Variable variable = ( Variable ) term ; for ( Function bodyDataAtom : bodyDataAtoms ) { List < Term > arguments = bodyDataAtom . getTerms ( ) ; for ( int i = 0 ; i < arguments . size ( ) ; i ++ ) { /** * Finds the position of the variable in the current body atom */ if ( arguments . get ( i ) . equals ( variable ) ) { // i is not final... final int index = i ; return Optional . ofNullable ( alreadyKnownCastTypes . get ( bodyDataAtom . getFunctionSymbol ( ) ) ) . map ( types -> types . get ( index ) ) . orElseThrow ( ( ) -> new IllegalStateException ( "No type could be inferred for " + term ) ) ; } } } throw new IllegalStateException ( "Unbounded variable: " + variable ) ; } else if ( term instanceof ImmutableExpression ) { ImmutableExpression expression = ( ImmutableExpression ) term ; ImmutableList < Optional < TermType > > argumentTypes = expression . getTerms ( ) . stream ( ) . map ( t -> getCastTypeFromSubRule ( t , bodyDataAtoms , alreadyKnownCastTypes ) ) . map ( Optional :: of ) . collect ( ImmutableCollectors . toList ( ) ) ; return expression . getOptionalTermType ( argumentTypes ) . orElseThrow ( ( ) -> new IllegalStateException ( "No type could be inferred for " + term ) ) ; } else if ( term instanceof Constant ) { return ( ( Constant ) term ) . getType ( ) ; } else if ( term instanceof ImmutableFunctionalTerm ) { Predicate functionSymbol = ( ( ImmutableFunctionalTerm ) term ) . getFunctionSymbol ( ) ; if ( functionSymbol instanceof DatatypePredicate ) return functionSymbol . getExpectedBaseType ( 0 ) ; } throw new IllegalStateException ( "Could not determine the type of " + term ) ; }
Extracts the cast type of one projected variable from the body atom that provides it .