LINUX.ORG.RU

История изменений

Исправление AndreyKl, (текущая версия) :

В общем-то всё доказалось, там не очень сложно. Запутался скорее от недостатка опыта (плюс ошибку сделал при определении inner, в коде выше правда кажется уже поправлено). Попробую сделать орд вместо нат.

Спецификация осталась та же по моему (только я более общий тип добавил для списка).

Fixpoint argmax (A : Type) (default : A) (f : A -> nat) (xs : list A) : A :=
  match xs with
  | [] => default
  | [x] => x
  | x::xs => inner (f x) x f xs
  end
with inner (A : Type) (s : nat) (r : A) (f : A -> nat) (xs : list A) : A :=
       match xs with
       | [] => r
       | x::xs' => let fx := f x in
                 if s <? fx
                 then inner fx x f xs'
                 else inner s r f xs'
       end.

Theorem argmax_correct (A : Type) (d x : A) (f : A -> nat) (xs : list A) :
    argmax d f xs = x ->
    ((xs = [] /\ x = d) \/
     exists ix, nth_error xs ix = Some x /\
           (forall y iy, nth_error xs iy = Some y -> f y < f x \/ ix <= iy)).
Proof. Admitted.

Вот ссылка на рабочий код (coq 8.13)

Что касается

Вот это настоящая проблема достаточно мощных статических систем типов. Что-то чуть более нетривиальное, чем сортировку доказать крайне сложно. Можно написать assume, но в контракты времени выполнения условие не сконвертируется и вполне может оказаться ложным.

То это проблема не статических систем типов, а программирования в целом (и даже значительно шире, если честно). В программировании запросто может оказаться что ты пишешь вообще не то что нужно. И у меня так несколько раз было (на пхп/яваскрипте ещё).

Если брать контракты, то те же яйца вид сбоку: что мешает сделать ошибку в контракте? При этом логические спецификации читаются по-моему гораздо лучше. Т.е. ошибку с точки зрения корректности требований (т.е. с точки зрения «потребителя» или «клиента», т.е. того кому функция нужна в итоге для использования) найти по-моему проще в типе argmax_correct выше, чем в контракте.

Если брать данный конкретный случай, то сначала я ошибся в написании inner, а потом на спецификации inner_correct, и не мог доказать. И не доказал до тех пор пока не разобрался что именно не так и не поправил. Т.е. в некотором смысле это критерий - если не получается доказать (а вообще то должно доказываться), то вероятнее всего что то не так либо с функцией либо со спекой. Конечно, можно неудачно сформулировать и зависнуть, но это больше уже дело опыта, кмк.

Исправление AndreyKl, :

В общем-то всё доказалось, там не очень сложно. Запутался скорее от недостатка опыта (плюс ошибку сделал при определении inner, в коде выше правда кажется уже поправлено). Попробую сделать орд вместо нат.

Спецификация осталась та же по моему (только я более общий тип добавил для списка).

Fixpoint argmax (A : Type) (default : A) (f : A -> nat) (xs : list A) : A :=
  match xs with
  | [] => default
  | [x] => x
  | x::xs => inner (f x) x f xs
  end
with inner (A : Type) (s : nat) (r : A) (f : A -> nat) (xs : list A) : A :=
       match xs with
       | [] => r
       | x::xs' => let fx := f x in
                 if s <? fx
                 then inner fx x f xs'
                 else inner s r f xs'
       end.

Theorem argmax_correct (A : Type) (d x : A) (f : A -> nat) (xs : list A) :
    argmax d f xs = x ->
    ((xs = [] /\ x = d) \/
     exists ix, nth_error xs ix = Some x /\
           (forall y iy, nth_error xs iy = Some y -> f y < f x \/ ix <= iy)).
Proof. Admitted.

Вот ссылка на рабочий код (coq 8.13)

Что касается

Вот это настоящая проблема достаточно мощных статических систем типов. Что-то чуть более нетривиальное, чем сортировку доказать крайне сложно. Можно написать assume, но в контракты времени выполнения условие не сконвертируется и вполне может оказаться ложным.

