A General Framework for Semantics-based Bottom-up Abstract Interpretation of Logic Programs