Hi hopefully someone can help me. I was just wondering if my code below was sufficient in setting up a matrix of 12 x 12 and, assuming the 'constrain(M)' calls all the correct constraints which are defined in rules lower down, labelling each of the rows? It's failing at the moment and I've traced my constraints so I know they all work but didn't know whether it was because I'm calling them outside of the main predicate?
matrix(M) :-
M = [R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
R1 = [A,B,C,D,E,F,G,H,I,J,K,L],
R2 = [A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2],
R3 = [A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3],
R4 = [A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4],
R5 = [A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5],
R6 = [A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6],
R7 = [A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7],
R8 = [A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8],
R9 = [A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9],
R10 = [A10,B10,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10],
R11 = [A11,B11,C11,D11,E11,F11,G11,H11,I11,J11,K11,L11],
R12 = [A12,B12,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12],
constrain(M),
labeling([],R1),
labeling([],R2),
labeling([],R3),
labeling([],R4),
labeling([],R5),
labeling([],R6),
labeling([],R7),
labeling([],R8),
labeling([],R9),
labeling([],R10),
labeling([],R11),
labeling([],R12).
You should always separate the constraint posting from the actual search (labeling/2).
The reason is clear: It can often be extremely expensive to search for concrete solutions. Posting the constraints, on the other hand, is often very fast.
If, as in your case, the two parts are uncleanly mixed, you cannot tell easily which part is responsible if there are unexpected problems such as nontermination.
In your case, the only thing you should improve in the main predicate is enforcing said separation between constraint posting and search.
The mistake that causes unexpected failure is most likely contained in one of the rules you did not post here. You can find out which rules are involved in the failure by systematically replacing the goals in which they are called by true. Thus, there's no need for tracing: You can debug CLP(FD) programs declaratively in this way.
EDIT: Here is more information about the separation between posting constraints and the search for concrete solutions. As introduced in GUPU, we will use the notion of core relation, which has the following properties:
By convention, its name ends with an underscore _.
Also by convention, its last argument is the list of variables that need to be labeled.
It posts the CLP(FD) constraints. This is also called the (constraint) modeling part or (constraint) model.
It doesn't use labeling/2.
The search part is usually performed by label/1 or labeling/2.
Suppose you have a predicate where you intermingle these two aspects, such as in your current case:
matrix(M) :-
constraints_hold(M),
... relate M to variables Vs ...
labeling(Strategy, Vs).
Obviously, for the reasons explained above, the call of labeling/2 is the part we want to remove from this predicate. Of course, as you observe, we still want to somehow access the variables that are supposed to be labeled.
We do this as follows:
We introduce a new argument to the core relation to pass around the list of finite domain variables that need to be labeled.
By convention, we reflect the additional argument by appending an underscore (_) to the predicate name.
So, we obtain the following core relation:
matrix_(M, Vs) :-
constraints_hold(M),
... relate M to variables Vs ...
The only missing part (which you haven't done yet, but which you should have done in any case), is stating the relation between the object of interest (in this case: the matrix) and the finite domain variables. This is the part I leave as a simple exercise for you. Hint: append/2.
Once you have done all this, you can solve the whole task by combining the core relation and labeling/2 in a single query or predicate:
?- matrix_(M, Vs), labeling(Strategy, Vs).
Note that this separation between core relation and search:
makes it extremely easy to try different labeling strategies without recompiling your program.
allows you to determine important procedural properties of the core relation without needing to search for concrete solutions.
Use the introduction and explanation of this important separation as an indicator when judging the quality of any text about CLP(FD) constraints.
Sometimes the value of a variable accessed within the control-flow of a program cannot possibly have any effect on a its output. For example:
global var_1
global var_2
start program hello(var_3, var_4)
if (var_2 < 0) then
save-log-to-disk (var_1, var_3, var_4)
end-if
return ("Hello " + var_3 + ", my name is " + var_1)
end program
Here only var_1 and var_3 have any influence on the output, while var_2 and var_4 are only used for side effects.
Do variables such as var_1 and var_3 have a name in dataflow-theory/compiler-theory?
Which static dataflow analysis techniques can be used to discover them?
References to academic literature on the subject would be particularly appreciated.
The problem that you stated is undecidable in general,
even for the following very narrow special case:
Given a single routine P(x), where x is a parameter of type integer. Is the output of P(x) independent of the value of x, i.e., does
P(0) = P(1) = P(2) = ...?
We can reduce the following still undecidable version of the halting problem to the question above: Given a Turing machine M(), does the program
never stop on the empty input?
I assume that we use a (Turing-complete) language in which we can build a "Turing machine simulator":
Given the program M(), construct this routine:
P(x):
if x == 0:
return 0
Run M() for x steps
if M() has terminated then:
return 1
else:
return 0
Now:
P(0) = P(1) = P(2) = ...
=>
M() does not terminate.
M() does terminate
=> P(x) = 1 for a sufficiently large x
=> P(x) != P(0) = 0
So, it is very difficult for a compiler to decide whether a variable actually does not influence the return value of a routine; in your example, the "side effect routine" might manipulate one of its values (or even loop infinitely, which would most definitely change the return value of the routine ;-)
Of course overapproximations are still possible. For example, one might conclude that a variable does not influence the return value if it does not appear in the routine body at all. You can also see some classical compiler analyses (like Expression Simplification, Constant propagation) having the side effect of eliminating appearances of such redundant variables.
Pachelbel has discussed the fact that you cannot do this perfectly. OK, I'm an engineer, I'm willing to accept some dirt in my answer.
The classic way to answer you question is to do dataflow tracing from program outputs back to program inputs. A dataflow is the connection of a program assignment (or sideeffect) to a variable value, to a place in the application that consumes that value.
If there is (transitive) dataflow from a program output that you care about (in your example, the printed text stream) to an input you supplied (var2), then that input "affects" the output. A variable that does not flow from the input to your desired output is useless from your point of view.
If you focus your attention only the computations involved in the dataflows, and display them, you get what is generally called a "program slice" . There are (very few) commercial tools that can show this to you.
Grammatech has a good reputation here for C and C++.
There are standard compiler algorithms for constructing such dataflow graphs; see any competent compiler book.
They all suffer from some limitation due to Turing's impossibility proofs as pointed out by Pachelbel. When you implement such a dataflow algorithm, there will be places that it cannot know the right answer; simply pick one.
If your algorithm chooses to answer "there is no dataflow" in certain places where it is not sure, then it may miss a valid dataflow and it might report that a variable does not affect the answer incorrectly. (This is called a "false negative"). This occasional error may be satisfactory if
the algorithm has some other nice properties, e.g, it runs really fast on a millions of code. (The trivial algorithm simply says "no dataflow" in all places, and it is really fast :)
If your algorithm chooses to answer "yes there is a dataflow", then it may claim that some variable affects the answer when it does not. (This is called a "false positive").
You get to decide which is more important; many people prefer false positives when looking for a problem, because then you have to at least look at possibilities detected by the tool. A false negative means it didn't report something you might care about. YMMV.
Here's a starting reference: http://en.wikipedia.org/wiki/Data-flow_analysis
Any of the books on that page will be pretty good. I have Muchnick's book and like it lot. See also this page: (http://en.wikipedia.org/wiki/Program_slicing)
You will discover that implementing this is pretty big effort, for any real langauge. You are probably better off finding a tool framework that does most or all this for you already.
I use the following algorithm: a variable is used if it is a parameter or it occurs anywhere in an expression, excluding as the LHS of an assignment. First, count the number of uses of all variables. Delete unused variables and assignments to unused variables. Repeat until no variables are deleted.
This algorithm only implements a subset of the OP's requirement, it is horribly inefficient because it requires multiple passes. A garbage collection may be faster but is harder to write: my algorithm only requires a list of variables with usage counts. Each pass is linear in the size of the program. The algorithm effectively does a limited kind of dataflow analysis by elimination of the tail of a flow ending in an assignment.
For my language the elimination of side effects in the RHS of an assignment to an unused variable is mandated by the language specification, it may not be suitable for other languages. Effectiveness is improved by running before inlining to reduce the cost of inlining unused function applications, then running it again afterwards which eliminates parameters of inlined functions.
Just as an example of the utility of the language specification, the library constructs a thread pool and assigns a pointer to it to a global variable. If the thread pool is not used, the assignment is deleted, and hence the construction of the thread pool elided.
IMHO compiler optimisations are almost invariably heuristics whose performance matters more than effectiveness achieving a theoretical goal (like removing unused variables). Simple reductions are useful not only because they're fast and easy to write, but because a programmer using a language who understand basics of the compiler operation can leverage this knowledge to help the compiler. The most well known example of this is probably the refactoring of recursive functions to place the recursion in tail position: a pointless exercise unless the programmer knows the compiler can do tail-recursion optimisation.
I'm creating several puzzle solvers in Prolog SWI with CHR (Constraint Handling Rules)
Everything works great but, I like to test which solver is best one.
Therefore I like to find out, which solver uses the least amount of backtracks.
Is there a clever way to find out (or print out), the amount of backtracks that the solver had needed for solving a particular puzzle?
Logically, counting would help, but it doesn't --> backtracking ! <-- .
Also, printing a new line on the screen isn't effective, because of SWI's GUI. You can't print more than +/- 50 lines and can't select properly
It is indeed not trivial to accomplish this, given Constraint Handling Rules maintain a 'constraint store' and execution of rules may add, rewrite or remove rules from this store at runtime. This changes the state of the program and makes it somewhat difficult to keep track of global states throughout execution.
However, since CHR is integrated in SWI, you can make use of the non-logical operation nb_setarg/3 to keep count of the backtracks.
Notes from the doc:
Compatible with GNU-Prolog's setarg(A,T,V,false)
This implementation is thread-safe, reentrant and capable of handling exceptions
EDIT
As regarding where to count the backtracks, this of course depends on your program, but will usually occur in the CHR constraint rule that defines the fail condition of your search, allowing it to 'branch' (= rewrite CHR rules). Every time a rewrite of the constraint store occurs during search, it represents a backtrack and you can increase a counter accordingly using the operation as defined above.
Consider a small, abstract example:
invalid_state ==> increment_backtracks, fail.
guess <=> branch
I have a homework assignment, and i am finished other then one question (see title)
For the life of my, i cannot figure this out... so i started to think it was a trick question.
the current answer that i will submit is:
L1 = {a^n b^n: n>=1} is deterministic. And the reverse,
L2 = {b^n a^n: n>=1} is also deterministic.
However, since all deterministic languages are a subset of Non-deterministic languages, L2 can be considered non-deterministic.
On a side note, the only other example i was trying to make work is:
L3= {{a,b}a}
This seems possible because forward there is non-determinism, since the input could be either a, or b as long as its followed by an a.
and in reverse there is determinism since it will accept only an 'a'. But, it introduces new non-determinism since the second input could be either a or b.
any help / guidance would be great.
I know the deadline has passed, but somebody might find this useful in the future.
(a+b+c)*WcW^R, where W is in (a+b)+; this is non-deterministic because you don't know where the "WcW" bit starts.
W^RcW(a+b+c)*, where W is in (a+b)+; this is deterministic because you can write a deterministic PDA to accept simple palindromes of the form "W^RcW" and modify the accepting state to loop to itself on any of a, b and c.
The trick here is that PDAs have to read input from left to right.
I need to write something like circular buffer in TurboProlog 2.0 for calculating average. I don't know what predicates i need to write, and have no idea how link them together.
I'm not sure what functionality of "a circular buffer" needs to be realized for your application. In general a "buffer" would be reusable storage, often associated with I/O processes that handle asynchronous communications (hence the need for a buffer that allows one process to get ahead of the other). A "circular buffer" denotes a way of managing the available storage with pointers (both to the beginning and end of valid/unprocessed data) that wraparound through a (linear) contiguous region. This has an advantage over maintaining a FIFO queue with a fixed location for the beginning of valid data because no "shuffling" of unprocessed items is required.
In the general context of standard Prolog, where rewriting memory locations is not directly supported, that advantage doesn't make sense. Even in Turbo Prolog it has to be asked exactly what you want to accomplish, so that a skillful use of the extended/nonstandard features available can be made.
Here are some ideas:
Turbo Prolog supports lists that are in some ways more restrictive and perhaps in other ways more elaborate than the proper lists of standard Prolog. One of the restrictions is that in Turbo Prolog all items of a list must belong to the same "domain", a notion foreign to the weakly-typed character of standard Prolog. Also domains may be designated as "reference" domains in Turbo Prolog, a level of indirection that permits partially bound compound terms to be passed between subgoals. Without going into too much detail, one sense of "circular buffer" might be a "list" (formed from a reference domain) which wraps back around on itself (a cyclical reference). Such a term can be created in many other Prologs, the distinction being that it is not a proper list. Circular though such a term might be, it would not be much of a buffer (once created) because items in the list could not be rewritten.
Turbo Prolog supports dynamic assertion and retraction of facts, with metapredicates like asserta/1 and assertz/1 that allow serial positioning of new facts at the beginning or the end of those existing facts for the same predicate (and also if desired within a specified named "module" or factbase to use the Turbo Prolog terminology). If the simple management of items in a FIFO queue is your objective, then this is most likely the approach you want (at least for an initial implementation), with items encapsulated as facts.
Turbo Prolog also supports "external" factbases with some additional features, external in the sense of being stored (either in memory or on disk) in a way that allows persistence and expanded space beyond what is allocated for internal factbases. Given the modest fixed sizes usually associated with circular buffers (because they are meant for reuse and overflow is usually dealt with by blocking on the input process until the output process has a chance to catch up), external factbases don't seem to offer much of interest, though possibly the ability to persist "buffers" might be of interest for long-running processes.
Hopefully these suggestions will elicit some clarification on what really needs to be accomplished here.
After much thought, was written the following program
% Consumer predicate. If buffer is empty, nothing to take, need to wait for producer predicate.
consumer(BufferBefore, [], _) :-
length(BufferBefore, BuffSize),
BuffSize = 0,
write("Buffer is empty. Waiting for producer"), nl, !, fail.
% If the buffer is not empty, returns first element and removes them from the buffer
consumer(BufferBefore, BufferAfter, Result) :-
car(BufferBefore, Result),
deletefirst(BufferBefore, BufferAfter).
% Producer predicate. If data and buffer is empty, nothing taken from the data to put in buffer.
producer([], [], [], [], _) :- write("End of data!."), !, fail.
% Else if buffer is not empty, add first elem from data (and removes them from here) to last position in buffer.
producer(DataBefore, BufferBefore, DataAfter, BufferAfter, Size) :-
length(BufferBefore, BuffSize), BuffSize < Size, !,
car(DataBefore, Elem),
addlast(Elem, BufferBefore, BufferAfter),
deletefirst(DataBefore, DataAfter).
Several examples of running
consumer([1,2,3,4,5], BufferAfter, Result)
returns
BufferAfter = [2,3,4,5], Result = 1.
And
producer([1,2,3,4,5,6],[7,8,9],DataAfter, BufferAfter, %">3 here"%)
returns
DataAfrer = [2,3,4,5,6], BufferAfter = [7,8,9,1].
Now, to demonstrate any calculation, we need to write a program that, which will run "consumer" until the buffer is empty will be. And "consumer" will run "producer", when buffer is empty. And stop the process, when data and buffer will be empty.
Hope will be useful to anyone.