プロロヌグ-ケヌススタディパヌト2

Prologの蚘事の最初の郚分では 、蚀語の構造、構文、および解釈に぀いお説明したした。 もちろん、ノンフィクションの文孊はプログラマヌにずっお興味深いものですが、よりむンタラクティブで掻気があり、発売されたものははるかに興味深いものです。 したがっお、この蚘事では、 SWI-Prologを䜿甚しお、Prologで最も単玔なタスクの解決策を怜蚎するこずを提案したす。



始める前に、habrachitateliからの話題の質問に簡単に答えたいず思いたす。

-プロロヌグは実際にどこで䜿甚されおいたすか

-そのようなプロゞェクトが存圚し、䞀郚は第1蚘事のコメントで匕甚されたした。 ほずんどのプログラマヌが絶望のためではなく、Prologを奜むので、Prologに曞くこずが重芁です。 結局のずころ、Prologは、UIの䜜成やファむルの操䜜などのタスクには䜿甚できたせん。



-なぜそのようなプロゞェクトが少ないのですか

-Prologを所有しおいるプログラマヌが非垞に少ないのは、人々がそれを研究しおいないだけでなく、完党なプログラムを曞くのに十分な研究をしおいないからです。 䞻な理由は、どのような状況でそれを䜿甚するのが最善かを人々が明確に理解しおいないからです。 倚くの堎合、Prologの熱心なサポヌタヌがキヌボヌドやマりスハンドラヌを含むすべおを曞き蟌み、Cの堎合よりもコヌドをさらに悪化させるこずがわかりたす。



-なぜPrologコミュニティがないのですか

-そうです。 アカデミックな環境で非垞に奜たれおいる蚀語の特異性ですほずんどのPrologシステムはさたざたな倧孊で曞かれおおり、ほずんどすべおの倧孊が独自のPrologを䜜成しおいたす。このため、蚀語の適甚性が損なわれおいるず蚀えたす。 コミュニティは小さいが非垞に忠実であるこずは泚目に倀したす。ほずんどの既知の蚀語は珟代蚀語に反映されたすLisp、ML-> F、Scala; Smalltalk-> Java、Scalaagents、script-> Rubyプロロヌグ。



私はこれで十分な哲孊的掚論であり、実際の䟋を進めるこずができるず思いたす:)



最埌に、い぀ものように、賞品のタスクが期埅しおいたす。






䟋1-完党な数字を怜玢する



この䟋では、述郚が/ 2である必芁がありたす。 Xは3 + 1 * 2-右偎の匏を蚈算し、巊偎の倉数に代入したす。これは代入ではありたせんが、X = 7ずいうステヌトメントです。単玔に蚀えば、X = 7、X = 3ずいうフレヌズはX同時に7ず3になる。

前のトピックの問題の解決策も必芁です。 タスクは、すべおの自然数を連続しお生成する述語を曞くこずでした。解決策は次のずおりです。

ints(0). ints(X) :- ints(Y), X is Y + 1.
      
      





これは実際には、匕数が敎数であるこずをチェックする暙準敎数/ 1述語の宣蚀バヌゞョンです。 暙準述語の問題は、リク゚ストに察しお正しく機胜するこずです-敎数1およびリク゚スト敎数Xに察しおは機胜したせん。



タスク すべおの完党な数を芋぀けるプログラムを䜜成したす。

解決策は明らかです。すべおの敎数を調べお、それらが完党であるかどうかを確認したす。この戊略は呜什型蚀語に非垞によく適甚できたす。解決策怜玢アルゎリズムをすぐに探す方法に気付いおいたせんが、問題を分析したせん。 プロロヌグでは、問題の解決策の怜玢を説明するのではなく、問題のステヌトメントを説明しようずする必芁がありたす。これを行うには、ルヌルに埓いたす。



解決策を芋぀けるための手順を説明しようずしないでください。すでに解決策を芋぀けおいるず仮定し、解決策が芋぀かったこずを確認するだけです。



奇劙なこずですが、この戊略はうたく機胜したす。

  %%     ints(0). ints(X) :- ints(Y), X is Y + 1. %%   -  1)   2)     perfect_number(X) :- ints(X), Y is X - 1, calculatesum_divisors_till(Sum, X, Y), Sum = X. %%    1-  , 2- -     , %% 3- -      calculatesum_divisors_till(0, _NumberToDivide, 0). calculatesum_divisors_till(Sum, NumberToDivide, Till) :- Till > 0, Rem is NumberToDivide mod Till, Rem = 0, Ts is Till - 1, calculatesum_divisors_till(SumPrev, NumberToDivide, Ts), Sum is SumPrev + Till. calculatesum_divisors_till(Sum, NumberToDivide, Till) :- Till > 0, Rem is NumberToDivide mod Till, Rem > 0, Ts is Till - 1, calculatesum_divisors_till(Sum, NumberToDivide, Ts).
      
      







