<commit_before>package it.unibz.inf.ontop.spec.mapping.transformer.impl;

/*
 * #%L
 * ontop-reformulation-core
 * %%
 * Copyright (C) 2009 - 2014 Free University of Bozen-Bolzano
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import it.unibz.inf.ontop.datalog.CQIE;
import it.unibz.inf.ontop.dbschema.*;
import it.unibz.inf.ontop.exception.OntopInternalBugException;
import it.unibz.inf.ontop.model.term.impl.FunctionalTermImpl;
import it.unibz.inf.ontop.model.term.functionsymbol.BNodePredicate;
import it.unibz.inf.ontop.model.term.functionsymbol.Predicate;
import it.unibz.inf.ontop.model.term.functionsymbol.URITemplatePredicate;
import it.unibz.inf.ontop.model.term.*;
import it.unibz.inf.ontop.model.type.TermType;
import it.unibz.inf.ontop.model.type.impl.TermTypeInferenceTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.IntStream;

import static it.unibz.inf.ontop.model.OntopModelSingletons.TERM_FACTORY;


public class MappingDataTypeCompletion {

    private final DBMetadata metadata;

    private static final Logger log = LoggerFactory.getLogger(MappingDataTypeCompletion.class);

    /**
     * Constructs a new mapping data type resolution.
     * If no datatype is defined, then we use database metadata for obtaining the table column definition as the
     * default data-type.
     * //TODO: rewrite in a Datalog-free fashion
     *
     * @param metadata The database metadata.
     */
    public MappingDataTypeCompletion(DBMetadata metadata) {
        this.metadata = metadata;
    }

    public void insertDataTyping(CQIE rule) {
        Function atom = rule.getHead();
        Predicate predicate = atom.getFunctionSymbol();
        if (predicate.getArity() == 2) { // we check both for data and object property
            Term term = atom.getTerm(1); // the second argument only
            Map<String, List<IndexedPosition>> termOccurenceIndex = createIndex(rule.getBody());
            // Infer variable datatypes
            insertVariableDataTyping(term, atom, 1, termOccurenceIndex);
            // Infer operation datatypes from variable datatypes
            insertOperationDatatyping(term, atom, 1);
        }
    }

    /**
     * This method wraps the variable that holds data property values with a data type predicate.
     * It will replace the variable with a new function symbol and update the rule atom.
     * However, if the users already defined the data-type in the mapping, this method simply accepts the function symbol.
     */
    private void insertVariableDataTyping(Term term, Function atom, int position,
                                          Map<String, List<IndexedPosition>> termOccurenceIndex) {
        Predicate predicate = atom.getFunctionSymbol();

        if (term instanceof Function) {
            Function function = (Function) term;
            Predicate functionSymbol = function.getFunctionSymbol();
            if (function.isDataTypeFunction() ||
                    (functionSymbol instanceof URITemplatePredicate)
                    || (functionSymbol instanceof BNodePredicate)) {
                // NO-OP for already assigned datatypes, or object properties, or bnodes
            }
            else if (function.isOperation()) {
                for (int i = 0; i < function.getArity(); i++) {
                    insertVariableDataTyping(function.getTerm(i), function, i, termOccurenceIndex);
                }
            } else {
                throw new IllegalArgumentException("Unsupported subtype of: " + Function.class.getSimpleName());
            }
        } else if (term instanceof Variable) {
            Variable variable = (Variable) term;
            Term newTerm;
            Predicate.COL_TYPE type = getDataType(termOccurenceIndex, variable);
            newTerm = TERM_FACTORY.getTypedTerm(variable, type);
            log.warn("Datatype "+type+" for the value " + variable + " of the property " + predicate + " has been " +
                    "inferred " +
                    "from the database");
            atom.setTerm(position, newTerm);
        } else if (term instanceof ValueConstant) {
            Term newTerm = TERM_FACTORY.getTypedTerm(term, ((ValueConstant) term).getType());
            atom.setTerm(position, newTerm);
        } else {<commit_msg>Datatype inference (from the DB schema) message moved from WARN to INFO.<commit_after>package it.unibz.inf.ontop.spec.mapping.transformer.impl;

/*
 * #%L
 * ontop-reformulation-core
 * %%
 * Copyright (C) 2009 - 2014 Free University of Bozen-Bolzano
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import it.unibz.inf.ontop.datalog.CQIE;
import it.unibz.inf.ontop.dbschema.*;
import it.unibz.inf.ontop.exception.OntopInternalBugException;
import it.unibz.inf.ontop.model.term.impl.FunctionalTermImpl;
import it.unibz.inf.ontop.model.term.functionsymbol.BNodePredicate;
import it.unibz.inf.ontop.model.term.functionsymbol.Predicate;
import it.unibz.inf.ontop.model.term.functionsymbol.URITemplatePredicate;
import it.unibz.inf.ontop.model.term.*;
import it.unibz.inf.ontop.model.type.TermType;
import it.unibz.inf.ontop.model.type.impl.TermTypeInferenceTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.IntStream;

import static it.unibz.inf.ontop.model.OntopModelSingletons.TERM_FACTORY;


public class MappingDataTypeCompletion {

    private final DBMetadata metadata;

    private static final Logger log = LoggerFactory.getLogger(MappingDataTypeCompletion.class);

    /**
     * Constructs a new mapping data type resolution.
     * If no datatype is defined, then we use database metadata for obtaining the table column definition as the
     * default data-type.
     * //TODO: rewrite in a Datalog-free fashion
     *
     * @param metadata The database metadata.
     */
    public MappingDataTypeCompletion(DBMetadata metadata) {
        this.metadata = metadata;
    }

    public void insertDataTyping(CQIE rule) {
        Function atom = rule.getHead();
        Predicate predicate = atom.getFunctionSymbol();
        if (predicate.getArity() == 2) { // we check both for data and object property
            Term term = atom.getTerm(1); // the second argument only
            Map<String, List<IndexedPosition>> termOccurenceIndex = createIndex(rule.getBody());
            // Infer variable datatypes
            insertVariableDataTyping(term, atom, 1, termOccurenceIndex);
            // Infer operation datatypes from variable datatypes
            insertOperationDatatyping(term, atom, 1);
        }
    }

    /**
     * This method wraps the variable that holds data property values with a data type predicate.
     * It will replace the variable with a new function symbol and update the rule atom.
     * However, if the users already defined the data-type in the mapping, this method simply accepts the function symbol.
     */
    private void insertVariableDataTyping(Term term, Function atom, int position,
                                          Map<String, List<IndexedPosition>> termOccurenceIndex) {
        Predicate predicate = atom.getFunctionSymbol();

        if (term instanceof Function) {
            Function function = (Function) term;
            Predicate functionSymbol = function.getFunctionSymbol();
            if (function.isDataTypeFunction() ||
                    (functionSymbol instanceof URITemplatePredicate)
                    || (functionSymbol instanceof BNodePredicate)) {
                // NO-OP for already assigned datatypes, or object properties, or bnodes
            }
            else if (function.isOperation()) {
                for (int i = 0; i < function.getArity(); i++) {
                    insertVariableDataTyping(function.getTerm(i), function, i, termOccurenceIndex);
                }
            } else {
                throw new IllegalArgumentException("Unsupported subtype of: " + Function.class.getSimpleName());
            }
        } else if (term instanceof Variable) {
            Variable variable = (Variable) term;
            Term newTerm;
            Predicate.COL_TYPE type = getDataType(termOccurenceIndex, variable);
            newTerm = TERM_FACTORY.getTypedTerm(variable, type);
            log.info("Datatype "+type+" for the value " + variable + " of the property " + predicate + " has been " +
                    "inferred " +
                    "from the database");
            atom.setTerm(position, newTerm);
        } else if (term instanceof ValueConstant) {
            Term newTerm = TERM_FACTORY.getTypedTerm(term, ((ValueConstant) term).getType());
            atom.setTerm(position, newTerm);
        } else {
{'fraction_non_alphanumeric': 0.08994167604624988, 'fraction_numerical': 0.0038882635833418604, 'mean_word_length': 2.746262935990801, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4675536', 'n_tokens_mistral': 2683, 'n_tokens_neox': 2622, 'n_words': 785}