Format on Prolog - prolog

I have a doubt making tables with format, I need to make tables, I know I can make it this way:
If for example my table is tabla("estudents",["name","age","id"]).
But I have a problem, I need to get the numbers of attributes of the table, then I'll set a length of 18 to each square and the length will be N..
print_table_name(C):- tabla(C,A), //I SEARCH MY TABLE
atom_codes(Name,C), //PASSING THE NAME TO ATOM
length(A,N), //I GET MY NUMBER OF ATRIBUTES
Length is 18*N, //Length WILL BE THE LENGTH OF THE TABLE
print_edge(N), //HERE I PRINT THE TOP EDGE
format('|~t~a~t~N|)|~n',Name), //HERE IS MY ERROR
print_edge(N). //HERE I PRINT THE BOTTOM EDGE
print_edge(0):- format('~n',[]).
print_edge(N):- format('+~`-t~18|+', []), M is N-1, print_edge(M), !.
format('|~t~a~t~N|)|~n',Name) here I can't pass N as a variable, then I dont know how I can do to format get the N, N is the length of the table..
It print this
+--------------------------------------------------------------------------+
|students
||
+--------------------------------------------------------------------------+
and if I put the length where is N, then it works.
+--------------------------------------------------------------------------+
| students |
+--------------------------------------------------------------------------+
The problem is that I don't know how to pass the variable N to format.

In this case you should pass N as an argument to the format/2 predicate. Replace the variable N in the format by the symbol * and put N in the argument list.
I'm not sure if you will get the desire effect, but at least it won't fail.
format('|~t~a~t~*|)|~n',[Name, N]).
Edit
Right now I can only test the solution in this limited online interpreter: I replace the ~t by the character dot ~46t to see the effect and this is the result:
?- format('|~46t~a~46t~*|)|~n',['students', 72]).
|...............................students................................)|
PS: Are you sure about the parenthesis between the two last vertical bar?

Related

Prolog, print employees with same names

This is my first time using Prolog.
I have employees:
employee(eID,firstname,lastname,month,year).
I have units:
unit(uID,type,eId).
I want to make a predicate
double_name(X).
that prints the last names of the employees with the same first name in the unit X.
I am doing something like this :
double_name(X) :-
unit(X,_,_eID),
employee(_eID,_firstname,_,_,_),
_name = _firstname,
employee(_,_name,_lastname,_,_),
write(_lastname).
But it prints all the employees in the unit.
How can i print only the employees with the same name ?
unit(unit_01,type,1).
unit(unit_01,type,2).
unit(unit_01,type,3).
employee(1,mary,smith,6,1992).
employee(2,fred,jones,1,1990).
employee(3,mary,cobbler,2,1995).
double_name(Unit) :-
unit(Unit,_,Eid_1),
employee(Eid_1,Firstname,Lastname_1,_,_),
unit(Unit,_,Eid_2),
Eid_1 \= Eid_2,
employee(Eid_2,Firstname,Lastname_2,_,_),
write(Firstname),write(","),write(Lastname_1),nl,
write(Firstname),write(","),write(Lastname_2).
Variables in Prolog typically start with an upper case letter, but starting them with and underscore is allowed, but not typical.
In double_name/2 the predicates like
unit(Unit,_,Eid_1)
employee(Eid_1,Firstname,Lastname_1,_,_)
are used to load the values from the facts into variables while pattern matching (via unification) that the bound variables match with the fact.
To ensure that a person is not compared with themselves.
Eid_1 \= Eid_2
and to make sure that two people have the same first name the same variable is used: Firstname.
The write/1 and nl/0 predicates just write the result to the screen.
Example:
?- double_name(unit_01).
mary,smith
mary,cobbler
true ;
mary,cobbler
mary,smith
true ;
false.
Notice that the correct answer is duplicated. This can be resolved.
See: Prolog check if first element in lists are not equal and second item in list is equal
and look at the use of normalize/4 and setof/3 in my answer
which I leave as an exercise for you.

Edit Distance Data Structure

I am new to data structure want to know the flow of this diagram as mentioned ,it's for calculating minimum edit distance between two string ,in the graph i understood that String 1 is of three length and String 2 is also of three length , so tutorial shown graph from eD(3,3) then why the graph split again in eD(3,2),eD(2,3),eD(2,2) for the 2 level of recursion . What it signifies ? Please need detail explanation . Why we can't split level 2 ,like this eD(3,2),eD(2,3).
I am following this Url : https://www.geeksforgeeks.org/dynamic-programming-set-5-edit-distance/
enter image description here
Ok, so basically in case of Edit Distance, we are trying to either insert, update or delete an element. So, our basic approach is to try all three of these available operations at each point and check which case gives the best result.
Specific to the case that you are trying to understand, the following is the scenario:
eD(3,3) = eD(2,2) if str1[3] == str2[3] # Without incuring any cost, we find edit distance of the remaining strings.
else l + min(del, ins, rep)
where
del = eD(2,3), Deleted the last character of str1, and finding the edit distance of the remaining strings.
ins = eD(3,2), Inserted the last element of str2 in str1, thus now we are finding the edit distance between the remaining strings. E.g. 'adc' and 'axf', if we add 'f' to the first string, it will become 'adcf'. Thus now, the last characters of both strings is same, I have to eventually find the edit distance between 'adc' and 'ax', Thus it becomes eD(3,2).
rep = eD(2,2), Replaced the last element of str1 with the last element of str2, and finding the edit distance of the remaining strings. E.g. 'abc' and adf, if we replace the last character of first string with the last character of second string, we will get 'abf' and 'adf', as now the last characters of both the strings are same, eventually we are finding the edit distance between 'ab' and 'ad'. Thus, eD(2,2)

