Prolog List of Constants to String - string

i have a list in input: [asd,qweqwe,fsdf,lkasd]
As un can see from the code i want connect each constant of the list to output a single variable list.
i m using yap prolog, i consult this code and i write :- run.
the write function print out _G1233 and not 'asd,asd2,asd3,asd4'
why ? how i have to change the code for output me 'asd,asd2,asd3,asd4' ?
run :- toAtomicVars([asd,asd2,asd3,asd4],',',Out),
write(Out),nl.
toAtomicVars([],In,Out).
toAtomicVars([A|B],In,Out) :-
atomic_concat(A,In,Out1),
atomic_concat(',',Out1,Out2),
toAtomicVars(B,Out2,Out2).

you (should) get a warning like
Singleton variables: [In,Out]
Singleton variables: [Out]
that means that you dont really do anything with those variables:
toAtomicVars([],In,Out).
In and Out can be anything, so prolog just prints a dummy value, _Gsomething that means that the variable is not instantiated.
same thing happens in the second clause:
toAtomicVars([A|B],In,Out) :-
atomic_concat(A,In,Out1),
atomic_concat(',',Out1,Out2),
toAtomicVars(B,Out2,Out2).
you dont say anywhere what is that Out.
personally i think that it would be easier if you just printed each variable recursively and then print a comma, something like:
print_list([X]):-
write(X).
print_list([H|T]):-
write(H),
write(', '),
print_list(T).
but if you want to put commas in the list you should add a rule that defines Out.

Related

Using Groovy 3 YamlBuilder with Yaml that contains a hyphen

I'm trying to write a Groovy 3 script that uses yamlbuilder to write a yaml file. I have it working on almost everything apart from;
execution:
set-props:
url:http://myhouse.net
port:8000
How do I write a map that allows the use of a hyphen in the name? Following my previous work I foolishly tried;
def setprops=[:]
setprops=(["url":"http://myhouse.net","port":"8000"])
execution.set-props=setprops
Which gives me an error 'The LHS of an assignment should be a variable or a field'.
If I just use execution.setprops then it works fine, but of course the resulting yaml from yaml(execution) is invalid.
I think if the set-props was a a key/value pair then it could go into quote and everything would be good. But because it is part of the structure I don't know what needs to be done.
You can use strings as "methods" and the builder will create your
intermediate structures from them:
import groovy.yaml.YamlBuilder
def b = new YamlBuilder()
b.execution {
"set-props"(
url: "..."
)
}
println b
Or to continue on your example: You can create the whole map and use is as argument, where you want to have that content.
def setprops=["set-props": [url:"..."]]
b.execution(setprops)
Both result in:
---
execution:
set-props:
url: "..."
Note that the first version nests via passed closures and then passes in the map. The second bit just passes a nested map.

Keep String property after inseriting to a list

I´m doing a project where I need to recognize specific strings and add them to a list. Im using this method to insert them in a specific position:
insertAt(E,N,Xs,Ys) :-
same_length([E|Xs],Ys),
append(Before,Xs0,Xs),
length(Before,N),
append(Before,[E|Xs0],Ys)
The problem is that when I insert any String for example '4X',in my list appears 4X, as a number and a variable. How can i keep the single quotes after the insert?
This is the line that gives me problems:
insertAt('>500',0,ListA,ListB),writeln(ListB).
When the list show in promt it looks like [>500],without the quotes.
Simple example since you didn't indicate how you are creating 4X
test :-
append(["4x"],[],New),
write(New).
Example run:
?- test.
[4x]
true.
After updates in comments.
Is there a way to write while maintaining the quotes?
?- print('4x').
'4x'
true.
?- print([a,b,'4X',d]).
[a,b,'4X',d]
true.
Of note: portray/1
I have never used portray/1 but you might.

How to return string of dict keys in python3 without brackets

I am trying to build an interactive shell-like terminal program in Python3 for a school project.
It should be easily expandable and not rely on non-python-builtin modules.
For this matter, I made a module, which is imported and contains something like this:
commandDictionary={
"command":'''
Information for my program on how to handle command
In multiple lines.''',
}
helpDictionary={
"command":'''
Short Text for the help-command to display
Also in multiple lines.'''
}
What I want to do is to list all keys from helpDictionaryin a string form if help is input.
The output should look like this:
Help
List of available commands:
command1, command2, command3, command4 #Newline after 4 commands.
command5, command6, commandWithALongName, command8
My Problem is, that helpDictionary.keys() returns something like this:
['command1', 'command2']
and I dont want the Brackets nor the ' .
Is this possible?
If you don't want to retain the contents in memory, you can print any iterable you want with an arbitrary separator like this:
print(*helpDictionary.keys(), sep=', ')
If you do want the string for something, use str.join on the separator you want:
s = ', '.join(helpDictionary.keys())
print(s)
Both cases shown above will output the result in essentially arbitrary order because dictionaries use hash tables under the hood. If you want to sort commands lexicographically, replace helpDictionary.keys() with sorted(helpDictionary.keys()).
So, your problem is how to print a list without brackets. There are several solutions.
Traverse the keys: for k in helpDictionary.keys(): print(k)
Or convert the list to a string, then print the mid.
li = list(helpDictionary.keys())
print(str(li)[1:-1])

