I am using the [family ontology][1] to test Jess rules. Everything works fine unless manipulating data with Jess built-in functions e.g. min and max. I have designed the following rule:
(defrule print_people_min_age
(object (https://wiki.csc.calpoly.edu/OntologyTutorial/family_example.owl#age ?a))
=>
(printout t "Min age " (min ?a) crlf))
The rule compiles well, but I am not getting the desired output. It outputs me ages of each person in the ontology. I tried to put the min function in the LHS but it results in error.
[1]: Family Ontology https://wiki.csc.calpoly.edu/OntologyTutorial/attachment/wiki/AddingRuleWithJessTab/family_example_for_rules.owl
Functions (min <numeric-expresion>+) and (max <numeric-expresion>+) are meant to be applied to a number of arguments - you are calling it with just one argument. The rule fires once for each object, and the minimum of that single age is - that age.
This rule illustrates how to find a minimum:
(defrule print_people_min_age
(object (https://wiki.csc.calpoly.edu/OntologyTutorial/family_example.owl#age ?a1))
(not (object (https://wiki.csc.calpoly.edu/OntologyTutorial/family_example.owl#age ?a2&:(< ?a2 ?a1))))
=>
(printout t "Min age " ?a1 crlf))
Related
Often code is not as readable as it could be because parameters are always at the end of the function name. Ex.: addDaysToDate(5, myDate).
I thought about a more readable syntax like this:
function add(days)DaysTo(date) {
// Some implementation
}
var myDate = new Date()
add(5)DaysTo(myDate)
And you could go really crazy:
addA(5)('dollar')CouponTo(order)If(user)IsLoggedIn
So here is my question: Are there any languages that incorporate this concept?
Assuming a generous interpretation of the phrase "is there", then: Algol 60 could look like your example. Specifically, it allowed a form of comment in procedure parameters.
add(5) Days To: (myDate);
The specific rule in the grammar that permits this is:
<parameter delimiter> ::= , | ) <letter string> : (
which is to say, the parameters in a procedure statement can be separated by a comma (as is common) or by an arbitrary sequence of letters delimited by ) and :(.
Spaces are everywhere ignored, so they're ok here too.
The letter-string is treated as a comment, so as for all comments, it has no bearing on what the code actually does. This is just as valid as the previous example:
add(5) Bananas To: (myDate);
It seems curious to me now, nearly 45 years after I last used this, that the comment part can only contain letters, no digits.
<letter string> ::= <letter> | <letter string> <letter>
Revised Report on the Algorithmic Language ALGOL 60
Have a look at Pogoscript https://github.com/featurist/pogoscript
There are no keywords in PogoScript. All control structures use the same syntax rules as regular functions and methods, so it's very easy to write your own control structures
Arguments and parameters can be placed anywhere in the name of a function or method call. The careful placement of an argument or a parameter can give it a lot of meaning.
sing (n) bottlesOfBeerOnTheWall =
if (n > 0)
console.log ((n) bottlesOfBeerOnTheWall)
sing (n - 1) bottlesOfBeerOnTheWall
(n) bottlesOfBeerOnTheWall =
"#((n) bottles) of beer on the wall, #((n) bottles) of beer.\n" +
"Take one down, pass it around, #((n - 1) bottles) of beer on the wall."
(n) bottles =
if (n == 0)
"no bottles"
else if (n == 1)
"1 bottle"
else
"#(n) bottles"
sing 99 bottlesOfBeerOnTheWall
Hello i do not understand why i do have the following problem :
I am trying to define taxes definition for Company using taxes implementation from Employee.I do not understand why i face the following errors:
data Employee=Employee{
age::Int,
name::String,
job::Job,
wage::Double
}
data Job= Worker | Manager |Unemployed deriving(Eq,Ord,Show)
data Company=Company{
compName::String,
year::Int,
employees::[Employee]
}
class Charges a where
taxes::a->Double
instance Charges Employee where
taxes Employee{age=a,wage=w}=fromIntegral a * w
Implementation 1:
instance Charges Company where
taxes comp=foldl ((+).taxes) 0 employees
Error:
Couldn't match type `[Employee]' with `Double'
Expected type: Company -> Double
Actual type: Company -> [Employee]
Why is it a problem since i take an Employee one by one i apply taxes which is already implemented for Employee and i add it to the counter??
Implementation2 - using foldr
instance Charges Company where
taxes comp =foldl ((+).taxes) 0 (employees comp)
Error:
Couldn't match expected type `Company -> Double'
with actual type `Double'
* Possible cause: `foldr' is applied to too many arguments
I see no more then 3 arguments what is the problem?
There is already a function in the Prelude that is excellent for summing lists of numbers. Why are we reinventing summation with a fold? Break the problem down into a few parts:
Find the company's employees
Compute taxes for each
Sum the results
Thus:
instance Charges Company where
taxes = sum . map taxes . employees
I have written the following Jess rule to use it in a Protege ontology.
(mapclass Cliente)
(defrule perfil-familia-numerosa
?cliente <- (object (is-a Cliente)
(nombre ?name)
(discapacidad? ?discapacity)
(distrito_deseado ?desired_district)
(n_miembros_familia ?n)
(presupuesto_maximo ?max)
(presupuesto_minimo ?min))
(test (> n 4))
=>
(assert (perfil-cliente ?name soltero)))
When I try entering it in the Jess tab, I get a type error Jess reported an error in routine > [...] java.lang.Integer cannot be cast to java.lang.String.
However, the slot in question is an Integer, so it is not clear to me why Jess it's treating it as a String. Any help?
The problem is here:
(test (> n 4))
A reference to a bound variable retains the '?', so you have to write
(test (> ?n 4))
However, it might be better to add this constraint to (n_miembros_familia ?n).
(n_miembros_familia ?n&:(> ?n 4))
What error problem?
ERROR-1: [ARGACCES5]function >= expected argument #2 to be of type integer or float.
ERROR-2: [CSTRCPSR1] expected the begining of a contrust.
How to fix this error?
For the first error, you're passing a non-numeric argument as the second argument into the >= function. When an error occurs within a construct, CLIPS will show you what's been parsed to help you locate the problem:
CLIPS>
(defrule example
(test (>= 3 a))
=>)
[ARGACCES5] Function >= expected argument #2 to be of type integer or float
ERROR:
(defrule MAIN::example
(test (>= 3 a)
CLIPS>
Typically the second error occurs when you have an extra or missing parenthesis when loading constructs. For example, if you create a file named example.clp with the following contents:
(defrule example-1 =>)
(defrule example-2 =>)
) ; Extra parenthesis
(defrule example-3 =>)
(defrule example-4 =>)
You'll get this error when you try to load it:
CLIPS> (watch compilations)
CLIPS> (load "example.clp")
Defining defrule: example-1 +j+j
Defining defrule: example-2 +j
[CSTRCPSR1] Expected the beginning of a construct.
Defining defrule: example-3 +j
Defining defrule: example-4 +j
FALSE
CLIPS>
If you're watching compilations, you can get a better idea of where the error is occurring. In this case it's between the rules example-2 and example-3.
I need some function which among other stuff would define a new global symbol. So that I could use it like this:
(define (func-prototype symbol value comment)
(define symbol value) ; this should somehow be reformulated
(format "~a=~a !~a\n" symbol value comment))
(define string-list (map func-prototype
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value))))
and be able to get the following results:
> string-list
'("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
> s1
1
> s2
20
> s3
300
Can this be implemented as a function or it is possible to do that only with the help of macros? Could you please suggest any possible implementations or at least give some hints/references that might be helpful?
I'd rethink the general approach, making it simpler. My suggestion: define a global hash table and inside the function add bindings to it, for example:
(define value-map (make-hash))
(define (func-prototype symbol value comment)
(hash-set! value-map symbol value)
(format "~a=~a !~a\n" symbol value comment))
Use it like this:
(define string-list
(map (lambda (lst)
(apply func-prototype lst))
'((s1 1 "first value")
(s2 20 "second value")
(s3 300 "third value"))))
string-list
=> '("s1=1 !first value\n"
"s2=20 !second value\n"
"s3=300 !third value\n")
And wherever you need to refer to one of the symbols in the hash table, do this:
(define (get key)
(hash-ref value-map key))
(get 's1)
=> 1
(get 's2)
=> 20
(get 's3)
=> 300
In general it is not possible to accomplish what you are trying to accomplish in the way you described. Your only hope would be to write stuff out to a file and then load that file into an interactive session. But even then.
In scheme you can't introduce top-level names, such as your desired s1, s2, and s3, except at the top-level. To do so, you could define a macro as:
>(define-syntax define-foo
(syntax-rules ()
((_ name value)
(define name value))))
>(define-foo s1 1)
<undefined>
> s1
1
If you try to use that macro in a function, it is no dice because the body of a function must end with an expression and any definition forms, like what the above macro would expand into, become local variables. That is:
(define (func-prototype name value comment)
(define-foo name value)
name)
>(func-prototype 's1 1 "com")
1
> s1
<error>
One approach that you could take that would work if your string-list is a constant would be as such:
> (define-syntax declare-variables
(syntax-rules ()
((_ (name value comment) ...)
(begin
(define name value)
...))))
> (declare-variables (s1 1 "com") (s2 20 "com") (s3 300 "com"))
> s1
1
This gets it done (I've ignored using 'comment') but, as I said, requires a compile time string-list.
One possibility you might think would work, but wouldn't, would be to use eval as:
(eval '(define s1 1) (environment ...))
but 'eval' only works for expressions, not declarations. Which gets me back to 'load' as a possibility.
First, consider whether you really want to do this, or whether a different solution (like a hash table) would work as well.
You can do this with reflection and dynamic evaluation using the eval procedure.
;; define-variable-with-value! : symbol any -> void
(define (define-variable-with-value! name value)
(eval `(define ,name (quote ,value))))
The quote is important; otherwise you risk reinterpreting a value as an expression to evaluate. To see the difference, consider the example
(define-variable-with-value! 'x (list 'error "kaboom"))