Scheme intersection between lists of pairs - scheme

I have the following example of lists where on the first line I have a result and on the second a filter, and I need to keep only the results that match at least one of the pairs in the filter.
(((john . ?x) (new-york . ?city)) ((mike . ?x) (chicago . ?city)) ((mary . ?x) (london . ?city)))
(((new-york . ?city)) ((chicago . ?city)))
(((john . ?x) (new-york . ?city)) ((mike . ?x) (chicago . ?city)) ((mary . ?x) (london . ?city)))
(((john . ?x) (air-hockey . ?game)) ((mike . ?x) (tennis . ?game)))
The problem I'm having is that both the results and filter have a variable number of parameters and I don't know how to take out one element at a time for comparison. I could use some hints since this is a homework.
Match would mean in the first example john and mike since their cities match the filter. While in the second example it would just add each of the games they play to the result.
While you have to check each of the entries on the first line, for the match to work you would have to get #t for at least one of the entries on the second line

It's not clear to me from your question what "match" means in this context. Let me suggest that you probably first want to develop a helper function that accepts one element from the first line and one element from the second line, and returns "true" when they match.
Also, I would definitely write some test cases first :).

I believe this is the same question that was asked here, take a look at my answer.

Related

What's the return value of CLIPS' do-for-fact if fact has been found?

The CLIPS reference manual explains about do-for-fact:
If a fact-set satisfies
the query, the specified action is executed, and the function is immediately terminated. The
return value is the evaluation of the action. If no fact-set satisfied the query, then the return value
is the symbol FALSE.
However, I cannot find any details on what the "evaluation of the action" means in general.
Is it safe to assume that do-for-fact always returns a value not equal to FALSE if a fact has been found?
Is the following code snippet correct?
(if (not (do-for-fact ((?p1 girl boy woman man)
(?p2 girl boy woman man)
(?p3 girl boy woman man))
(and (= ?p1:age ?p2:age ?p3:age)
(neq ?p1 ?p2)
(neq ?p1 ?p3)
(neq ?p2 ?p3))
(printout t ?p1:name " " ?p2:name " " ?p3:name crlf)))
then
(printout t "Nobody found" crlf)
)
Action refers to the BNF description of the function syntax:
(do-for-fact <fact-set-template> <query> <action>*)
This action term is the same term used in the body of a deffunction:
(deffunction <name> [<comment>]
(<regular-parameter>* [<wildcard-parameter>]) <action>*)
The return value in both cases is the last action evaluated. If the last action evaluated returns the value FALSE, then the do-for-fact function will return the value FALSE just as it would if there was no fact-set that satisfied the query.
In your example, the printout function has no return value which is treated as a non-FALSE value by the not function, so it will work as you expect
CLIPS> (printout t)
CLIPS> (not (printout t))
FALSE
CLIPS>
If you had included the symbol FALSE after the printout call, then the return value of the do-for-fact call would always be FALSE regardless of whether any fact-set satisfied the query.
(printout t ?p1:name " " ?p2:name " " ?p3:name crlf)
FALSE))

Sorting list of cons by second object

