1 / 11

Prolog Program Style ( ch . 8)

Prolog Program Style ( ch . 8). Many style issues are applicable to any program in any language. Some Prolog specifics: short clauses, predicates If meaning in comments must use “and”, then break into separate preds . meaningful names for predicates, constants , variables

una
Télécharger la présentation

Prolog Program Style ( ch . 8)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Prolog Program Style (ch. 8) • Many style issues are applicable to any program in any language. • Some Prolog specifics: • short clauses, predicates • If meaning in comments must use “and”, then break into separate preds. • meaningful names for predicates, constants, variables • helps programmer understand the meaning of their code • good indentation • use the same conventions throughout program • cuts: use green cuts rather than red • if possible, use not, one, -> instead of cuts • try to avoid assert/retract unless absolutely required • be careful to restore program state (database) when necessary • comments: • I/O convention of predicates • essentials of algorithm • special features, shortcomings, assumptions about input, ...

  2. Efficiency issues • Declarative vs procedural • a difficult balance: clearest solutions can be the most inefficient • sometimes must encode a clear solution efficiently, using procedural considerations • Algorithm vs implementation • a quicksort is faster than a bubble sort, no matter how you implement it! • A fast algorithm can be implemented inefficiently, however. • Data structures • related to algorithms • a better data structure can naturally result in a faster implementation • eg. a sorted binary tree permits faster data extraction than an unsorted linear list • Nondeterminism vs determinism • reduce backtracking: avoid needless searching: once, if-then-else, cuts • Backtracking requires extra memory. • consult vs compile • depending on implementation, compiling programs can give upwards of a 10x speed increase • (lose debugging info, however)

  3. Memory and recursion • recursion requires memory • stack used to save tree for return • extra usage for backtracking... p(...) :- do_things(...), % Memory used here to do_more_things(...), % save tree for backtracking. p(...). % Recursion. • This is an examples of tail recursion: last goal is recursive call, and goals before it are deterministic (backtracking will fail). • To optimize, do this: p(...) :- do_things(...), do_more_things(...), !, % This throws away tree before call. p(...). % Recursion.

  4. Efficiency: memory • This can still cause problems in very large computations. Sometimes, various memory usage before the cut can be enormous. • Some Prologs such as Sicstus have a builtin memory management optimizer called “garbage_collect” • garbage collection important for symbolic languages (and Java!): finds unused memory (eg. unused atoms, freed clauses, etc.), and puts it back on heap for later usage • done automatically at periodic times. Unfortunately, might not happen when required! • calling garbage_collect lets programmer ensure of optimal memory use p(...) :- do_things(...), garbage_collect, do_more_things(...), garbage_collect, !, % this throws away tree before call p(...). % recursion

  5. Last-clause determinacy COSC 2P93 Prolog: Lisp • Sicstus compiler will automatically “insert” a cut into the first goal of the last clause of a recursive predicate. • So this is not required... p(...) :- ... p(...) :- % last clause of p. !, %  unnecessary! (do something), p(...).

  6. Efficiency: execution profiling Profile: run-time execution statistics See sect. 9.2, Sicstus manual Scheme: ?- [Load some code.] ?- prolog_flag(profiling,_,on). ?- [Run some queries.] ?- prolog_flag(profiling,_,off). ?- print_profile.

  7. Profiling COSC 2P93 Prolog: Lisp ?- print_profile. insns try/retry called name ---------------------------------------------------------------- *13694/14300 user:remove_nth/4 ← callers: remove_nth 13694 times *606/14300 user:select_random/3 ← select_random 606 times 97676 606 *14300 user:remove_nth/4 ← remove_nth called 14300 times *13694/14300 user:remove_nth/4 ← called preds: remove_nth 13694 times ---------------------------------------------------------------- *101/5050 user:lotto649/1 *4949/5050 user:make_intlist/3 74841 9999 *5050 user:make_intlist/3 *4949/5050 user:make_intlist/3 ---------------------------------------------------------------- *101/2027 user:lotto_loop/9 *1926/2027 user:writelist/1 18417 6474 *2027 user:writelist/1 *1926/2027 user:writelist/1 -- etc

  8. Efficiency: determinism • Nondeterminacy: multiple solutions via backtracking • a major feature of Prolog: search • also a source of inefficiency when multiple solutions not needed • possible to get erroneous solns on backtracking as well • SicstusPrologindexes clauses based on first argument • a hash table created, with first arg value as hash key • interpreter will very quickly unify a call with its “hashed” clause; no need for unification on inappropriate calls. • But if a clause has a variable 1st arg, this won’t work • When possible, make predicates determinate • each clause takes care of one case, given in 1st arg • Result: • faster execution • less memory usage

  9. Example: determinism COSC 2P93 Prolog: Lisp % make integer list... intlist(N, L) :- N > 0, make_intlist(0, N, L). make_intlist(M, N, [ ]) :- M > N. make_intlist(M, N, [M|L2]) :- M =< N, M2 is M+1, make_intlist(M2, N, L2). Notice how 1starg to make_intlist/3 is variable. So Prolog must use inefficient unification to match calls with clauses.

  10. Determinism COSC 2P93 Prolog: Lisp intlist(N, L) :- N > 0, make_intlist(L, 0, N). make_intlist([ ], M, N) :- M > N. make_intlist([M|L2], M, N) :- M =< N, M2 is M+1, make_intlist(L2, M2, N). Here, we’ve moved 3rdarg (solution list) to 1st position. This version is faster: calls to make_intlist can be resolved instantly using 1st argument value.

  11. Determinacy checker COSC 2P93 Prolog: Lisp command: spdetfile_name If we call it on “inefficient” make_intlist... * Non-determinate: user:make_intlist/3 (clause 1) * Indexing cannot distinguish this from clause 2. spdet –D (file) will also generate declarations to use... :- nondetuser:make_intlist/3.

More Related