Related
Here's a code which recursively add the element X at the end of the list.
app(X, [], [X]).
app(X, [Y | S], [Y | S2]) :- app(X, S, S2).
Could anyone explain me how it works? Where's the return statement, what exactly the app(X, S, S2) [Y | S], [Y | S2] do?
You don't need return statement everything is done by unification (simply pattern matching). The clause:
app(X, [Y | S], [Y | S2])
states that the second argument is a list with head Y and tail S and the third argument is a list with head Y and tail S2. So it forces (by using unification) the heads of the two lists to be the same. Recursively the two lists become identical except the fact that the third argument list has one more element in the end (element X) and this is defined by the first clause. Note that second clause only works for lists with one or more elements. So as a base of the recursion when we examine the empty list (in the second parameter) then the third list due to first clause contains only one more element the element X.
Prolog programs are made by defining facts and rules. You define facts and rules, and Prolog interpreter tries to come up with solutions to make them true. Other than this basic concept, you need to know two other important concepts which Prolog programmers use extensively.
These are:
Input and Output parameters: There are no return statements in Prolog. Some variables will be results (outputs) and some others will be the inputs. In your program, the first and second parameters are input and the last one is the output.
Pattern Matching: If a list is expressed as [Head|Tail]. Head is the first element and Tail is a list of the remaining elements.
When you call app, for example, as app(5, [1, 2, 3, 4], L)., Prolog interpreter tries to come up with values for L such that app is true.
Prolog interpreter is solving the problem in the following steps:
In order to make app(X, [Y | S], [Y | S2]) true, the first element of the last parameter need to become Y. So, in my example, L becomes [1, S2].
Then it tries to match the rule app(X, S, S2). Here S is [2, 3, 4] and S2 is the output parameter for the next run. Then Step 1 gets repeated but with app(5, [2, 3, 4], S2) and after that S2 becomes [2, S2]. So, L, now, becomes [1, 2, S2].
This same thing gets repeated (recursion) and L is populated as [1, 2, 3, 4, S2].
Now, the second parameter is empty. So, the first fact app(X, [], [X]) is matched. In order to make this true, the last parameter becomes a list containing just X (which is 5 in this case), which results in L being [1, 2, 3, 4, 5].
In Mathematica:
I would like to pass a variable number of arguments to a function.
I would like to print the name of each argument. The problem is that SymbolName evaluates its input. For a given variable, you can get around this:
a=18;
SymbolName[Unevaluated[a]]
works. But that won't work if the variable is in a list. For example:
printname[x__]:=Print[Table[SymbolName[Unevaluated[{x}[[i]]]],{i,1,Length[{x}]}]];
printname[a,b,c]
will not work. Any suggestions?
Thanks in advance.
Mathematica tries to evaluate the argument of Unevaluated[] when you call it. So {x}[[i]] gets converted into {18, b, c}[[i]] which you didn't want and then the iteration over i doesn't work anymore because Unevaluated[] doesn't let the Table access the iterator.
So, to really solve the issue you should disable Mathematica's evaluation completely for the functions that you want to pass the symbols through.
In[1]:= SetAttributes[SymbolName, HoldAll];
SetAttributes[Map, HoldAll];
After this you can just do
In[2]:= a=18; SymbolName ### Unevaluated /# {a, b, c}
Out[2]:= {a, b, c}
where ### and /# are shorthand for Apply[] and Map[].
Setting Hold[] or similar attributes in Mathematica's built in functions can lead to trouble. See this question and answer in the Mathematica stackexchange for more information.
Specifically, to make a function that takes an arbitrary number of arguments would be
sym = SymbolName ### Unevaluated /# {##} &
But the List[] function that takes the sequence of arguments ## for the function & will again evaluate a and turning HoldAll on for List[] is not OK.
Thus the easiest way to do this is to define a function with HoldAll that just passes the args into a Block[] as the list of local variables. This makes a creates an isolated context where the variables do not evaluate to anything.
In[1]:= SetAttributes[f, HoldFirst];
In[2]:= f[seq__] := Block[{seq}, Print[SymbolName /# {seq}]];
In[3]:= a=18; f[a, b, c]
Out[3]:= {a, b, c}
I have this
initialstate(0,[],[[1,0],[2,3],[1,2],[2,3]]).
I would like to find which sublist inside the list is the same with the number 1.
And after delete the sublist who had the number one.
It would be something like that :
?- initialstate(_,_,[X,_]), initialstate(_,_,list),
delete(list,X,Newlist),assertz(initialstate(A,B,Newlist)).
I know this is wrong but i am trying to explain you what i want to do.
I want my final list to be :
initialstate(0,[],[[2,3],[2,3]]).
Edit: A new answer to incorporate CapelliC's endorsement of delete/3 and OPs further queries in the comments.
Predicate:
initial_state_without_elements(initialstate(A,B,List), Element,
initialstate(A,B,FilteredList) ):-
delete(List, Element, FilteredList).
Query:
?- initial_state_without_elements(initialstate(0,[],[[1,0],[2,3],[1,2],[2,3]]), [2,_], NewState).
NewState = initialstate(0, [], [[1, 0], [1, 2]]).
We want to take some list of lists, ListOfLists, and remove all the sublists, Ls, that contain a given Element. In general, to check if an element X is in some list List, we we can use member(X, List).
So we want a list of lists, SubListsWithout, which contains all Ls of ListOfLists for which member(Element, SubList) is false.
Here is a predicate sublists_without_elements/3, which takes a list of lists, an element, and a variable as arguments, and unifies the variable with a list of the sublists of the first which do not contain the element. This predicate uses the standard recursive technique for describing lists:
sublists_without_element([], _, []).
sublists_without_element([L|Ls], Element, SubListsWithout) :-
member(Element, L), !,
sublists_without_element(Ls, Element, SubListsWithout).
sublists_without_element([L|Ls], Element, [L|SubListsWithout]) :-
sublists_without_element(Ls, Element, SubListsWithout).
The first clause is our base case: the empty list has no sublists, regardless of the element.
The second clause is true if (1) Element is a member of L, and (2) SubListsWithout is a list of the sublists of Ls which do not contain Element. (note: *L has not been added to SubListsWithout in this clause, which means it has been excluded from the lits we are accumulating. The ! is used to prune the search path here, because once we know that an Element is a member of L, we don't want to have anything to do with L again.)
The third clause is true if L is added to SubListsWithout, and SubListsWithout contains the rest of the sublists of Ls which do not have Element as a member.
The above is one way to write your own predicate to filter a list. It is important that you be able to write and read predicates of this form, because you will see tons of them. However, you'll also want to get to know the standard libraries of your Prolog implementation. In SWI-Prolg, you can simply use exclude\3 to accomplish the above task. Thus, you could achieve your desired goal in with the following:
filter_initial_state(initial_state(A,B,List),
Element,
initial_state(A,B,FilteredList)) :-
exclude(member(Element), List, FilteredList).
You can use it thus,
?- filter_initial_state(initial_state(0,[],[[1,0],[2,3],[1,2],[2,3]]), 1, Filtered).
and prolog will reply,
Filtered = initial_state(0, [], [[2, 3], [2, 3]]).
I think you've chosen the right builtin (delete/3), but there is some detail wrong. Here is a working 'query':
?- retract(initialstate(A,B,C)), C=[[X,_]|_], delete(C,[X,_],Newlist), assertz(initialstate(A,B,Newlist)).
A = 0,
B = [],
C = [[1, 0], [2, 3], [1, 2], [2, 3]],
X = 1,
Newlist = [[2, 3], [2, 3]].
First of all: if you do a assertz without first doing a retract you'll end with having an almost duplicate of your data, and probably is not what you want. assertz stores the updated initialstate after the old one (there is asserta, but I doubt will correct the bug).
Second, note how to use pattern matching to extract the essential information:
C=[[X,_]|_]
the use of _ (i.e. an anonymous var) is essential, because allows to specify which part of the complex structure we must ignore when using it. And we must use it also to indicate to delete/3 what to match.
delete(C,[X,_],Newlist)
I am wondering how to get a nice proper looking list with the elements I have! I've been trying to look up stuff on this but none of the actual examples I've found seem to actually work
Here is one method I found on the web:
create_list(Item, List, [Item|List]).
if I run this query:
Hi = [1,2], Hey = [3,4], create_list(Hi, Hey, Output).
The result gets weird:
Output = [[1,2], 3,4]
The brackets are all wrong!
It should be:
[[1,2], [3,4]]
The brackets are all wrong! It should be:
[[1,2], [3,4]]
This is because your create_list uses [Item|List]. If you wanted brackets around [3,4] to remain in place, replace [Item|List] with [Item,List]. Of course List has incorrect meaning now, so I would rename it, as follows:
list_of_two(First, Last, [First, Last]).
This would not work for more than two items, however. Your original one rule would work, like this:
create_list([1,2],[],O1), create_list([3,4],O1,O2), create_list([5,6],O2,O3).
This produces
[[5, 6], [3, 4], [1, 2]]
in the O3 list.
In contrast with other languages, a list is a very basic datastructure in Prolog:
[] is/creates an empty list
[1] is/creates a list with a single element
[1,2,3,4,....,n] is/creates a list with n elements
[1|[2,3,4]] is/creates a list by inserting 1 in the list [2,3,4] (the result is [1,2,3,4])
So, you don't need a predicate to "create" a list: if you have n elements just put them in brackets; if the elements are generated recursively, use | to create a list with the new element. For example:
put_in_list(A1,A2,A3, L):- L = [A1,A2,A3].
alternatively:
put_in_list(A1,A2,A3, [A1,A2,A3]).
also:
generate(0, []).
generate(N, [ [N, NN]| Rest ]):-
NN is N-1,
NNN is N-2,
generate(NNN, Rest).
All in all, you should be careful with types; in your case, you have a list of numbers (let's call it X) and you want a list of lists of numbers (so this would be a list of Xs). The problem was created when you gave a list of Xs as an argument instead of an X to a predicate.
I would like to be able to have a pattern that matches only expressions that are (alternately: are not) children of certain other elements.
For example, a pattern to match all Lists not within a Graphics object:
{ {1,2,3}, Graphics[Line[{{1,2},{3,4}}]] }
This pattern would match {1,2,3} but not {{1,2},{3,4}}.
There are relatively easy ways to extract expressions matching these criteria, but patterns are not only for extraction, but also for replacement, which is my main use case here (ReplaceAll).
Do you know of any easy, concise, and general ways to do this?
Is it possible to do this at all with just patterns?
I will propose a solution based on expression pre-processing and soft redefinitions of operations using rules, rather than rules themselves. Here is the code:
ClearAll[matchChildren, exceptChildren];
Module[{h, preprocess},
preprocess[expr_, parentPtrn_, lhs_, match : (True | False)] :=
Module[{pos, ptrnPos, lhsPos},
ptrnPos = Position[expr, parentPtrn];
lhsPos = Position[expr, lhs];
pos = Cases[lhsPos, {Alternatives ## PatternSequence ### ptrnPos, __}];
If[! match,pos = Complement[Position[expr, _, Infinity, Heads -> False], pos]];
MapAt[h, expr, pos]];
matchChildren /:
fun_[expr_, matchChildren[parentPtrn_, lhs : Except[_Rule | _RuleDelayed]],
args___] :=
fun[preprocess[expr, parentPtrn, lhs, True], h[lhs], args] //.
h[x_] :> x;
matchChildren /:
fun_[expr_, matchChildren[parentPtrn_, lhs_ :> rhs_], args___] :=
fun[preprocess[expr, parentPtrn, lhs, True], h[lhs] :> rhs, args] //.
h[x_] :> x;
exceptChildren /:
fun_[expr_,exceptChildren[parentPtrn_, lhs : Except[_Rule | _RuleDelayed]],
args___] :=
fun[preprocess[expr, parentPtrn, lhs, False], h[lhs], args] //.
h[x_] :> x;
exceptChildren /:
fun_[expr_, exceptChildren[parentPtrn_, lhs_ :> rhs_], args___] :=
fun[preprocess[expr, parentPtrn, lhs, False], h[lhs] :> rhs, args] //.
h[x_] :> x;
]
A few details on implementation ideas, and how it works. The idea is that, in order to restrict the pattern that should match, we may wrap this pattern in some head (say h), and also wrap all elements matching the original pattern but also being (or not being) within some other element (matching the "parent" pattern) in the same head h. This can be done for generic "child" pattern. Technically, one thing that makes it possible is the intrusive nature of rule application (and function parameter-passing, which have the same semantics in this respect). This allows one to take the rule like x_List:>f[x], matched by generic pattern lhs_:>rhs_, and change it to h[x_List]:>f[x], generically by using h[lhs]:>rhs. This is non-trivial because RuleDelayed is a scoping construct, and only the intrusiveness of another RuleDelayed (or, function parameter-passing) allows us to do the necessary scope surgery. In a way, this is an example of constructive use of the same effect that leads to the leaky functional abstraction in Mathematica. Another technical detail here is the use of UpValues to overload functions that use rules (Cases, ReplaceAll, etc) in the "soft" way, without adding any rules to them. At the same time, UpValues here allow the code to be universal - one code serves many functions that use patterns and rules. Finally, I am using the Module variables as a mechanism for encapsulation, to hide the auxiliary head h and function preprocess. This is a generally very handy way to achieve encapsulation of both functions and data on the scale smaller than a package but larger than a single function.
Here are some examples:
In[171]:= expr = {{1,2,3},Graphics[Line[{{1,2},{3,4}}]]};
In[168]:= expr/.matchChildren[_Graphics,x_List:>f[x]]//FullForm
Out[168]//FullForm= List[List[1,2,3],Graphics[Line[f[List[List[1,2],List[3,4]]]]]]
In[172]:= expr/.matchChildren[_Graphics,x:{__Integer}:>f[x]]//FullForm
Out[172]//FullForm= List[List[1,2,3],Graphics[Line[List[f[List[1,2]],f[List[3,4]]]]]]
In[173]:= expr/.exceptChildren[_Graphics,x_List:>f[x]]//FullForm
Out[173]//FullForm= List[f[List[1,2,3]],Graphics[Line[List[List[1,2],List[3,4]]]]]
In[174]:= expr = (Tan[p]*Cot[p+q])*(Sin[Pi n]+Cos[Pi m])*(Tan[q]+Cot[q]);
In[175]:= expr/.matchChildren[_Plus,x_Tan:>f[x]]
Out[175]= Cot[p+q] (Cot[q]+f[Tan[q]]) (Cos[m \[Pi]]+Sin[n \[Pi]]) Tan[p]
In[176]:= expr/.exceptChildren[_Plus,x_Tan:>f[x]]
Out[176]= Cot[p+q] f[Tan[p]] (Cos[m \[Pi]]+Sin[n \[Pi]]) (Cot[q]+Tan[q])
In[177]:= Cases[expr,matchChildren[_Plus,x_Tan:>f[x]],Infinity]
Out[177]= {f[Tan[q]]}
In[178]:= Cases[expr,exceptChildren[_Plus,x_Tan:>f[x]],Infinity]
Out[178]= {f[Tan[p]]}
In[179]:= Cases[expr,matchChildren[_Plus,x_Tan],Infinity]
Out[179]= {Tan[q]}
In[180]:= Cases[expr,matchChildren[_Plus,x_Tan],Infinity]
Out[180]= {Tan[q]}
It is expected to work with most functions which have the format fun[expr_,rule_,otherArgs___]. In particular, those include Cases,DeleteCases, Replace, ReplaceAll,ReplaceRepeated. I did not generalize to lists of rules, but this should be easy to do. It may not work properly in some subtle cases, e.g. with non-trivial heads and pattern-matching on heads.
According to your explanation in the comment to the acl's answer:
Actually I'd like it to work at any
level in the expression <...>. <...>
what I need is replacement: replace
all expression that match this
"pattern", and leave the rest
unchanged. I guess the simplest
possible solution is finding the
positions of elements, then using
ReplacePart. But this can also get
quite complicated in the end.
I think it could be done in one pass with ReplaceAll. We can rely here on the documented feature of the ReplaceAll: it does not look at the parts of the original expression which were already replaced even if they are replaced by themselves! Citing the Documentation: "ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part, or on any of its subparts."
Here is my solution (whatIwant is what you want to do with matched parts):
replaceNonChildren[lst_List] :=
ReplaceAll[#, {x_List :> whatIwant[x], y_ :> y}] & /# lst
Here is your test case:
replaceNonChildren[{{1, 2, 3}, Graphics[Line[{{1, 2}, {3, 4}}]]}] // InputForm
=> {whatIwant[{1, 2, 3}], Graphics[Line[{{1, 2}, {3, 4}}]]}
Here is a function that replaces only inside certain head (Graphics in this example):
replaceChildren[lst_List] :=
ReplaceAll[#, {y : Graphics[__] :> (y /. x_List :> whatIwant[x])}] & /# lst
Here is a test case:
replaceChildren[{{1, 2, 3}, Graphics[Line[{{1, 2}, {3, 4}}]]}] // InputForm
=> {{1, 2, 3}, Graphics[Line[whatIwant[{{1, 2}, {3, 4}}]]]}
You might write a recursive function that descends an expression tree and acts on the types of expression you want only if inside the right type of sub-expression, while leaving everything else alone. Patterns would be used heavily in the definition of the function.
Consider, for example, the following expression.
test = {{1, 2}, Graphics[{
Point[{{-1, 0}, {1, 0}}],
Line[{{-1, 0}, {1, 0}}]},
Frame -> True,
PlotRange -> {{-1, 1}, {-0.5, 0.5}}]};
Let's suppose that we want to rotate every ordered pair that we see in the first argument of Graphics about the origin through the angle Pi/4, while leaving other points alone. The following function does this.
Clear[f];
f[{x_?NumericQ, y_?NumericQ}] := If[flag === True,
RotationMatrix[Pi/4].{x, y}, {x, y}];
f[Graphics[primitives_, rest___]] := Block[{flag = True},
Graphics[f[primitives], rest]];
f[x_?AtomQ] := x;
f[x_] := f /# x;
Now we check
f[test]
I am probably misunderstanding you, but, if I do understand correctly you want to match all expressions with head List which have the property that, going upwards in the expression tree, we'll never meet a Graphics. I m not sure how to do this in one pass, but if you are willing to match twice, you can do something like
lst = {randhead[5], {1, 2, {3, 5}}, Graphics[Line[{{1, 2}, {3, 4}}]]};
Cases[#, _List] &#Cases[#, Except#Graphics[___]] &#lst
(*
----> {{1, 2, {3, 5}}}
*)
which first selects elements so that the Head isn't Graphics (this is done by Cases[#, Except#Graphics[___]] &, which returns {randhead[5], {1, 2, {3, 5}}}), then selects those with Head List from the returned list. Note that I've added some more stuff to lst.
But presumably you knew this and were after a single pattern to do the job?