2015-01-22 3 views
2

Я знакомлюсь с базой MiniZinc. Итак, вооружившись MiniZinc IDE, я пишу фрагменты, какотладка minizinc (во всяком случае, я нашел ошибку?)

solve satisfy; 

string: s1 = "hello"; 
string: s2 = "world"; 

function list of int: cdr(list of int: v) = 
    [v[i] | i in 1..length(v)]; 
function list of string: cdr(list of string: v) = 
    [v[i] | i in 1..length(v)]; 

function string: concat(list of string: V) = 
    if length(V) == 0 then "" else V[0] ++ concat(cdr(V)) endif; 

output [concat([s1," ",s2])++" "++show(cdr([1,2,3]))]; 

, который отображает

Compiling hello.mzn 
Running hello.mzn 
hello world [1, 2, 3] 
---------- 
Finished in 49msec 

настоящее время, корд из списка Интс кажется неправильным. Я предполагаю, что это моя ошибка, хотя я не могу ее заметить.

Может ли assertions помочь мне здесь? Поскольку я собираюсь использовать Gecode (а затем у меня есть Gist), чтобы на самом деле поставить мой код в производство, могу ли я следовать этому маршруту?

Любой намек оценил ...

редактировать этот фрагмент

solve satisfy; 

function list of string: cdr_s(list of string: v) = 
    [v[i] | i in 2..length(v)]; 

function string: vcat(list of string: V) = 
    if length(V) == 0 then "" else V[1] ++ vcat(cdr_s(V)) endif; 

output [vcat(["hello"," ","world"])]; 

отчеты

MiniZinc: type error: no function or predicate with this signature found: `cdr_s(array[int] of string)' 
/tmp/MiniZinc IDE-9nYiuF/hello.ozn:2 

ответ

3

Я немного смущен тем, что, по вашему мнению, является ошибкой, и есть некоторые другие проблемы.

Выходной сигнал модели кажется прекрасным с помощью «cdr ([1,2,3])« дающего »[1,2,3]». Название «корд» означает, что вы хотите функцию «но первый», но MiniZinc система по умолчанию 1 на основе (не 0 на основе), поэтому ваша функция, вероятно, следует

function list of int: cdr(list of int: v) = 
    [v[i] | i in 2..length(v)]; 

Так можно определить индексы массива (например,что индекс старт 0), более общее определение этого (что я не очень доволен, но вы, вероятно, получите мою точку):

function list of int: cdr3(list of int: v) = 
    [v[i] | i in index_set(v) diff {min(index_set(v))}]; 

Итак, теперь вы можете написать что-то вроде этого:

% ... 
array[int] of int: t = array1d(0..3, [1,2,3,4]) 
output [ 
    show(cdr3(t)) 
]; 

Кроме того, ваша функция «concat» не используется вообще, вместо нее используется встроенный «concat». (Попробуйте переименовать свою версию в «concat1».) Вот почему вы не получаете ошибку для конструкции «V [0]» (которая должна выдавать ошибку за пределы). Я ожидал, что попытка переопределить встроенный файл приведет к ошибке, но MiniZinc 2.0 более разрешительна, чем версия 1.6 в определенных областях.

И я согласен с общим замечанием Акселя. В качестве общего языка программирования MiniZinc не очень впечатляет (по крайней мере, в моей книге). Реальная власть возникает, когда вы добавляете ограничения и переменные решения в модель. Обратите внимание, что обработка списка/массивов MiniZinc с переменными решения не так динамична, как Prolog. В общем, вы всегда должны мыслить в терминах массивов с фиксированной длиной.

Замечательно, что вы начинаете изучать MiniZinc. Я надеюсь, что эти комментарии действительно помогут вам при изучении MiniZinc.

/Hakan

+0

вне темы - ваша страница MiniZinc недоступна на данный момент? –

+0

Возможно, я должен был упомянуть об этом. Да, http://hakank.org/ не работает уже неделю. Лучшей заменой является использование моей страницы GitHub: https://github.com/hakank/hakank, где публикуются почти все мои модели CP (и все остальное). – hakank

+0

еще одна ошибка, которую я обнаружил после того, как исправил ее с указанием: кажется, что пользовательские функции не могут вызывать другие пользовательские функции ... – CapelliC

2

MiniZinc является решатель, а не обычный язык программирования. Он знает переменные и параметры. Вы определяете ограничения, чтобы разграничить пространство поиска для значений переменных, составляющих решения. Оператор вывода затем используется для отображения решения форматированным способом.

В коде нет ни переменных, ни ограничений. Утверждения используются в MiniZinc как специальные ограничения ("assertint assert") для обнаружения недопустимых параметров. Это похоже на макрос assert в C/C++.

Пользовательские функции были введены в MiniZinc 2.0, чтобы написать ограничения более элегантным способом. Также поддерживается рекурсия.

Посмотрите на tutorial и examples.

Hakan Kjellerstrand's MiniZinc page также отличное начало.

Твой знак gecode относится к одному из поддерживаемых опорных концов для MiniZinc. MiniZinc IDE позволяет выбрать внутренний интерфейс. Для некоторых back-end требуется установка внешних пакетов. Компилятор MiniZinc создает промежуточный код FlatZinc, который окончательно интерпретируется и решается одним из решающих обратных концов.

+0

Спасибо. С моим глупым тестом я пытался понять, насколько поддерживается поддержка перегрузки пользователей, и доступны инструменты для отладки. До сих пор я еще не нашел практического способа отладки ... – CapelliC

+0

В некоторых случаях это помогает взглянуть на файл FlatZinc. Он показывает, как MiniZinc интерпретирует спецификацию программирования ограничений. Кроме того, вы можете запустить minizinc.exe с параметром --keep-files, чтобы иметь возможность анализировать промежуточные файлы. Большинство исполняемых файлов вокруг MiniZinc имеют отладочные флаги в качестве необязательных параметров командной строки. –

+0

@CapelliC Один способ отладки - использовать трассировку/1 для индексов печати и т. Д. – hakank

Смежные вопросы