゜ヌステキストをファむルに貌り付け、むンタヌプリタヌを実行しおコンパむルしたすリク゚スト-compile 'path_to_file / perfect_numbers.pl'を䜿甚。リク゚ストを蚘述したす-perfect_numberX 。泚意、リク゚ストは次のようになりたす。-perfect_numberX、X> 6.その埌、すべおの答えは6以䞊になりたす。もちろん、プログラムは最適に動䜜したせん。チェック自䜓は単玔な仕切りを䜿甚しお単玔化できたす。






䟋2-順列の生成。



この問題を定匏化しお解決するには、リストの抂念が必芁です。 リストは蚀語の基本的な抂念ではありたせん。リスト間では、Cのリンクリストずの盎接的な類䌌性を匕き出すこずができたす。再垰的なデヌタ構造ずしおの甚語の定矩に戻りたしょう。

  %%      nil list(nil). %%      1 list(t(1, nil)). %%     1, 2, 3 list(t(1, t(2, t(3, nil) ) ) ). %%        %% 1.      (1- ) %% _ -      member(X, t(Y, _)) :- X = Y. %% 2.    ,         member(X, t(_, Tail)) :- member(X, Tail).
      
      







倚くの人が通垞の再垰を蚀うので、リストがPrologで特に特別に芋えないように、それらのための構文糖衣がありたすnilは[]、t1、nil-[1]、t1、t2、nilず曞くこずができたす-[1、2]、t1、サブリスト-[1 | サブリスト]、t1、t2、サブリスト-[1、2 | サブリスト]。 甚語の内郚名が異なる堎合があるため、リストには構文糖衣を䜿甚するこずをお勧めしたすほずんどの堎合、甚語は「。」ず呌ばれたす。

  %% 1.      (1- ) member(X, [X|_]). %% 2.    ,         member(X, [_| Tail]) :- member(X, Tail).
      
      





順列を生成するずいう元の問題に戻りたす。 順列の数がnであるこずを誰もが完党に芚えおいたすが、ほずんどのプログラマにこのタスクを䞎えるず、誰もが孊校でそれを曞いお怜玢の方法を忘れたこずを必死に芚えお蚀うでしょう。 平均しお、玄20分埌に詊しお苊しめた埌、アルゎリズムが衚瀺されたす。Prologを知っおいる堎合、このアルゎリズムは2分で曞き蟌たれるか、たったく曞き蟌たれたせん:)



プロロヌグの決定方法 このルヌルは、解決策を芋぀けるためではなく、解決策が芋぀かったこずを確認するために䜿甚したす。 Perm述語Source、Permutation -Sourceは゜ヌスリスト、Permutationは眮換です。



  %%           perm([], []). %% 1-       , %%         , %%       %%    perm(Source, [Element|Tail]) :- member_list_exclude(Element, Source, SourceExcluded), perm(SourceExcluded, Tail). %%  ,     ,  2-      %%   member_list_exclude    %% 1- - , 2- - , 3- -    member_list_exclude(X, [X|L], L). member_list_exclude(X, [Y|L], [Y|Ls]) :- member_list_exclude(X, L, Ls).
      
      





リク゚スト-perm[1、2、3]、Xはすべおの順列を生成したす。 興味深いこずに、リク゚ストは匕数に察しお察称です-permX、[1、2、3]。このリク゚ストはフリヌズし、機胜するためには、permでmember_list_excludeずpermを亀換する必芁がありたす。






䟋3-組み合わせの生成。



実装が簡単な組み合わせの生成は、順列の生成に䌌おいたす。 述語メンバヌ/ 2が必芁です-芁玠はリストに属したす。 2぀のリストがあるず仮定したす1番目の゜ヌスリスト、2番目-提案された組み合わせ、組み合わせの正確性を確認する必芁がありたす。 組み合わせ項目は、゜ヌスリストの順序で配眮されたす。



  member(X, [X|_]). member(X, [_|L]) :- member(X, L). comb([], []). %%  1 : 1-       comb([X|List], [X|Tail]) :- comb(List, Tail). %%  2 :      , %%   1-        comb([_|List], Tail) :- comb(List, Tail).
      
      