Stack multiple columns into one

I want to do a simple task but somehow I'm unable to do it. Assume that I have one column like:
a
z
e
r
t
How can I create a new column with the same value twice with the following result:
a
a
z
z
e
e
r
r
t
t
I've already tried to double my column and do something like :
=TRANSPOSE(SPLIT(JOIN(";",A:A,B:B),";"))
but it creates:
a
z
e
r
t
a
z
e
r
t
I get inspired by this answer so far.
Try this:
=SORT({A1:A5;A1:A5})
Here we use:
sort
{} to combine data
Accounting your comment, then you may use this formula:
=QUERY(SORT(ArrayFormula({row(A1:A5),A1:A5;row(A1:A5),A1:A5})),"select Col2")
The idea is to use additional column of data with number of row, then sort by row, then query to get only values.
And join→split method will do the same:
=TRANSPOSE(SPLIT(JOIN(",",ARRAYFORMULA(CONCAT(A1:A5&",",A1:A5))),","))
Here we use range only two times, so this is easier to use. Also see Concat + ArrayFormula sample.
Few hundreds rows is nothing :)
I created index from 1 to n, then pasted it twice and sorted by index. But it's obviously fancier to do it with a formula :)
Assuming Your list is in column A and (for now) the times of repeat are in C1 (can be changed to a number in the formula), then something simple like this will do (starting in B1):
=INDEX(A:A,(INT(ROW()-1)/$C$1)+1)
Simply copy down as you need it (will give just 0 after the last item). No sorting. No array. No sheets/excel problems. No heavy calculations.

How do I Prolog specify pair printing format

Pair data is nice to work with, but I found hard to present. I ask how to accomplish printing a set of vectors such that keys & values line up in a pleasantly. Leading zeros in the pair-values, would help. Sample data:
[1-7,2-43,3-56,4-87,5-110,6-80,7-15]
[1-1837,2-1873,3-1911,4-1946,5-1975,6-1994,7-2005]
I tried to figure out use of SWI format_predicate ; but couldn't.
Then I thought to experiment inline;
format('~n~w ~w~w~n', ['Pairs: ',1-246,1-2, ' EOL']).
End result should deal with pairs of the form KK-VVVV:
01-0007 02-0043 03-0056 04-0087 05-0110 06-0080 07-0015 398 People 7 Gens.
01-1837 02-1873 03-1911 04-1946 05-1975 06-1994 07-2005 Spanning 168 Years
Final Answers:
fpair(A-B) :- format('~`0t~d~2|-~`0t~d~7| ', [A,B])
applist(_,[]). applist(P,[X|L]) :- Q =.. [P,X],call(Q),applist(P,L).
dojustone(X):- format('~# ',[fpair(X)]).
dolist(X):- applist(dolist,X).
I use a # specifier for complex formats, it allows to output specific terms. For instance
?- format('~s~n~#~n~#~n~w~n', ['Pairs: ',fpair(1-246),fpair(1-2), ' EOL']).
that is, fpair/1 is an user predicate, called by #, capturing its output.
To get fixed width fields, I use the tab specification, built from two specifiers working together. Finally, to prefix with 0s, I would use
fpair(A-B) :-
format('~`0t~d~6| ~`0t~d~12|', [A,B]).
Without knowing a priori the maximum number of digits, we must use a guess. I used 6 here.

mathematica: PadRight[] and \[PlusMinus]

Is there any way that
PadRight[a \[PlusMinus] b,2,""]
Returns
{a \[PlusMinus] b,""}
Instead of
a \[PlusMinus] b \[PlusMinus] ""
?
I believe that i need to somehow deactivate the operator properties of [PlusMinus].
Why do i need this?
I'm creating a program to display tables with physical quantities. To me, that means tables with entries like
(value of a) [PlusMinus] (uncertainty of a)
When i have several columns with different heights, i'm stuffing the shorter ones with "", so i can use Transpose the numeric part of the table.
If the column has more than one entrie, there's no problem:
PadRight[{a \[PlusMinus] b,c \[PlusMinus] d},4,""]
gives what i want:
{a \[PlusMinus] b,c \[PlusMinus] d,"",""}
It is when the column has only one entrie that my problem appears.
This is the code that constructs the body stuffed with "":
If[tested[Sbody],1,
body = PadRight[body, {Length[a], Max[Map[Length, body]]
With
tested[a__] :=
If[Length[DeleteDuplicates[Map[Dimensions, {a}]]] != 1, False,
True];
, a function that discovers if is arguments have the same dimension
and
a={Quantity1,Quantity2,...}
Where the quantities are the one's that i want on my table.
Thanks
First you need to be aware of that any expression in Mathematica is in the form of Head[Body]
where body may be empty, a single expression or a sequence of expressions separated by commas
Length operate on expressions, not necessarily lists
so
Length[PlusMinus[a,b]]
returns 2 since the body of the expression contains to expressions (atoms in this case) that are a and b
Read the documentation on PadRight. The second argument define the final length of the expression
so
PadRight[{a,b},4,c] results with a list of length 4 with the last two elements equal to
PadRight[{a,b},2,c] results with the original list since it is already of length 2
Therefore
PadRight[PlusMinus[a,b],2,anything] just returns the same PlusMinus[a,b] unchanged since it is already of length 2
so, youר first example is wrong. You are not able to get a result with head List using PadRight when you try to pad to an expression with head PlusMinus
There is no problem of executing
PadRight[PlusMinus[a,b],3,""]
but the result looks funny (at best) and logically meaningless, but if this is what you wanted in the first place you get it, and following my explanations above you can figure out why
HTH
best
yehuda

Resources