code: public Optional<ImmutableSubstitution<ImmutableTerm>> computeUnidirectionalSubstitution(ImmutableTerm sourceTerm,
                                                                                                     ImmutableTerm targetTerm) {
          /*
           * Variable
           */
          if (sourceTerm instanceof Variable) {
              Variable sourceVariable = (Variable) sourceTerm;
  
              // Constraint
              if ((!sourceVariable.equals(targetTerm))
                      && (targetTerm instanceof ImmutableFunctionalTerm)
                      && ((ImmutableFunctionalTerm)targetTerm).getVariables().contains(sourceVariable)) {
                  return Optional.empty();
              }
  
              ImmutableSubstitution<ImmutableTerm> substitution = substitutionFactory.getSubstitution(
                      ImmutableMap.of(sourceVariable, targetTerm));
              return Optional.of(substitution);
          }
          /*
           * Functional term
           */
          else if (sourceTerm instanceof ImmutableFunctionalTerm) {
              if (targetTerm instanceof ImmutableFunctionalTerm) {
                  return computeUnidirectionalSubstitutionOfFunctionalTerms((ImmutableFunctionalTerm) sourceTerm,
                          (ImmutableFunctionalTerm) targetTerm);
              }
              else {
                  return Optional.empty();
              }
          }
          /*
           * Constant
           */
          else if(sourceTerm.equals(targetTerm)) {
              return Optional.of(substitutionFactory.getSubstitution());
          }
          else {
              return Optional.empty();
          }
      }
docs: Returns a substitution theta (if it exists) such as :
  theta(s) = t
  
  with
  s : source term
  t: target term