I need to sort list of cons elements by cdr element.
For example:
(aaa.4 bbb.2 ccc.6 ddd.9 eee.3) => (bbb.2 eee.3 aaa.4 ccc.6 ddd.9)
Help me please, i just start learning Lisp.
This (aaa.4 bbb.2 ccc.6 ddd.9 eee.3) is not a list of conses, but a list of symbols named "aaa.4", "bbb.2" etc.
What your text implies is rather something like this:
((aaa . 4)
(bbb . 2)
(ccc . 6)
(ddd . 9)
(eee . 3))
You can sort a list by some key with the key argument to sort:
(sort list #'< :key #'cdr)
Sort may destructively modify the input list in order to create the sorted output list. To protect against that, copy it first:
(sort (copy-list list) #'< :key #'cdr)

Get values from a subClass in a sparql query

Im have a problem trying to do a sparql query using subClasses.
I have the following ontology:
where Quesos is a SubClassOf Ingrediente as you can see in the next image and Quesos have some other members too.
I want to have some recipes back from some ingredients. For example:
I want to have all the recipes that contains tomato, salt and cheese (where cheese could be any cheese) and I want to have back all the recipes than contains those ingredients.
Here is the problem: If i put the ingredient (like salt or tomato) then the query works fine, but if I put "Quesos" then I've got no answer. I don´t know how to play with the subclasses in a sparql query.
So far I have the following query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rec:<http://www.receta.org#>
SELECT ?r ?cal ?tiempo ?dif (COUNT (?i) as ?cantIng)(GROUP_CONCAT(DISTINCT ?listaIngredientes) as ?listaIng)(GROUP_CONCAT(DISTINCT ?modoPreparacion) as ?Preparacion)
WHERE {
?x rdf:type rec:Receta .
?x rdfs:label ?r.
?x rec:Ingrediente rec:Sal.
?x rec:Ingrediente rec:Tomate.
?x rec:Calorias ?cal.
?x rec:tiempoPreparacion ?tiempo.
?x rec:dificultad ?dif.
?x rec:listaIngredientes ?listaIngredientes.
?x rec:modoPreparacion ?modoPreparacion.
}
GROUP BY ?r ?cal ?tiempo ?dif
ORDER BY ?cantIng
And I need to add the "subclassOf" line, but I cant find the way. Anyone can help? thank you!
This actually has nothing to do with subclasses, but just with the difference between an instance and a class. Since rec:Quesos is the class of all cheeses, and each specific type of cheese is modeled as an instance of rec:Quesos, you can query this by adding a graph pattern to your query that, instead of matching a specific ingredient (such as rec:Sal or rec:Tomate), matches any ingredient of the type rec:Quesos:
?x rec:Ingrediente ?i .
?i a rec:Quesos.
Or more shortly (since you don't actually need the value of ?i for anything else):
?x rec:Ingrediente [ a rec:Quesos ].

Scheme: match-lambda syntax error

I am writing a function annotate that uses match-lambda often with recursive calls to annotate. Here is one of the patterns and matches:
(`(,<param> . ,<params> (lambda (,<args>) ,<stmt> . ,<stmts>))
`(CLOSURE ENV ,(append (append `(,<param>) `(,<params>))`(,<args>)) (lambda (ENV) ,(map annotate `(,<stmt> . ,<stmts>)))))
I am getting a complaint that the first use of "." is illegal -- between "param" and "params" -- but I can't figure out why. This pattern and match doesn't get any complaints and seems very similar with regards to the first ".":
(`(λ (,<param1> . ,<params>) ,<stmt> . ,<stmts>)
`(CLOSURE ENV ,(map annotate `(,<param1> . ,<params>)) (λ (ENV) ,(map annotate `(,<stmt> . ,<stmts>)))))
Any advice is appreciated.
Thanks.
The . needs to be before the last element in the list (except for some Racket-specific syntax that you are not using). Remember that the general form of a list is (a b c . d), meaning (cons a (cons b (cons c d))). You might be able to use ,#<params> to match some elements in the middle of a list, but I am not sure about that.

Scheme: match-lambda syntax error

I am writing a function annotate that uses match-lambda often with recursive calls to annotate. Here is one of the patterns and matches:
(`(,<param> . ,<params> (lambda (,<args>) ,<stmt> . ,<stmts>))
`(CLOSURE ENV ,(append (append `(,<param>) `(,<params>))`(,<args>)) (lambda (ENV) ,(map annotate `(,<stmt> . ,<stmts>)))))
I am getting a complaint that the first use of "." is illegal -- between "param" and "params" -- but I can't figure out why. This pattern and match doesn't get any complaints and seems very similar with regards to the first ".":
(`(λ (,<param1> . ,<params>) ,<stmt> . ,<stmts>)
`(CLOSURE ENV ,(map annotate `(,<param1> . ,<params>)) (λ (ENV) ,(map annotate `(,<stmt> . ,<stmts>)))))
Any advice is appreciated.
Thanks.
The "." is used in Racket and in Scheme to represent "improper lists"; that is, sequences of cons pairs that don't end with "empty". So, for instance,
'(3 4 . 5)
is a shorthand for
(cons 3 (cons 4 5))
The 'dot' is used to mean: "I'm done with the list-like part; here's the final value, use this instead of "empty". For this reason, you can't use the dot just anywhere in the list; it has to be just before a single, final element. In your example, the dot in the pattern precedes a bunch of elements, not just one.
Looking at your example, it looks you want to use the "..." syntax here, e.g.:
(match '(a b c d e)
[`(,x ... d e) 'ok])
(Actually, you can also use dots for infix notation in Racket, but I'm pretty sure that's not what you're trying to do, here.)

Resources