Proof: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 28: | Line 28: | ||
3.1. using built-in natural numbers: |
3.1. using built-in natural numbers: |
||
< |
<syntaxhighlight lang="lisp">(thm (implies (and (evenp x) (evenp y)) |
||
(evenp (+ x y))))</ |
(evenp (+ x y))))</syntaxhighlight> |
||
=={{header|Agda}}== |
=={{header|Agda}}== |
||
< |
<syntaxhighlight lang="agda">module PeanoArithmetic where |
||
-- 1.1. The natural numbers. |
-- 1.1. The natural numbers. |
||
Line 216: | Line 216: | ||
-- when checking that the clause even+even≢even zero zero () has type |
-- when checking that the clause even+even≢even zero zero () has type |
||
-- {m n : ℕ} → 2×ℕ m → 2×ℕ n → ¬ 2×ℕ (m + n) |
-- {m n : ℕ} → 2×ℕ m → 2×ℕ n → ¬ 2×ℕ (m + n) |
||
-- </ |
-- </syntaxhighlight> |
||
=={{header|ATS}}== |
=={{header|ATS}}== |
||
Line 229: | Line 229: | ||
< |
<syntaxhighlight lang="ats">(* Let us do a little quasi-math in ATS, even though this is NOT an |
||
intended use of the facilities. However, I DO consider the task a |
intended use of the facilities. However, I DO consider the task a |
||
good didactic exercise. *) |
good didactic exercise. *) |
||
Line 378: | Line 378: | ||
implement |
implement |
||
main0 () = |
main0 () = |
||
println! ("Success!")</ |
println! ("Success!")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 393: | Line 393: | ||
< |
<syntaxhighlight lang="ats">(* ATS does not contain a full-fledged proof language, but does |
||
contain enough to do a considerable amount of *informal* proof |
contain enough to do a considerable amount of *informal* proof |
||
about a program. |
about a program. |
||
Line 495: | Line 495: | ||
implement |
implement |
||
main0 () = |
main0 () = |
||
println! ("Success!")</ |
println! ("Success!")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 503: | Line 503: | ||
=={{header|Coq}}== |
=={{header|Coq}}== |
||
< |
<syntaxhighlight lang="coq">(* 1.1 Define a countably infinite set of natural numbers {0, 1, 2, 3, ...}. *) |
||
Inductive nat : Set := |
Inductive nat : Set := |
||
| O : nat |
| O : nat |
||
Line 619: | Line 619: | ||
intros. apply H1. apply (even_plus_even _ _ H H0). |
intros. apply H1. apply (even_plus_even _ _ H H0). |
||
Qed. |
Qed. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 631: | Line 631: | ||
However, there is no obvious way to show that 3.2 and 3.3 must always be true (though you could argue that addition must be commutative because the 'addEven' function is symmetric in relation to its arguments). So all I've been able to do here is write functions to test these assertions for given even numbers whilst accepting that this doesn't constitute a proof for all such cases. |
However, there is no obvious way to show that 3.2 and 3.3 must always be true (though you could argue that addition must be commutative because the 'addEven' function is symmetric in relation to its arguments). So all I've been able to do here is write functions to test these assertions for given even numbers whilst accepting that this doesn't constitute a proof for all such cases. |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 793: | Line 793: | ||
testAssociative(genEven(numbers[7]), genEven(numbers[8]), genEven(numbers[9])) |
testAssociative(genEven(numbers[7]), genEven(numbers[8]), genEven(numbers[9])) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 821: | Line 821: | ||
Using [http://www.haskell.org/haskellwiki/GADT GADTs] and [http://www.haskell.org/haskellwiki/GHC/Type_families type families] it is possible to write a partial adaptation of the Agda version: |
Using [http://www.haskell.org/haskellwiki/GADT GADTs] and [http://www.haskell.org/haskellwiki/GHC/Type_families type families] it is possible to write a partial adaptation of the Agda version: |
||
< |
<syntaxhighlight lang="haskell">{-# LANGUAGE TypeOperators, TypeFamilies, GADTs #-} |
||
module PeanoArithmetic where |
module PeanoArithmetic where |
||
Line 966: | Line 966: | ||
-- |
-- |
||
-- since we have a "citizen" of an uninhabited type here (contradiction!). |
-- since we have a "citizen" of an uninhabited type here (contradiction!). |
||
-- </ |
-- </syntaxhighlight> |
||
See also [[Proof/Haskell]] for implementation of a small theorem prover. |
See also [[Proof/Haskell]] for implementation of a small theorem prover. |
||
Line 976: | Line 976: | ||
These ways can be combined. |
These ways can be combined. |
||
<syntaxhighlight lang="idris"> |
|||
<lang Idris> |
|||
module Proof |
module Proof |
||
Line 1,110: | Line 1,110: | ||
exact evenNotOdd (EvSS ex) ossx |
exact evenNotOdd (EvSS ex) ossx |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Isabelle}}== |
=={{header|Isabelle}}== |
||
< |
<syntaxhighlight lang="isabelle">theory Proof |
||
imports Main |
imports Main |
||
begin |
begin |
||
Line 1,199: | Line 1,199: | ||
by(auto intro: myeven.intros) |
by(auto intro: myeven.intros) |
||
end</ |
end</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Line 1,209: | Line 1,209: | ||
So, these can be our definitions: |
So, these can be our definitions: |
||
< |
<syntaxhighlight lang="j">context=:3 :0 |
||
if. 0 = L. y do. context (,: ; ]) y return. end. |
if. 0 = L. y do. context (,: ; ]) y return. end. |
||
kernel=. > {: y |
kernel=. > {: y |
||
Line 1,241: | Line 1,241: | ||
odd=: successor@even |
odd=: successor@even |
||
defined=: '(zero not exists_in odd successor equals is_member_of addition even)'</ |
defined=: '(zero not exists_in odd successor equals is_member_of addition even)'</syntaxhighlight> |
||
Here, '''even''' is a function which, given a natural number, produces a corresponding even natural number. '''odd''' is a similar function which gives us odd numbers. |
Here, '''even''' is a function which, given a natural number, produces a corresponding even natural number. '''odd''' is a similar function which gives us odd numbers. |
||
Line 1,260: | Line 1,260: | ||
# the sum of two even numbers can never be odd. |
# the sum of two even numbers can never be odd. |
||
< |
<syntaxhighlight lang="j">'A B C' induction 0 :0 |
||
((even A) addition (even B)) is_member_of (even C) |
((even A) addition (even B)) is_member_of (even C) |
||
((A addition B) addition C) equals (A addition (B addition C)) |
((A addition B) addition C) equals (A addition (B addition C)) |
||
(A addition B) equals (B addition A) |
(A addition B) equals (B addition A) |
||
not ((even A) addition (even B)) exists_in (odd C) |
not ((even A) addition (even B)) exists_in (odd C) |
||
)</ |
)</syntaxhighlight> |
||
Meanwhile, here is how the invalid proofs fail: |
Meanwhile, here is how the invalid proofs fail: |
||
< |
<syntaxhighlight lang="j"> 'A B C' induction '((even A) addition (even B)) is_member_of (odd C)' |
||
|assertion failure: assert</ |
|assertion failure: assert</syntaxhighlight> |
||
and |
and |
||
< |
<syntaxhighlight lang="j"> 'A B C' induction 'not ((even A) addition (even B)) is_member_of (even C)' |
||
|assertion failure: assert</ |
|assertion failure: assert</syntaxhighlight> |
||
Line 1,284: | Line 1,284: | ||
We use the Go method which means that this Nim version has the same limits. When translating, we did some adjustments: for instance, we use overloading of operators which allows a more natural way to express the operations. |
We use the Go method which means that this Nim version has the same limits. When translating, we did some adjustments: for instance, we use overloading of operators which allows a more natural way to express the operations. |
||
< |
<syntaxhighlight lang="nim">import strformat, sugar |
||
type |
type |
||
Line 1,393: | Line 1,393: | ||
testCommutative(newEvenNumber(numbers[8]), newEvenNumber(numbers[9])) |
testCommutative(newEvenNumber(numbers[8]), newEvenNumber(numbers[9])) |
||
testAssociative(newEvenNumber(numbers[7]), newEvenNumber(numbers[8]), newEvenNumber(numbers[9]))</ |
testAssociative(newEvenNumber(numbers[7]), newEvenNumber(numbers[8]), newEvenNumber(numbers[9]))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,418: | Line 1,418: | ||
Using GADT, we can port the Coq version to OCaml. |
Using GADT, we can port the Coq version to OCaml. |
||
<syntaxhighlight lang="ocaml"> |
|||
<lang OCaml> |
|||
type zero = Zero |
type zero = Zero |
||
type 'a succ = Succ |
type 'a succ = Succ |
||
Line 1,475: | Line 1,475: | ||
plus_succ_left (plus_commutative a plus') |
plus_succ_left (plus_commutative a plus') |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Omega}}== |
=={{header|Omega}}== |
||
< |
<syntaxhighlight lang="omega">data Even :: Nat ~> *0 where |
||
EZ:: Even Z |
EZ:: Even Z |
||
ES:: Even n -> Even (S (S n)) |
ES:: Even n -> Even (S (S n)) |
||
Line 1,489: | Line 1,489: | ||
even_plus EZ en = en |
even_plus EZ en = en |
||
even_plus (ES em) en = ES (even_plus em en) |
even_plus (ES em) en = ES (even_plus em en) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 1,496: | Line 1,496: | ||
Clearly 3.2 and 3.3 are not attempted, and I'm not sure which of 3.4/4.1/4.2 the last axiom is |
Clearly 3.2 and 3.3 are not attempted, and I'm not sure which of 3.4/4.1/4.2 the last axiom is |
||
closest to, or for that matter what the difference between them is supposed to be. |
closest to, or for that matter what the difference between them is supposed to be. |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #008080;">constant</span> <span style="color: #000000;">axioms</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"even+1"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"odd"</span><span style="color: #0000FF;">},</span> |
<span style="color: #008080;">constant</span> <span style="color: #000000;">axioms</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"even+1"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"odd"</span><span style="color: #0000FF;">},</span> |
||
Line 1,534: | Line 1,534: | ||
<span style="color: #000000;">proof</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"int"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"even"</span><span style="color: #0000FF;">)</span> |
<span style="color: #000000;">proof</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"int"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"even"</span><span style="color: #0000FF;">)</span> |
||
<span style="color: #000000;">proof</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"even+even"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"odd"</span><span style="color: #0000FF;">)</span> |
<span style="color: #000000;">proof</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"even+even"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"odd"</span><span style="color: #0000FF;">)</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,562: | Line 1,562: | ||
Via <code>#lang cur</code>. |
Via <code>#lang cur</code>. |
||
< |
<syntaxhighlight lang="racket">#lang cur |
||
(require rackunit |
(require rackunit |
||
Line 1,637: | Line 1,637: | ||
(by-rewrite IHa) |
(by-rewrite IHa) |
||
display-focus ; show how the context and goal are after rewrite |
display-focus ; show how the context and goal are after rewrite |
||
reflexivity)</ |
reflexivity)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,660: | Line 1,660: | ||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Partial attempt only. |
Partial attempt only. |
||
<lang |
<syntaxhighlight lang="raku" line># 20200807 Raku programming solution (Incomplete) |
||
sub check ($type, @testee) { |
sub check ($type, @testee) { |
||
Line 1,702: | Line 1,702: | ||
# 4.1 Prove that the addition of any two even numbers cannot be odd |
# 4.1 Prove that the addition of any two even numbers cannot be odd |
||
# 4.2 Try to prove that the addition of any two even numbers cannot be even (it should be rejected) |
# 4.2 Try to prove that the addition of any two even numbers cannot be even (it should be rejected) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>Is 0 ∈ ℕ : True |
<pre>Is 0 ∈ ℕ : True |
||
Line 1,718: | Line 1,718: | ||
Note that the only current implementation of Salmon is an interpreter that ignores proofs and doesn't try to check them, but in the future when there is an implementation that checks proofs, it should be able to check the proof in this Salmon code. |
Note that the only current implementation of Salmon is an interpreter that ignores proofs and doesn't try to check them, but in the future when there is an implementation that checks proofs, it should be able to check the proof in this Salmon code. |
||
< |
<syntaxhighlight lang="salmon">pure function even(x) returns boolean ((x in [0...+oo)) && ((x % 2) == 0)); |
||
theorem(forall(x : even, y : even) ((x + y) in even)) |
theorem(forall(x : even, y : even) ((x + y) in even)) |
||
proof |
proof |
||
Line 1,746: | Line 1,746: | ||
(x + y) in even because type_definition(even, L10); |
(x + y) in even because type_definition(even, L10); |
||
}; |
}; |
||
};</ |
};</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 1,752: | Line 1,752: | ||
{{works with|Tcl|8.5}} |
{{works with|Tcl|8.5}} |
||
< |
<syntaxhighlight lang="tcl">package require datatype |
||
datatype define Int = Zero | Succ val |
datatype define Int = Zero | Succ val |
||
datatype define EO = Even | Odd |
datatype define EO = Even | Odd |
||
Line 1,818: | Line 1,818: | ||
} { |
} { |
||
puts "\tevenOdd \[[list add $a $b]\] = [evenOdd [add $a $b]]" |
puts "\tevenOdd \[[list add $a $b]\] = [evenOdd [add $a $b]]" |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>BASE CASE |
<pre>BASE CASE |
||
Line 1,836: | Line 1,836: | ||
=={{header|Twelf}}== |
=={{header|Twelf}}== |
||
< |
<syntaxhighlight lang="twelf">nat : type. |
||
z : nat. |
z : nat. |
||
s : nat -> nat. |
s : nat -> nat. |
||
Line 1,880: | Line 1,880: | ||
%worlds () (sum-evens _ _ _ _). |
%worlds () (sum-evens _ _ _ _). |
||
%total D (sum-evens D _ _ _). |
%total D (sum-evens D _ _ _). |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Line 1,886: | Line 1,886: | ||
{{libheader|Wren-fmt}} |
{{libheader|Wren-fmt}} |
||
Most of what was said in the preamble to the Go entry applies equally to Wren though, as Wren is dynamically typed, we have to rely on runtime type checks. |
Most of what was said in the preamble to the Go entry applies equally to Wren though, as Wren is dynamically typed, we have to rely on runtime type checks. |
||
< |
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt |
||
// Represents a natural number. |
// Represents a natural number. |
||
Line 2,056: | Line 2,056: | ||
testCommutative.call(EvenNumber.new(numbers[8]), EvenNumber.new(numbers[9])) |
testCommutative.call(EvenNumber.new(numbers[8]), EvenNumber.new(numbers[9])) |
||
testAssociative.call(EvenNumber.new(numbers[7]), EvenNumber.new(numbers[8]), EvenNumber.new(numbers[9]))</ |
testAssociative.call(EvenNumber.new(numbers[7]), EvenNumber.new(numbers[8]), EvenNumber.new(numbers[9]))</syntaxhighlight> |
||
{{out}} |
{{out}} |