What I'm trying to accomplish is to get what 'Components' are not being used. So I created a list with all the 'Components' and 'In Use Components'.
My idea is to compare this lists and create another list with the elements that didn't match.
component('name 1', 1).
component('name 2', 2).
component('name 3', 3).
component('name 4', 4).
component('name 5', 5).
inUse(1, 'name 1').
inUse(1, 'name 3').
inUse(1, 'name 5').
comp_list(L):- findall(Comp, component(Comp, _), L).
inuse_list(L):- findall(Comp, inUse(_, Comp), L).
I don't know how to do something like this: member('name comp', List). where I can replace 'name comp' with every element of the other list.
Thanks in advance.
Example:
L1 = ['name 1', 'name 2', 'name 3', 'name 4', 'name 5'] %comp_list(L).
L2 = ['name 1', 'name 3', 'name 5'] %inuse_list(L).
someRule(R):- comp_list(L1), inuse_list(L2), %more code, to obtain a list R with:
R = ['name 2', 'name 4'] (Elements lacking on inuse_list)
Although the answer is correct, it is much better to avoid lists as long as you can if you need to reason about facts and rules in the database. In this case, a target unused components is easily defined as
ununsed(Name) :-
component(Name, _),
\+ inUse(_, Name).
This nicely enumerates the unused components. If you want them in a list, use findall/3 over unused/1. In most cases though the definition of unused/1 is way easier to combine with other pure logical relations.
In most cases aggregation primitives like findall/3, aggregate/3, etc., are best delayed until the very end or not used at all.
You could add a simple recursive predicate to obtain elements of comp_list that are not member of inuse_list:
obtain_elements([],_,[]).
obtain_elements([H|T],L,[H|T1]):-\+member(H,L),obtain_elements(T,L,T1).
obtain_elements([H|T],L,L2):-member(H,L),obtain_elements(T,L,L2).
and use it like:
someRule(R):- comp_list(L1),
inuse_list(L2),
obtain_elements(L1,L2,R).
OR another way using findall/3 predicate:
someRule(R):- comp_list(L1),
inuse_list(L2),
findall(X,(member(X,L1),\+member(X,L2)),R).
Related
I have facts like that :
student(stud01, 'Programming 1', 90).
student(stud01, 'Math 1', 78).
student(stud01, 'Statistics 1', 94).
student(stud01, 'Electronics 1', 81).
student(stud01, 'Management', 66).
student(stud01, 'English', 83).
i want to build a predict that take the student id and and put all its grade in list
and after that take the max grade
i try this :
stuGrade(ID,List):-
stuGrade([],ID,List).
stuGrade(TmpList,ID,List):-
student(ID,Course,Grade),
not(mem([ID],TmpList)), !,
append_List([Grade],TmpList,NewTmpList),
stuGrade(List,ID,NewTmpList).
stuGrade(List,ID,List).
maxStudentGrade(ID,Max):-
stuGrade(ID,L),
max(L,Max).
but the problem that after using ?-trace. i see that the output list containing only the first grade (90) how can i slove this problem
Suppose that you begin with ?- stuGrade(stu01, List).
Then you will get the first student entry at least. And you say there is some issue after that.
So, a simple way to check is to test by using the first part of the query, such that,
?- ID = stu01, TmpList = [],
student(ID,Course,Grade),
not(mem([ID],TmpList)), !.
When you find its result is false, stop and check the last predicate.
Using break points
trace/0 and nodebug/0 are nice tools.
You may want to check issues by like the following,
stuGrade(TmpList, ID, List) :-
student(ID, Course, Grade),
trace, % <------------------ Put a break point here.
not(mem([ID], TmpList)),
nodebug, % <----------------- Here, stop tracing.
!,
append_List([Grade], TmpList, NewTmpList),
stuGrade(List, ID, NewTmpList).
Good luck.
And you code...
stuGrade(ID,List):- stuGrade([],ID,List).
stuGrade(TmpList, ID, List):-
student(ID, Course, Grade),
not(mem([ID], TmpList)),
!,
append_List([Grade], TmpList, NewTmpList),
stuGrade(List, ID, NewTmpList).
stuGrade(List,ID,List).
Not bad. But, consider the first clause of stuGrade/3.
When you get a Grade, it's prepended to TmpList and you get NewTmpList. But at the next line, the newly built list is put as the third argument, as you know that it's for the final returned List.
It cannot be that. The first parameter of stuGrade/3, TmpList, is the accumulating parameter. Then NewTmpList might be placed as the first argument of the recursive query, such that stuGrade(NewTmpList, ID, List).
Perhaps my understanding of how the =FILTER() function works is incorrect, but I was under the impression that it was
=FILTER(range, condition 1, [condition 2], ...)
which means this:
=FILTER('Item Database'!A5:A, 'Item Database'!R4:R="Heavy Armor", 'Item Database'!R5:R="Light Armor")
should return a list of items from 'Item Database'!A5:A who's R column matched either "Heavy Armor" or "Light Armor"
As I said, it is possible my understanding is just incorrect, but all I'm getting is an N/A error telling me that no items match the filter result
Here's a link to a copy of the spreadsheet as well
https://docs.google.com/spreadsheets/d/1oXLbc9vkjuWYU60xhsYsT3vv7utOJswVjwJUWS3XpF0/edit?usp=sharing
+++++Edit
With some further fooling around with it, I'm thinking that BOTH conditon 1 and condition 2 must be met in order to fit the criteria. Going to try this:
=FILTER('Item Database'!A5:A, 'Item Database'!R5:R="Heavy Armor")&FILTER('Item Database'!A5:A, 'Item Database'!R5:R="Light Armor"
Above attempt populated one cell instead of cascading down the entire column like my Weapon and All lists do.
Have also attempted:
=FILTER('Item Database'!A5:A, 'Item Database'!R5:R="*"&"Armor")
=FILTER('Item Database'!A5:A, 'Item Database'!R5:R="*"&" Armor")
=FILTER('Item Database'!A5:A, 'Item Database'!R5:R="*Armor")
Final solution turned out to be:
=FILTER('Item Database'!A5:A, ('Item Database'!R5:R="Heavy Armor") + ('Item Database'!R5:R="Light Armor"))
Marking this as answered so no one's time is wasted, yay for trial and error!
use:
=FILTER('Item Database'!A5:A,
REGEXMATCH('Item Database'!R5:R, "Heavy Armor|Light Armor"))
I am working on an assignment and I am woefully stuck. I have little experience with prolog and I am learning on the job based on online material and a textbook.
The aim of the assignment is to produce a predicate, parse(), that is able to check that a given argument/term is of the following form, returning true or false as appropriate:
((int,int),[(int,float),(int,float)...])
So an int pair, followed by an n-sized list of (int,float) pairs, with both wrapped up in a tuple.
For example:
( (1, 7), [(1, 0.0), (2, 0.5), (3, 0.7), (4, 0.8), (5, 0.8), (6,
0.25), (7, 0.3)] )
Could anyone point me in the right direction for where to begin on this? I haven't ever done this sort of this in Prolog.
I am not looking for a full coded answer, naturally this is an assignment, but just some direction for how to approach this problem. I have no declarative programming background, so this is an educational exercise.
Thanks!
We can start with the observation that what you show is already a valid Prolog term:
?- T = ( (1, 7), [(1, 0.0), (2, 0.5), (3, 0.7), (4, 0.8), (5, 0.8), (6, 0.25), (7, 0.3)] ) .
T = ((1, 7), [(1, 0.0), (2, 0.5), (3, 0.7), (4, 0.8), (5, 0.8), (6, 0.25), (7, 0.3)]).
So, in such a case, there is no manual parsing necessary. By parsing, we typically mean the conversion of unstructured text, such as plain lists of characters or character codes, to a structured representation.
Prolog automatically rejects terms that are not syntactically valid. So, in your case, if you already have such a term, all it takes is to state what must hold about it so that it satisfies all constraints.
In Prolog, it is often useful to first think about building blocks you may want to use as a useful basis. For example, let us describe an (int,float) term:
integer_float_tuple((I,F)) :- integer(I), float(F).
We can use it as follows:
?- integer_float_tuple((3,4.5)).
true.
Note though:
First, the definition is not a true relation. For example, the most general query ?- integer_float_tuple(T). will fail even though there clearly are solutions!
Second, using terms of the form (A,B) is discouraged, also because (',')/2 is already used for so many other things in Prolog. It would be better to represent such pairs as I-F, using (-)/2 which is commonly used to denote pairs throughout Prolog libraries.
In any case, we can build on this definition with:
good_term((Tuple,Tuples)) :-
Tuple = (A,B),
integer(A), integer(B),
maplist(integer_float_tuple, Tuple).
This states everything that must hold for such terms, and thus lets you validate them although, as noted, not generate them. To generalize such predicates to work in all directions, use your Prolog system's CLP(FD) and CLP(R) constraints. This will give you a definition that is monotonic and satisfies many desirable properties we expect from a logic program.
Further, if you really want to parse your data manually (as opposed to relying on Prolog's built-in notion of structured terms), I have two recommendations:
First, add the following directive to your program:
:- set_prolog_flag(double_quotes, chars).
This lets you conveniently write lists of characters with double quotes.
For example:
?- Cs = "abc".
Cs = [a, b, c].
Such a representation is very convenient for what we do next, which is using Prolog Definite Clause Grammars for parsing such lists of characters.
I won't solve the whole task for you, but I give you a start. We can start by describing what we mean by a digit:
digit(D) --> [D], { char_type(D, digit) }.
We use such a grammar with the phrase/2 interface predicate. For example:
?- phrase(digit(D), "5").
D = '5'.
Building on this definition, let us describe lists of digits:
digits([]) --> [].
digits([D|Ds]) --> digit(D), digits(Ds).
Example query:
?- phrase(digits(Ds), "5235").
Ds = ['5', '2', '3', '5'] ;
false.
Finally, let us combine all this to decsribe an integer:
integer(I) --> digit(D), digits(Ds), { number_chars(I, [D|Ds]) }.
With number_chars/2, we are performing the crucial conversion between characters and actual integers, which you need in your own representation.
Example query:
?- phrase(integer(I), "5235").
I = 5235 ;
false.
Using such building blocks, you can conveniently describe the general outline of such lists of characters by forther grammar elements.
Overall, your eventual grammar may look like:
pattern --> "(", whitespace, "(", integer, ",", integer, ")", ...
Where you need to supply definitions for whitespace//0 and complete the whole description.
See dcg for more information about this approach.
In Prolog we write predicates, not functions, that in the most basic case just qualify the 'trueness' of the relation - conventionally described by the 'name' of the predicate, so called functor - among the arguments.
So, you're writing a relation among 3 arguments:
parse(Needle, Haystack, Found) :-
...
You should write down a further relation, that holds true when Needle matches one of the elements of Haystack. So you have a choice: either a recursive parse/3, where the current element to be matched is made explicit in the head pattern (that is, parse(Needle, [Element|Haystack], Found) :- etc) or use member/2 from library(lists), that on backtracking will iterate elements...
I have a list of strings like the following:
list = ['a1', 'a2', 'a3', 'a4', 'a5', 'a6']
I would like to retrieve all the items and the indices between a pair of strings. For example, all the items between 'a2' and 'a6'.
Is there a way to do it with regular expressions?
the desire output is the following:
(in reality I only need the indices as I can retreive all the values with the indices).
THe reason to want regex is; I am trying to mine the output from a PDF and I am trying to mine the text and from the text extracted from the PDF I am creating a big list with all the output. From this list created from the PDF a im trying to automate these text extraction of the PDFs. As they can have variable texts and different formats I want to be able to take various formats of representing the same data.I figured regex allows to take text with slight variable format and then transform that with the desired format.
example of reference list:
list = ['name', 'Mark', 'Smith', 'location', 'Florida', 'Coast', 'FL', 'date']
location_indices = [3, 6]
desired namelst = ['name', 'Mark', 'Smith']
location= ['location', 'Florida', 'Coast', 'FL']
I figured that the best way to go about this is to get the indices between Location and Date and from there I can generate the location list. Now, As my original list can vary slightly in the reference list I think regex provides me the flexibility to have slight different original list than I can reformat.
Let's define your list:
>>> lst = ['a1', 'a2', 'a3', 'a4', 'a5', 'a6']
(So as not to overwrite a builtin, I renamed the list to lst.)
Now, let's retrieve the indices and values of all items from a2 to a6 inclusive:
>>> [(i,x) for (i,x) in enumerate(lst) if lst.index('a2')<=i<=lst.index('a6')]
[(1, 'a2'), (2, 'a3'), (3, 'a4'), (4, 'a5'), (5, 'a6')]
I have a query like
SearchQueryset().all().models(Show).order_by('title')
This will return list of objects. But in the title names there might be the special characters like ./hack:twilight and also numbers like 009:absolute.
According to order_by documentation, the priority goes to special characters. But when I see the output, it starts from the numbers.
Basically I need this output using that query
>> list = ['apple', 'zebra', '.hack', 'orange', 'car', 'funk', 'python']
>>> list.sort()
>>> list
['.hack', 'apple', 'car', 'funk', 'orange', 'python', 'zebra']
Any idea?