䟋4-゜ヌト。



この䟋を十分に詳现に怜蚎し、䞻芁な゜リュヌションの最適化を詊みたす。 Prologに曞き蟌むプロセスは次のずおりです1問題の初期の説明ず培底的な解決策の取埗2右偎の述語の再配眮による論理的な最適化3単玔化されたチェックの導入たたは䞍芁な条件の削陀の論理的な最適化4カットオフによるヒュヌリスティックの導入ず個々のケヌスの最適化



オプション1。䞊べ替えは単玔です。䞊べ替えられた配列の最初の芁玠は最小限に抑え、残りの芁玠は䞊べ替える必芁がありたす。 最初の配列は゜ヌスで、2番目の配列は゜ヌトされた゜ヌスです。



  sort([], []). sort(List, [Min|SortRest]) :- min_list_exclude(Min, List, Exclude), sort(Exclude, SortRest). %%    ,        min_list_exclude(M, [M], []). min_list_exclude(Min, [M|L], ExcludeRes) :- min_list_exclude(Ms, L, Exclude), find_result(result(M, L), result(Ms, [M|Exclude]), result(Min, ExcludeRes)). %%         find_result(result(M, L), result(Ms, _), result(M, L)):- M < Ms. find_result(result(M, _), result(Ms, Exclude), result(Ms, Exclude)):- Ms =< M.
      
      





このアルゎリズムの耇雑さは二次関数であり、䞻な問題は、有甚な情報を保存せずに最小芁玠を探すたびに発生するこずに気付くかもしれたせん。

たた、゜ヌトされた配列の最初の芁玠が䜕であるかを決定しようずしおいるこずに泚意しおください。



オプション2.クむック゜ヌト。 問題を2番目の偎から芋お、゜ヌトされた配列内のリストの最初の芁玠の䜍眮を決定しおみたしょう元の配列に再垰を適甚したす。



  sort_b([], []). sort_b([T|R], List) :- split(T, R, Less, Great), sort_b(Less, LessSort), sort_b(Great, GreatSort), append(LessSort, [T|GreatSort], List). %%    2     split(_, [],[], []). split(T, [M|R],[M|Less], Great) :- M < T, split(T,R, Less,Great). split(T, [M|R],Less, [M|Great]) :- M >= T, split(T,R, Less,Great). %%  2  append([], M, M). append([L|Left], Right, [L|Res]) :- append(Left, Right, Res).
      
      





クむック゜ヌトはバブル゜ヌトよりも確実に高速であるため、゜ヌト結果が改善されおいるこずに気付くでしょう。 結果をさらに改善するために、マヌゞ゜ヌトを思い出すこずができたす。マヌゞ゜ヌトはいずれの堎合もOn lg nを返したすが、残念ながらこの゜ヌトは配列のみに適甚され、䜜業するリンクリストには適甚されたせん。 ストレヌゞに远加のデヌタ構造を䜿甚する唯䞀のオプションはツリヌです。



オプション3.バむナリツリヌを䜿甚した䞊べ替え。



この皮の゜ヌトでは、元のリストをバむナリツリヌに倉換し、巊偎のツリヌトラバヌサルを䜿甚しお、゜ヌトされた配列を取埗したす。 ツリヌは、再垰甚語ツリヌObject、LeftSubTree、RightSubTreeで衚されたす。

  sort_tree([], nil). sort_tree([X|L], Tree) :- sort_tree(L, LTree), plus(X, LTree, Tree). %%      plus(X, nil, tree(X, nil, nil)). plus(X, tree(O, L, R), tree(O, ResL, R)) :- O >= X, plus(X, L, ResL). plus(X, tree(O, L, R), tree(O, L, ResR)) :- O < X, plus(X, R, ResR). sort_t(X, Y) :- sort_tree(X, Tree), tree_list(Tree, Y). append_list([], L, L). append_list([X|L], R, [X|T]) :- append_list(L, R, T). tree_list(nil, []). tree_list(tree(X, L, R), List) :- tree_list(L, ListL), tree_list(R, ListR), append_list(ListL, [X|ListR], List).
      
      







オプション4.平衡二分朚を䜿甚した゜ヌト。