То это проблема не статических систем типов, а программирования в целом (и даже значительно шире, если честно). В программировании запросто может оказаться что ты пишешь вообще не то что нужно. И у меня так несколько раз было (на пхп/яваскрипте ещё).

Если брать контракты, то те же яйца вид сбоку: что мешает сделать ошибку в контракте? При этом логические спецификации читаются по-моему гораздо лучше. Т.е. ошибку с точки зрения корректности требований (т.е. с точки зрения «потребителя» или «клиента», т.е. того кому функция нужна в итоге для использования) найти по-моему проще в типе argmax_correct выше, чем в контракте.

Если брать данный конкретный случай, то я затупил на спецификации inner_correct, и не мог доказать. И не доказал до тех пор пока не разобрался что именно не так и не поправил спецификацию. Т.е. в некотором смысле это критерий - если не получается доказать (а вообще то должно доказываться), то вероятнее всего что то не так либо с функцией либо со спекой. Конечно, можно неудачно сформулировать и зависнуть, но это больше уже дело опыта, кмк.

Исправление AndreyKl, :

В общем-то всё доказалось, там не очень сложно. Запутался скорее от недостатка опыта (плюс ошибку сделал при определении inner, в коде выше правда кажется уже поправлено). Попробую сделать орд вместо нат.

Спецификация осталась та же по моему (только я более общий тип добавил для списка).

Fixpoint argmax (A : Type) (default : A) (f : A -> nat) (xs : list A) : A :=
  match xs with
  | [] => default
  | [x] => x
  | x::xs => inner (f x) x f xs
  end
with inner (A : Type) (s : nat) (r : A) (f : A -> nat) (xs : list A) : A :=
       match xs with
       | [] => r
       | x::xs' => let fx := f x in
                 if s <? fx
                 then inner fx x f xs'
                 else inner s r f xs'
       end.

Theorem argmax_correct (A : Type) (d x : A) (f : A -> nat) (xs : list A) :
    argmax d f xs = x ->
    ((xs = [] /\ x = d) \/
     exists ix, nth_error xs ix = Some x /\
           (forall y iy, nth_error xs iy = Some y -> f y < f x \/ ix <= iy)).
Proof. Admitted.

Вот ссылка на рабочий код (coq 8.13)

Что касается

Вот это настоящая проблема достаточно мощных статических систем типов. Что-то чуть более нетривиальное, чем сортировку доказать крайне сложно. Можно написать assume, но в контракты времени выполнения условие не сконвертируется и вполне может оказаться ложным.

То это проблема не статических систем типов, а программирования в целом (и даже значительно шире, если честно). В программировании запросто может оказаться что ты пишешь вообще не то что нужно. И у меня так несколько раз было (на пхп/яваскрипте ещё).

Если брать контракты, то те же яйца вид сбоку: что мешает сделать ошибку в контракте? При этом логические спецификации читаются по-моему гораздо лучше. Т.е. ошибку с точки зрения корректности требований найти по-моему проще в типе argmax_correct выше, чем в контракте.

Если брать данный конкретный случай, то я затупил на спецификации inner_correct, и не мог доказать. И не доказал до тех пор пока не разобрался что именно не так и не поправил спецификацию. Т.е. в некотором смысле это критерий - если не получается доказать (а вообще то должно доказываться), то вероятнее всего что то не так либо с функцией либо со спекой. Конечно, можно неудачно сформулировать и зависнуть, но это больше уже дело опыта, кмк.

Исправление AndreyKl, :

В общем-то всё доказалось, там не очень сложно. Запутался скорее от недостатка опыта (плюс ошибку сделал при определении inner, в коде выше правда кажется уже поправлено). Попробую сделать орд вместо нат.

Спецификация осталась та же по моему (только я более общий тип добавил для списка).

