I need (for design choices) to obtain a list who respects the following pattern:
Uses = ['foo\/1', 'foobar\/2'].
I'm able to build up the
name/number pattern
doing:
all((P\/A), (rule(X, Ux, _, Module), member(U, Ux), U = (P/A)), Uses).
where rule is an internal fact and Ux is a list.
I can escape slashes easily, using the '/' shortcut, but what about putting (P/A) between quotes?
How do that? please help me.
If you want to obtain 'foo/1', you can easily use atomic_list_concat/2 predicate as follows:
Functor=foo,
Arity=1,
atomic_list_concat([Functor, '/', Arity], Output).
In this way Output variable will be bound to 'foo/1' term.
Just put them between 3 apexes:
?- A=foo, B=1, writeln('''A/B''').
'A/B'
A = foo,
B = 1
Related
I´m making a one bit addition:
sumbit(CIN,A,B,CO,R):- ...
?- sumbit(0
,1
,1
,CO
,R)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(CO),write(R),nl.
What I want to do is to print the variable values of CIN,A,B,CO and R.
It should come out something like this:
0
1
+
1
--
10
Instead it comes out as this:
_40
_73
+
_149
--
10
Yes.
Also is there a way to not print the "Yes"?
I´m using strawberry prolog if it helps.
Thank you in advance
One way to achieve that without altering your predicate definition is to tweak the query, like so:
?- [CIN, A, B] = [0, 1, 1]
,sumbit(CIN
,A
,B
,CO
,R)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(CO),write(R),nl.
Now all variables are instantiated, either by the call itself, or prior to the call.
When a variable is not instantiated, there's no value to print, so its "name" is printed instead. But since non-used name has no meaning in itself, it can be freely renamed by the system to anything. In SWI Prolog:
1 ?- write(A).
_G1338
true.
The renaming is usually done, as part of the Prolog problem solving process, to ensure that any two separate invocations of the same predicate do not interfere with each other.
So where SWI Prolog uses names like _G1338, the Prolog implementation you're using evidently uses names with the numbers only, after the underscore, like _40.
I found an answer by putting the write() inside the sumbit(...) predicate:
sumbit(CIN,A,B,CO,R):-
xor_(A,B,R1)
,and(A,B,R2)
,xor_(R1,CIN,R)
,and(R1,CIN,R4)
,or(R2,R4,CO)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(R),nl.
There are still some unanswered questions though:
is there a way to not print the "Yes"?
what was the _number that came out before?
Mathematica has a bevy of useful functions (Solve, NDSolve, etc.). These functions output in a very strange manner, ie {{v -> 2.05334*10^-7}}. The major issue is that there does not appear to be any way to use the output of these functions in the program; that is to say all of these appear to be terminal functions where the output is for human viewing only.
I have tired multiple methods (Part, /., etc.) to try to get the output of functions into variables so the program can use them for further steps, but nothing works. The documentation says it can be done but nothing they list actually functions. For example, if I try to use /. to move variables, it continues to treat the variable I assigned to as empty and does symbolic math with it instead of seeing the value. If I try to access the variable ie [[1]], it says the variable is not that deep.
The only method I have found is to put the later steps in separate blocks and copy-paste the output to continue evaluation. Is there any way to get the output of these functions into variables programmatically?
Solve etc. produce a list of replacement rules. So you need to apply these rules to the pattern to be replaced. For instance
solutions = x /. Solve[x^2 == 3, x]
gives you all the solutions in a list.
Here is a quick way to get variable names for the solutions:
x1 = solutions[[1]]
x2 = solutions[[2]]
Here is what I have understood about Prolog variables.
A single underscore stands for anonymous variable, which is like a new variable each time it occurs.
A variable name starting with underscore like _W is not an anonymous variable. Or, the variable names generated inside Prolog, like _G189, is not considered anonymous:
?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
Could you please help me understand?
By the way, I got the above example from some tutorials, but when I run it in SWI-Prolog version 6, I get the following:
?- append([1,2],X,Y).
Y = [1, 2|X].
Thanking you.
Variables
The anonymous variable _ is the only variable where different occurrences represent different variables. Other variables that start with _ are not anonymous. Different occurrences refer to the same variable (within the same scope). However, many Prologs like SWI will warn you should a variable not starting with an underscore occur only once:
?- [user].
a(V).
Warning: user://1:9:
Singleton variables: [V]
You have to rename that variable to _V to avoid that warning. This is a help for programmers to better spot typos in variable names. There are some more such restrictions in many systems.
a(_V,_V).
Warning: user://1:12:
Singleton-marked variables appearing more than once: [_V]
Again, this is only a warning. If you want that a variable starting with _ should occur twice (without warning), write __ instead. But better stick to more meaningful names without a starting _.
Answers
What you get from Prolog's top level loop are answers ; and in particular answer substitutions. They serve to represent solutions (that's what we are really interested in). There are several ways how answer substitutions may be represented. The tutorial you are using seems to refer to a very old version of SWI. I would say that this version is maybe 15 to 20 years old.
?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
However, the answer given is not incorrect: A new auxiliary variable _G189 is introduced.
Newer versions of SWI and many other systems try to minimize the output, avoiding auxiliary variables. So
?- append([1,2],X,Y).
Y = [1, 2|X].
is just as fine. It is the answer of a "newer" version (also some 6 years old). Note that this answer tells you much more than the first one: Not only does it show you the answer substitution more compactly, but it also tells you that there is exactly this one answer (and no more). See the dot . at the end? This means: There is no more here to answer. Otherwise there would be a ; for the next answer.
In Mathematica, how do you change the order of importance of variables? for example: if i enter b+c+a+d, i get a+b+c+d but i want b and d to preceed other variables. so that i get b+d+a+c
note, i'd like to use it where + is non-commutative
First you need to define an ordering function like:
In[1]:= CPOrdering[a]=3;
CPOrdering[b]=1;
CPOrdering[d]=2;
CPOrdering[c]=4;
Although, for more complicated examples, you should probably be smarter about it than this - ie use pattern matching.
Then you can sort expressions using
In[5]:= CirclePlus[a,b,c,d]
SortBy[%,CPOrdering]
Out[5]= a\[CirclePlus]b\[CirclePlus]c\[CirclePlus]d
Out[6]= b\[CirclePlus]d\[CirclePlus]a\[CirclePlus]c
This can then be automated using something like
CPOrdering[a_, b_] := CPOrdering[a] < CPOrdering[b]
CirclePlus[a__] /; (!OrderedQ[{a}, CPOrdering]) := CirclePlus##SortBy[{a}, CPOrdering]
The underlying reason b+c+a+d becomes a+b+c+d in Mathematica is because Plus has the attribute Orderless. In general, a symbol f with attribute Orderless means that the elements of f in an expession f[e1, e2, e3], the elements ei should be sorted into canonical order, and in particular, Mathematica's canonical order equivalent to that of OrderedQ and Ordering.
Orderless is even accounted for during pattern matching:
In[47]:= a+b+c+d /. a+c -> e
Out[47]= b+d+e
It's highly, highly recommended that you do NOT remove the Orderless attribute from Plus because the consequences could be dire for lots of functionality in Mathematica.
As other posters have noted, your best bet is to simply define your own function that is NOT Orderless, and will therefore preserve argument order. You might also find HoldForm useful in very limited circumstances.
Also note that nothing stops you from typesetting symbols in an expression in whatever order you want in a notebook, as long as you don't evaluate-in-place, etc.
So, don't use "+", because Plus[] IS commutative.
Define your own myPlus[x_,y_]:= .... whatever.
If you have an idea of what your new Plus[] should do, post it and we may try to help you with the definition/
HTH!
PS> You may change the definition of Plus[] ... but :)
I know on how to display a list by using loop.
For example,
choice(a):-write('This is the top 15 countries list:'),nl,
loop(X).
loop(X):-country(X),write(X),nl,fail.
Unfortunately, I don't know on how to display list by using list. Anyone can guide me?
it's not very clear what it is that you're trying to achieve.
I'm not sure from your description whether you have quite got to grips with the declarative style of Prolog. When you wrote your rule for loop you were providing a set of conditions under which Prolog would match the rule. This is different from a set of procedural instructions.
If you want to collect all the countries into a list you can use the setof rule like follows
top_countries(Cs):-
setof(C, country(C), Cs).
This will return a list [] of the countries matched by the rule.
If you wanted to output each element of this list on a new line you could do something like the following recursive function.
write_list([]).
write_list([H|T]):-
write(H),nl,
write_list(T).
The first rule matches the base case; this is when there are no elements left in the list. At this point we should match and stop. The second rule matches (unifies) the head of the list and writes it to screen with a newline after it. The final line unifies the tail (remainder) of the list against the write_list function again.
You could then string them together with something like the following
choice(a):-
write('This is the top 15 countries list:'),nl,
top_countries(X),
write_list(X).
Things to note
Try not to have singleton variables such as the X in your choice rule. Variables are there to unify (match) against something.
Look into good declarative programming style. When you use functions like write it can be misleading and tempting to treat Prolog in a procedural manner but this will just cause you problems.
Hope this helps
write/1 doesn't only write strings, it writes any Prolog term. So, though Oli has given a prettier write_list, the following would do the job:
choice(Countries):-write('This is the top 15 countries list:'),nl,write(Countries).