def mzn2fzn(
    mzn, *dzn_files, args=None, data=None, include=None, stdlib_dir=None,
    globals_dir=None, declare_enums=True, allow_multiple_assignments=False,
    keep=False, output_vars=None, output_base=None, output_mode='item',
    no_ozn=False
):
    """Flatten a MiniZinc model into a FlatZinc one.

    This function is equivalent to the command ``minizinc --compile``.

    Parameters
    ----------
    mzn : str
        The minizinc model. This can be either the path to the ``.mzn`` file or
        the content of the model itself.
    *dzn_files
        A list of paths to dzn files to attach to the minizinc execution,
        provided as positional arguments; by default no data file is attached.
    args : dict
        Arguments for the template engine.
    data : dict
        Additional data as a dictionary of variables assignments to supply to
        the minizinc executable. The dictionary is automatically converted to
        dzn format by the ``pymzn.dict2dzn`` function.
    include : str or list
        One or more additional paths to search for included ``.mzn`` files.
    stdlib_dir : str
        The path to the MiniZinc standard library. Provide it only if it is
        different from the default one.
    globals_dir : str
        The path to the MiniZinc globals directory. Provide it only if it is
        different from the default one.
    declare_enums : bool
        Whether to declare enum types when converting inline data into dzn
        format. If the enum types are declared elsewhere this option should be
        False. Default is ``True``.
    allow_multiple_assignments : bool
        Whether to allow multiple assignments of variables. Sometimes is
        convenient to simply let the data file override the value already
        assigned in the minizinc file. Default is ``False``.
    keep : bool
        Whether to keep the generated ``.mzn``, ``.dzn``, ``.fzn`` and ``.ozn``
        files or not. If False, the generated files are created as temporary
        files which will be deleted right after the problem is solved. Though
        files generated by PyMzn are not intended to be kept, this property can
        be used for debugging purpose. Note that in case of error the files are
        not deleted even if this parameter is ``False``. Default is ``False``.
    output_vars : list of str
        A list of output variables. These variables will be the ones included in
        the output dictionary. Only available if ``ouptut_mode='dict'``.
    output_base : str
        Output directory for the files generated by PyMzn. The default
        (``None``) is the temporary directory of your OS (if ``keep=False``) or
        the current working directory (if ``keep=True``).
    output_mode : {'dict', 'item', 'dzn', 'json', 'raw'}
        The desired output format. The default is ``'dict'`` which returns a
        stream of solutions decoded as python dictionaries. The ``'item'``
        format outputs a stream of strings as returned by the ``solns2out``
        tool, formatted according to the output statement of the MiniZinc model.
        The ``'dzn'`` and ``'json'`` formats output a stream of strings
        formatted in dzn and json respectively. The ``'raw'`` format, instead
        returns the whole solution stream, without parsing.
    no_ozn : bool
        If ``True``, the ozn file is not produced, ``False`` otherwise.

    Returns
    -------
    tuple (str, str)
        The paths to the generated fzn and ozn files. If ``no_ozn=True``, the
        second argument is ``None``.
    """

    mzn_file, dzn_files, data_file, data, keep, _output_mode, types = \
        _minizinc_preliminaries(
            mzn, *dzn_files, args=args, data=data, include=include,
            stdlib_dir=stdlib_dir, globals_dir=globals_dir,
            output_vars=output_vars, keep=keep, output_base=output_base,
            output_mode=output_mode, declare_enums=declare_enums,
            allow_multiple_assignments=allow_multiple_assignments
        )

    args = ['--compile']
    args += _flattening_args(
        mzn_file, *dzn_files, data=data, stdlib_dir=stdlib_dir,
        globals_dir=globals_dir, output_mode=output_mode, include=include,
        no_ozn=no_ozn, output_base=output_base,
        allow_multiple_assignments=allow_multiple_assignments
    )

    t0 = _time()
    _run_minizinc(*args)
    flattening_time = _time() - t0
    logger.info('Flattening completed in {:>3.2f} sec'.format(flattening_time))

    if not keep:
        with contextlib.suppress(FileNotFoundError):
            if data_file:
                os.remove(data_file)
                logger.info('Deleted file: {}'.format(data_file))

    if output_base:
        mzn_base = output_base
    else:
        mzn_base = os.path.splitext(mzn_file)[0]

    fzn_file = '.'.join([mzn_base, 'fzn'])
    fzn_file = fzn_file if os.path.isfile(fzn_file) else None
    ozn_file = '.'.join([mzn_base, 'ozn'])
    ozn_file = ozn_file if os.path.isfile(ozn_file) else None

    if fzn_file:
        logger.info('Generated file: {}'.format(fzn_file))
    if ozn_file:
        logger.info('Generated file: {}'.format(ozn_file))

    return fzn_file, ozn_file
Flatten a MiniZinc model into a FlatZinc one.

    This function is equivalent to the command ``minizinc --compile``.

    Parameters
    ----------
    mzn : str
        The minizinc model. This can be either the path to the ``.mzn`` file or
        the content of the model itself.
    *dzn_files
        A list of paths to dzn files to attach to the minizinc execution,
        provided as positional arguments; by default no data file is attached.
    args : dict
        Arguments for the template engine.
    data : dict
        Additional data as a dictionary of variables assignments to supply to
        the minizinc executable. The dictionary is automatically converted to
        dzn format by the ``pymzn.dict2dzn`` function.
    include : str or list
        One or more additional paths to search for included ``.mzn`` files.
    stdlib_dir : str
        The path to the MiniZinc standard library. Provide it only if it is
        different from the default one.
    globals_dir : str
        The path to the MiniZinc globals directory. Provide it only if it is
        different from the default one.
    declare_enums : bool
        Whether to declare enum types when converting inline data into dzn
        format. If the enum types are declared elsewhere this option should be
        False. Default is ``True``.
    allow_multiple_assignments : bool
        Whether to allow multiple assignments of variables. Sometimes is
        convenient to simply let the data file override the value already
        assigned in the minizinc file. Default is ``False``.
    keep : bool
        Whether to keep the generated ``.mzn``, ``.dzn``, ``.fzn`` and ``.ozn``
        files or not. If False, the generated files are created as temporary
        files which will be deleted right after the problem is solved. Though
        files generated by PyMzn are not intended to be kept, this property can
        be used for debugging purpose. Note that in case of error the files are
        not deleted even if this parameter is ``False``. Default is ``False``.
    output_vars : list of str
        A list of output variables. These variables will be the ones included in
        the output dictionary. Only available if ``ouptut_mode='dict'``.
    output_base : str
        Output directory for the files generated by PyMzn. The default
        (``None``) is the temporary directory of your OS (if ``keep=False``) or
        the current working directory (if ``keep=True``).
    output_mode : {'dict', 'item', 'dzn', 'json', 'raw'}
        The desired output format. The default is ``'dict'`` which returns a
        stream of solutions decoded as python dictionaries. The ``'item'``
        format outputs a stream of strings as returned by the ``solns2out``
        tool, formatted according to the output statement of the MiniZinc model.
        The ``'dzn'`` and ``'json'`` formats output a stream of strings
        formatted in dzn and json respectively. The ``'raw'`` format, instead
        returns the whole solution stream, without parsing.
    no_ozn : bool
        If ``True``, the ozn file is not produced, ``False`` otherwise.

    Returns
    -------
    tuple (str, str)
        The paths to the generated fzn and ozn files. If ``no_ozn=True``, the
        second argument is ``None``.