How to save strings in matrixes in matlab

I want to have a matrix/cell, that has strings inside that I can access and use later as strings.
For instance, I have one variable (MyVar) and one cell (site) with names inside:
MyVar=-9999;
site={'New_York'; 'Lisbon'; 'Sydney'};
Then I want to do something like:
SitePosition=strcat(site{1},'_101'}
and then do this
save(sprintf('SitePosition%d',MyVar),);
This doesn't work at all! Is there a way to have strings in a matrix and access them in order to keep working with them if they were a string?
This:
MyVar=-9999; site={'New_York'; 'Lisbon'; 'Sydney'};
SitePosition = strcat(site{1},'_101');
save(sprintf('SitePosition%d',MyVar));
Works fine and yields SitePosition-9999.mat, note the syntax changes in lines 2 and 3.
Is there something else you're expecting?
EDIT: Based on your comment
Check out the documentation for save regarding saving specific variables
New example:
MyVar=-9999;
site={'New_York'; 'Lisbon'; 'Sydney'};
SitePosition = strcat(site{1},'_101');
save(SitePosition,'MyVar');
Creates New_York_101.mat with only the variable MyVar in it.

Prolog: Pass User-Input as Parameters

I am new to Prolog and therefore need help with the following task.
I have the programm:
do(save) :- save_bal(bad).
do(act) :- save_bal(good), inc(good).
do(comb) :- save_bal(good), inc(bad).
save_bal(good) :- savMoney(X), depPeople(Y), Min is Y * 1000, X >= Min.
save_bal(bad) :- not(save_bal(good)).
inc(good) :- earn(Z), depPeople(Y), MinE is 3000 + Y * 400, Z >= MinE.
inc(bad) :- not(inc(good)).
savMoney(30000).
earn(60000).
depPeople(4).
My task is to rewrite this programm, so the numbers 30000, 60000 and 4 is set by a user input. How can I do this?
I tried:
:- read(A), savMoney(A).
:- read(B), earn(B).
:- read(C), depPeople(C).
But that won't work.
Can someone point me in the right direction?
Thanks in advance!
Prolog is an homoiconic language, then the first step you should take is to declare which predicate are data, and which are (just to say) logic constraints on the data.
Then, add near top of file (just a stylistic hint) the declarations
:- dynamic(savMoney/1).
:- dynamic(earn/1).
:- dynamic(depPeople/1).
then you can add a service predicate, say user_update_store/1, like
user_update_store(Entry) :-
AccessValueCurr =.. [Entry, ValueCurr],
(retract(AccessValueCurr) -> true ; ValueCurr = 0),
format('enter value for ~s (current is ~w):', [Entry, ValueCurr]),
read(NewValue),
% validate it's a number etc...
StoreNewValue =.. [Entry, NewValue],
assertz(StoreNewValue).
now you can start your user interface:
?- maplist(user_udpdate_store, [savMoney,earn,depPeople]).
this code should work for every (ISO compliant) Prolog. Note: I didn't tested it...
HTH
CapelliC provided an excellent (better) answer while I was busy typing away at this monstrosity. In fact, I didn't end up addressing the question in your title, because you were passing parameters just fine. Instead I wrote about assertz/1 and retract/1. However, I taught myself a fair amount while composing it and you might also find it informative.
In your example code, we have 3 facts declared with the predicates savMoney/1, earn/1, depPeople/1'. We then have a number of rules that determine values based on these facts. A rule is of the form :- ., and which I sometimes read to myself as "<head> is true if <body> is true". We can think of a fact as a rule of the form :- true, e.g.,savMoney(30000) :- true.`, which we might read as "30000 is savMoney if true is true", and true is true or we're all screwed. (BTW, is 'savMoney' short for saved money?)
A directive is of the form :- <body>.. It is like a rule that must be tested in order for the program (or world) to be true (this is more evocative than accurate, because, as you've seen, when a directive fails the whole program-world is not false, we just get a warning). When we consult a prolog file, we add new rules and facts to our program-world, and these can even be impossible nonsense statements like a :- \+ a. "a is true if not-a is true"1. That contradiction will cause cause a stack overflow if you query ?- a., but the program will load just fine. However, directives have to be evaluated and settled while the program loads in the order they are encountered:
This program will throw a stack overflow error when the interpreter consults it.
a :- \+ a.
:- a.
This program will throw an undefined procedure error, because it is being directed to prove a before a has been entered into the database.
:- a.
a :- \+ a.
When we have a directive like :- read(A), savMoney(A)., it's not saying "read the value of user input into A and then set saveMoney to A". Instead, it's saying something more like, "if this program is loaded, then A is a value read in from user input and A is savMoney." Suppose you run the program and enter 100 at the first prompt (the plain prompt is |). What happens?
prolog unifies the variable A with 100.
prolog tries to prove savMoney(100).
it replies Warning: Goal (directive) failed: user:(read(_G2072),savMoney(_G2072)).
This is because, while savMoney(30000) is true, savMoney(100) is not. A directive does not assert the contents of its body, it only tells prolog to prove those contents.
What you are trying to do is allow the user to assert a previously unknown fact into the database. As indicated by mbratch, this requires using the predicate assertz/12. However, predicted that be changed during run-time are differentiated from standard predicates.
If you try to define a reestablished predicate in a program, you'll get an error. E.g., consult a file consisting of the following declaration:
length(2, y).
You'll receive an error:
ERROR: /Users/aporiac/myprolog/swi/studies/test.pl:18:
No permission to modify static procedure `length/2'
Defined at /opt/local/lib/swipl-6.2.6/boot/init.pl:2708
This tells us that 'length/2' is static and that it is already defined in init.pl file at line 2708.
The same happens if you try to assert a static predicate with assertz/1. You can try this by querying assertz(savMoney(100)) in swipl. In order to add new facts or rules about a predicate, we have to declare the predicate to be dynamic.
This is accomplished with dynamic/1. To assure that prolog knows which of our predicates are to be counted as dynamic, we give it a directive like so3:
:- dynamic savMoney/1.
If you've added that to your file (before you define the predicate), you can then query ?- assertz(savMoney(100)). to add the new fact to the database. Now, if you query ?- savMoney(X), you'll get
X = 30000;
X = 100.
There are now two possible values for X, because we've added another fact to the database.
Of course, in your case, you don't want to keep adding values to savMoney/1, you want to be able to update and replace the value.
That calls for retract/1 (If you think there's a chance that more than one occurrence the asserted predicate could get added at some point, then you can use retractall/1 to clear all instances). Now we can write a rule like the following:
set_saved(Amount) :-
retract( savMoney(_) ),
assertz( savMoney(Amount) ).
set_saved(Amount) is true if savMoney(_) can be retracted and removed from the database and the new fact savMoney(Amount) can be asserted.
I've just seen that CapelliC has provided a simple input interface, and a much more concise solution to the problem, but here's my version of your example program in case it might be informative. (I didn't actually get around to adding the prompt and input, but querying, e.g., ?- set_saved(100), does what you'd expect).
:- dynamic [ savMoney/1,
earn/1,
depPeople/1 ].
do(save) :- save_bal(bad).
do(act) :- save_bal(good), inc(good).
do(comb) :- save_bal(good), inc(bad).
save_bal(good) :- savMoney(X), depPeople(Y), Min is Y * 1000, X >= Min.
save_bal(bad) :- not(save_bal(good)).
inc(good) :- earn(Z), depPeople(Y), MinE is 3000 + Y * 400, Z >= MinE.
inc(bad) :- not(inc(good)).
savMoney(30000).
earn(60000).
depPeople(4).
set_saved(Amount) :-
retract( savMoney(_) ),
assertz( savMoney(Amount) ).
set_earned(Amount) :-
retract( earn(_) ),
assertz( earn(Amount) ).
set_people_in_department(Number) :-
retract( depPeople(_) ),
assertz( depPeople(Number) ).
report([Saved, Earned, People]) :-
Saved = savMoney(_) , Saved,
Earned = earn(_) , Earned,
People = depPeople(_), People.
\+/1 is the standard negation operator in swi-prolog and not/1 is depreciated.
assert/1 is equivalent to, and depreciated in favor of, assertz/1. asserta/1 asserts the fact or clause as the first instance of the predicate at hand, while assertz/1 asserts it as the last. (Cf. the manual section on the Database).
Of course, this goes against the interpretation of the directive I suggested before. My interpretation fits when you're using 'normal' predicates in a directive. But, most often, we see directives used for special predicates like in module declarations (:- module(name, [<list of exported predicates>]) or module imports (:- use_module([<list of modules>])).

Resources