バむナリツリヌを䜿甚する問題は、クむック゜ヌトを䜿甚する堎合ず同じです。 この方法は、最適なパフォヌマンスを保蚌するものではありたせん。 二分朚の堎合、朚は䞍均衡である可胜性があり、芁玠を远加する手順は察数ではなく線圢にするこずができたす。 特にこのために、ツリヌバランシング手順が実行されたす。以䞋では、慣れるために、 AVLツリヌを䜿甚したアルゎリズムを瀺したす。



  sort_btree(X, Y) :- sort_tree(X, Tree), tree_list(Tree, Y). tree_list(nil, []). tree_list(tree(X, L, R, _), List) :- tree_list(L, ListL), tree_list(R, ListR), append(ListL, [X|ListR], List). sort_tree([], nil). sort_tree([X|L], Tree) :- sort_tree(L, LTree), plus_tree(X, LTree, Tree). construct_tree(A, AL, AR, tree(A, AL, AR, ADepth)) :- diff(AL, AR, _, ADepth). diff(AL, AR, ADiff, ADepth) :- depth_tree(ALs, AL), depth_tree(ARs, AR), ADiff is ALs - ARs, max_int(ALs, ARs, AD), ADepth is AD + 1. max_int(A, B, A) :- A > B. max_int(A, B, B) :- A =< B. append([], L, L). append([X|L], R, [X|T]) :- append(L, R, T). depth_tree(0, nil). depth_tree(X, tree(_, _, _, X)). plus_tree(X, nil, tree(X, nil, nil, 1)). plus_tree(X, tree(O, L, R, _), Res) :- O >= X, plus_tree(X, L, ResL), diff(ResL, R, Diff, Dep), balance_tree(tree(O, ResL, R, Dep), Diff, Res). plus_tree(X, tree(O, L, R, _), Res) :- O < X, plus_tree(X, R, ResR), diff(L, ResR, Diff, Dep), balance_tree(tree(O, L, ResR, Dep), Diff, Res). %% No rotations balance_tree(Tree, ADiff, Tree) :- ADiff < 2, ADiff > -2. %% Small right rotation balance_tree(tree(A, tree(B, BL, BR, _), AR, _), ADiff, Result) :- ADiff > 1, diff(BL, BR, BDiff, _), BDiff >= 0, construct_tree(A, BR, AR, ASubTree), construct_tree(B, BL, ASubTree, Result). %% Big right rotation balance_tree(tree(A, tree(B, BL, BR, _), AR, _), ADiff, Result) :- ADiff > 1, diff(BL, BR, BDiff, _), BDiff < 0, BR = tree(C, CL, CR, _), construct_tree(B, BL, CL, BSubTree), construct_tree(A, CR, AR, ASubTree), construct_tree(C, BSubTree, ASubTree, Result). %% Small left rotation balance_tree(tree(A, AL, tree(B, BL, BR, _), _), ADiff, Result) :- ADiff < -1, diff(BL, BR, BDiff, _), BDiff =< 0, construct_tree(A, AL, BL, ASubTree), construct_tree(B, ASubTree, BR, Result). %% Big left rotation balance_tree(tree(A, AL, tree(B, BL, BR, _), _), ADiff, Result) :- ADiff < -1, diff(BL, BR, BDiff, _), BDiff > 0, BL = tree(C, CL, CR, _), construct_tree(B, CR, BR, BSubTree), construct_tree(A, AL, CL, ASubTree), construct_tree(C, ASubTree, BSubTree, Result).
      
      





この䟋は、Prologでの実装には十分な衚珟力がありたせんが、䞭芏暡のプログラムのアむデアを提䟛したす。 トレヌニングのために、バブル゜ヌトたたは挿入による゜ヌトを実装できたす。これは読者の裁量に任されおいたす。






䟋5-茞血の問題。



次のタスクずしお、叀兞的な状態の問題を怜蚎しおください;このタスクは、Prologを䜿甚する利点をはるかによく反映しおいたす。 問題の䞀般的な声明氎の入ったいく぀かの容噚がある堎合、茞血によっお特定の容噚に䞀定量の氎を埗るこずが必芁です。 たずえば、容量が12リットル、8リットル、5リットルの氎差しを3぀甚意し、最初の氎差し、぀たり12リットルを完党に満たし、タスクを6リットルに蚭定したす。 たず、ペンず玙でこの孊校の問題を解決しおみおください :)



さたざたなアルゎリズムを生成しおタスクに適甚する前に、たずPrologの芳点から条件を曞き盎したしょう。 容量をsosudId、MaximumCapacity、CurrentCapacityずいう甚語ずしお説明し、システムの状態を容量のリストずしお説明したす。 䟋[sosud1、12、12、sosud2、8、0、sosud3、5、0] 。 次に、リク゚ストに぀いお説明したす。



  %% solve_pr_wo(InitialState, Goal, Steps). :- solve_pr_wo([sosud(1, 12, 12), sosud(2, 8, 0), sosud(3, 5, 0)], sosud(X, _, 6), Steps).
      
      







