2017-12-19 1 views
3

私はMercuryとロジックプログラミングには一般的に新しいです。これにより代数述語はMercuryでサポートされていますか?

:- pred diffThirtyFour(float, float). 
:- mode diffThirtyFour(in, out) is det. 

diffThirtyFour(A,B) :- 
    (B = A + 34.0). 

、Aは地面でなければならない、とBは自由である:私は

を例述語を取る...ドキュメントやサンプルでは、​​このような数値例を発見していません。 Aを自由にし、Bを磨く(例えば、mode diffThirtyFour(out,in) is det.を追加する)場合はどうでしょうか?この種の代数はコンパイル時に実行できますか?

更新...私は簡単に別の述語を定義することができますが、それは非常に論理的なようではありませんので

、作品のこの種のようなもの:の

:- pred diffThirtyFour(float, float). 
:- mode diffThirtyFour(in, out) is semidet. 
:- mode diffThirtyFour(out, in) is semidet. 

diffThirtyFour(A,B) :- 
    (B = A + 34.0, A = B - 34.0). 

少し警戒semidet、および第2目標の冗長性。これを行う唯一の方法ですか?

アップデート2

これが答えかもしれません...それは論理和が任意のソリューションを持つことがない程度コンパイル時に警告を発行します。正しい警告ですが、おそらく不必要なコードの臭いですか?これは私が必要なものを行いますが、より良い解決策がそこに存在する場合、それらを掲示すること自由に感じ...

:- pred diffThirtyFour(float, float). 
:- mode diffThirtyFour(in, out) is det. 
:- mode diffThirtyFour(out, in) is det. 



diffThirtyFour(A,B) :- 
    (A = B - 34.0, 
     B = A + 34.0 
    ; 
    error("The impossible happened...") 
    ). 

答えて

1

ちょうどdifferent clauses for different modesを入力する機能を発見しました。これは、(私はとにかく予想しなかったであろう)かなり代数ソルバーではありませんが、私が探していた正確な組織構造提供:リンクで説明したように

:- pred diffThirtyFour(float, float). 
:- mode diffThirtyFour(in, out) is det. 
:- mode diffThirtyFour(out, in) is det. 
:- pragma promise_pure(diffThirtyFour/2). 

diffThirtyFour(A::out,B::in) :- A = B - 34.0. 
diffThirtyFour(A::in, B::out) :- B = A + 34.0. 

を、promise_pureプラグマは、このために必要とされます機能を使用して意味の一貫性を破ることができます。また、promise_equivalent_clausesプラグマを使用すれば十分であり、これは純粋さがなく論理的な一貫性を保証します。 pred宣言のキーワードimpureを使用して、矛盾するセマンティクスの句を宣言することは可能です。

興味深いことに、標準intモジュールにおける加算及び減算は inversibleはなくfloatモジュールです。おそらく、浮動小数点演算のエラーの可能性があるために選択されました。

関連する問題