Fixpoint argmax (A : Type) (default : A) (f : A -> nat) (xs : list A) : A :=
  match xs with
  | [] => default
  | [x] => x
  | x::xs => inner (f x) x f xs
  end
with inner (A : Type) (s : nat) (r : A) (f : A -> nat) (xs : list A) : A :=
       match xs with
       | [] => r
       | x::xs' => let fx := f x in
                 if s <? fx
                 then inner fx x f xs'
                 else inner s r f xs'
       end.

Theorem argmax_correct (A : Type) (d x : A) (f : A -> nat) (xs : list A) :
    argmax d f xs = x ->
    ((xs = [] /\ x = d) \/
     exists ix, nth_error xs ix = Some x /\
           (forall y iy, nth_error xs iy = Some y -> f y < f x \/ ix <= iy)).
Proof. Admitted.

Вот ссылка на рабочий код (coq 8.13)

Что касается

Вот это настоящая проблема достаточно мощных статических систем типов. Что-то чуть более нетривиальное, чем сортировку доказать крайне сложно. Можно написать assume, но в контракты времени выполнения условие не сконвертируется и вполне может оказаться ложным.

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

Если брать контракты, то те же яйца вид сбоку: что мешает сделать ошибку в контракте? При этом логические спецификации читаются по-моему гораздо лучше. Т.е. ошибку с точки зрения корректности требований найти по-моему проще в типе argmax_correct выше, чем в контракте.

Если брать данный конкретный случай, то я затупил на спецификации inner_correct, и не мог доказать. И не доказал до тех пор пока не разобрался что именно не так и не поправил спецификацию. Т.е. в некотором смысле это критерий - если не получается доказать (а вообще то должно доказываться), то вероятнее всего что то не так либо с функцией либо со спекой. Конечно, можно неудачно сформулировать и зависнуть, но это больше уже дело опыта, кмк.

Исходная версия AndreyKl, :

В общем-то всё доказалось, там не очень сложно. Запутался скорее от недостатка опыта (плюс ошибку сделал при определении inner, в коде выше правда кажется уже поправлено). Попробую сделать орд вместо нат.

Спецификация осталась та же по моему (только я более общий тип добавил для списка).

Fixpoint argmax (A : Type) (default : A) (f : A -> nat) (xs : list A) : A :=
  match xs with
  | [] => default
  | [x] => x
  | x::xs => inner (f x) x f xs
  end
with inner (A : Type) (s : nat) (r : A) (f : A -> nat) (xs : list A) : A :=
       match xs with
       | [] => r
       | x::xs' => let fx := f x in
                 if s <? fx
                 then inner fx x f xs'
                 else inner s r f xs'
       end.

Theorem argmax_correct (A : Type) (d x : A) (f : A -> nat) (xs : list A) :
    argmax d f xs = x ->
    ((xs = [] /\ x = d) \/
     exists ix, nth_error xs ix = Some x /\
           (forall y iy, nth_error xs iy = Some y -> f y < f x \/ ix <= iy)).
Proof. Admitted.

Вот ссылка на рабочий код (coq 8.13)

Что касается

Вот это настоящая проблема достаточно мощных статических систем типов. Что-то чуть более нетривиальное, чем сортировку доказать крайне сложно. Можно написать assume, но в контракты времени выполнения условие не сконвертируется и вполне может оказаться ложным.

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

Если брать контракты, то те же яйца вид сбоку: что мешает сделать ошибку в контракте? При этом логические спецификации читаются по-моему гораздо лучше. Т.е. ошибку с точки зрения корректности требований найти по-моему проще в типе argmax_correct выше, чем в контракте.

Если брать данный конкретный случай, то я затупил на спецификации inner_correct, и не мог доказать. И не доказал до тех пор пока не разобрался что именно не так и не поправил спецификацию. Т.е. в некотором смысле это критерий - если не получается доказать (а вообще то должно доказываться), то вероятнее всего что то не так либо с функцией либо со спекой. Конечно, можно неудачно сформулировать и зависнуть, но это больше уже дело опыта, кмк.