目暙= sosud_、_、6であるこずに泚意しおください。぀たり、正確に6リットルを含むように、船の容量は重芁ではありたせん。



これですべおがわかったので、ステップがSteps倉数で指定されおいるず仮定しお、゜リュヌションを怜蚌する方法を説明したす。



  %%        , %%        solve_pr_wo(State, Goal, []) :- member(Goal, State). %%      Sosud  Sosud2    %%   ResSosud,   ResSosud2. %%    : %% mv(sosud(1, 12, 12) -> sosud(2, 8, 0), sosud(1, 12, 4) -> sosud(2, 8, 8)). solve_pr_wo(State, Goal, [mv(Sosud -> Sosud2 , ResSosud -> ResSosud2)| Steps]) :- %%     ,    %%           member(Sosud, State), member(Sosud2, State), not(Sosud = Sosud2), %%   ,  %%   4   mv(Sosud, Sosud2, ResSosud, ResSosud2), %%         replace(Sosud, State, ResSosud, State2), replace(Sosud2, State2, ResSosud2, StateX), %%       solve_pr_wo(StateX, Goal, Steps). %%         %% replace(ElementToReplace, InList, ElementToReplaceWith, OutList). replace(S, [S|L], X, [X|L]). replace(S, [T|L], X, [T|Ls]) :- replace(S, L, X, Ls). %%   - 2  %%        %%      mv(sosud(Id1, Max1, Current), sosud(Id2, Max2, Current2), sosud(Id1, Max1, 0), sosud(Id2, Max2, Current3)) :- Current > 0, Current3 is Current2 + Current, Current3 =< Max2. %%        mv(sosud(Id1, Max1, Current), sosud(Id2, Max2, Current2), sosud(Id1, Max1, Current3), sosud(Id2, Max2, Max2)) :- Current > 0, Current3 is Current2 + Current - Max2, Current3 >= 0.
      
      







さらに、茞血の手順が正しい堎合は、それらが説明する内容を確認できないため、ドメむンの怜蚌は必芁ないように思われるかもしれたせん。 実際、怜蚌の完党性は、プログラムが正しく収益を䞊げる可胜性を倧幅に向䞊させたす。 そうは蚀っおも、プログラムを過剰にチェックするず機胜し、堎合によっおは最適化しない堎合よりもさらに最適化されたすが、プログラムのチェックが䞍十分な堎合、完党に誀った結果が生成されたり、䞀郚の入力デヌタでフリヌズしたす。



さお、プログラムの説明が曞かれおいたす-あなたはそれを実行するこずができたす。 プログラムが機胜しないこずに驚かないでください、単にハングしたす:)これは芋た目ほど悪くありたせん。プログラムがハングしなかった堎合、それは正しい答えを䞎えるからです。 なぜハングしたのかを理解する必芁がありたす。ここで、Prologがルヌルを展開しお解決策を芋぀ける方法を理解するのに圹立ちたす。 実際、solve_pr_wo-> solve_pr_woを再垰的に呌び出すたびに、2぀のメンバヌ/ 2぀の述語を呌び出し、垞に同じ1番目ず2番目を生成するこずを理解するために、最倧10個の戻り点を蚘憶できる頭を持぀必芁はありたせん2番目の船述郚はバックトラッキングを匕き起こさず、メンバヌが1番目ず1番目の船を遞択するこずを蚱可したせん。 ぀たり、アルゎリズムは垞に第1から第2に、およびその逆に流れたす。



この䞍条理を解決するために、同じアクションを2回実行するこずを犁止するこず、぀たり、状態の履歎を保持し、条件がすでに満たされおいる堎合は再入力を犁止するこずがすぐに思い浮かびたす。 繰り返しを陀き、倚くの蚱容可胜な茞血戊略を絞り蟌むこずがわかりたした。 実際、戊略のセットを絞り蟌んでも、システムの蚱容可胜な状態のセット、぀たり解法は絞り蟌みたせんが、これは蚌明するこずは難しくありたせん。



状態のリストず゜リュヌションを呌び出す単䞀の述語を含むプログラムのフルバヌゞョン



  write_list([]). write_list([X|L]) :- writeln(X), write_list(L). solution :- solve_pr([sosud(1, 12, 12), sosud(2, 8, 0), sosud(3, 5, 0)], sosud(_, _, 6), [], Steps), write_list(Steps). replace(S, [S|L], X, [X|L]). replace(S, [T|L], X, [T|Ls]) :- replace(S, L, X, Ls). %%       ,     %%     ,   ,     solve_pr(State, Goal, _, [State]) :- member(Goal, State). solve_pr(State, Goal, History, [State|Steps]) :- member(Sosud, State), member(Sosud2, State), not(Sosud = Sosud2), mv(Sosud, Sosud2, ResSosud, ResSosud2), replace(Sosud, State, ResSosud, State2), replace(Sosud2, State2, ResSosud2, StateX), %%%      not(member(StateX, [State|History])), solve_pr(StateX, Goal, [State|History], Steps). %% mv(sosud(_Id, Max, Current), sosud(_Id2, Max2, Current2), ...,...). %%      mv(sosud(Id1, Max1, Current), sosud(Id2, Max2, Current2), sosud(Id1, Max1, 0), sosud(Id2, Max2, Current3)) :- Current > 0, Current3 is Current2 + Current, Current3 =< Max2. %%        mv(sosud(Id1, Max1, Current), sosud(Id2, Max2, Current2), sosud(Id1, Max1, Current3), sosud(Id2, Max2, Max2)) :- Current > 0, Current3 is Current2 + Current - Max2, Current3 >= 0.
      
      







すべおが珟圚機胜しおいたす 挔習ずしお、最適なステップ数で茞血を芋぀けるようにプログラムを倉曎できたす。 これらのタスクを詊すこずができたす。



泚 呜什型プログラミングの熱心なサポヌタヌは、すべおの状態を戻り倀深さのパスで反埩するだけであり、ヒュヌリスティックを䜿甚せずに完党に正しいこずに気付くでしょう。 事実、Prologでの思考は、総圓たりで行うのではなく、問題の説明ず゜リュヌションの怜蚌の説明で行う必芁があり、必芁な堎合は垞に最適化のために蚈算の必須性に戻る必芁がありたす 自然の二重性はマむナスではなく、プラスです。 たた、倧芏暡なPrologシステムは、リタヌンのある状態を怜玢するのに非垞によく適合しおいるこずにも泚意しおください。






おわりに





この蚘事で説明するタスクは、Prologでのプログラミングの研究です。 それらのほずんどは玄10〜15行かかるため、Prologのプログラマは十分な頻床でそれらをメモリから再珟できたす。 そしお、あなたは間違いなくそれらに戻らなければなりたせん。これはプログラミングの技術を思い起こさせるからですCでのクむック゜ヌトのように。 毎日の䜿甚のためのより耇雑で適甚されたタスクに぀いおは、埌で説明したす。



最埌に、賞品にはすでに2぀のタスクがありたす 。

  1. ご存じのように、機胜的および論理的な方法で、あらゆる方法で副䜜甚のあるプログラムを避け、モナドにラップし、特別な抂念を考え出したす。 暙準的な問題は、倖界の問題です。たずえば、ファむルぞのデヌタの曞き蟌み、ファむルぞの蚘録のロヌルバック、゜ケットによる数バむトの送信のキャンセルが䞍可胜であるため、バックトラッキングは正しく機胜したせん。 1぀のアドバむス-これらの目的にPrologを䜿甚しないでください。 しかし、Prologに非垞に適した特定の述語がありたすが、副䜜甚がありたす。 assertasserta、assertzの䟋ルヌルファクトデヌタベヌスに単玔なルヌルファクトを远加したす。 assertprime3の䟋 3が玠数であるずいう事実ずク゚リ-primeXは、゜ヌスプログラムが空であっおも3を返すようになりたした。



    目的  assertの宣蚀バヌゞョンを蚘述したす。぀たり、バックトラッキングプログラムを返すずき、事実はメモリに残しおおくべきではなく、論理的な仮定ずしお機胜する必芁がありたす。



    操䜜䟋 ク゚リcXは、次のプログラムに察しお1぀の数倀4を返す必芁がありたす

      a(X) :- b(Y), X is Y + 1 . c(X) :- my_assert(b(3)), a(X). c(X) :- b(X).
          
          





  2. 2 , — . , . , — , — . , — . , , — .



    : a/1 ( , ), subset_a/1, , a.



    : subset_a(X) X = [], X = [1], X = [2], X = [1, 2] ( ):

      a(1). a(2). subset_a(X) :- ....?
          
          









ご枅聎ありがずうございたした。



All Articles