CLIPs How can I print all defacts as result throught a Defrule? Or be able to insert multiple traits as answer? - artificial-intelligence

I'm working on a project that let's users find a list of jasmines based on flower color and blooming seasons, but I haven't found an effective way to be able to print all jasmines currently on the program at once by using a defrule
(deftemplate jazmin
(slot nombre)
(slot color-flor
(allowed-values blanca amarilla))
(multislot floracion
(allowed-values invierno primavera verano otono))
)
(defrule in-color-flor
=>
(printout t "Inserte el color de la flor: ")
(assert (color-flor (read)))
)
(defrule in-floracion
=>
(printout t "Inserte en que mes florece: ")
(assert (floracion (read)))
)
(defrule buscar-jazmin
(color-flor ?color-flor)
(floracion ?floracion)
(jazmin (nombre ?nombre) (color-flor ?color-flor) (floracion $? ?floracion $?))
=>
(printout t "El nombre del jazmin descrito es: " ?nombre crlf)
)
(defrule jazmin-no-encontrado
(color-flor ?color-flor)
(floracion ?floracion)
(not (jazmin (nombre ?nombre) (color-flor ?color-flor) (floracion $? ?floracion $?)))
=>
(printout t "El jazmin descrito no se encuentra" crlf)
)
(deffacts jazmines
(jazmin (nombre Jazmin-Blanco) (color-flor blanca) (floracion primavera verano otono))
(jazmin (nombre Jazmin-Chino) (color-flor blanca) (floracion primavera))
(jazmin (nombre Jazmin-Silvestre) (color-flor amarilla) (floracion verano))
(jazmin (nombre Jazmin-Azor) (color-flor blanca) (floracion primavera))
(jazmin (nombre Jazmin-Espanol) (color-flor blanca) (floracion verano otono))
(jazmin (nombre Jazmin-Amarillo) (color-flor amarilla) (floracion invierno primavera))
)
I want to know if it's possible to print all of them in one rule, or be able to specify more than one trait in a single (run).

A rule that prints all of them is:
(defrule jazmin
(jazmin (nombre ?nombre))
=>
(printout t "jazmin " ?nombre crlf)
)
Your rules already allow you to specify more than one trait (color and floracion).

Related

CLIPS How can I create a print out for when the values inserted are not any of the options?

I need to add to my program a print for when the user inserts values that dont correspond to the existing fruits on my program.
(clear)
(deftemplate fruta
(slot nombre)
(multislot color
(allowed-values naranja amarillo morado rojo verde))
(slot semilla
(allowed-values hueso multiple))
(multislot tipo-piel
(allowed-values aterciopelada lisa rugosa))
(slot crece-en
(allowed-values arbol planta))
)
(defrule in-color
=>
(printout t "Ingrese el color de la fruta: ")
(assert (color (read)))
)
(defrule in-semilla
=>
(printout t "Ingrese el tipo de semilla de la fruta: ")
(assert (semilla (read)))
)
(defrule in-tipo-piel
=>
(printout t "Ingrese el tipo de piel de la fruta: ")
(assert (tipo-piel (read)))
)
(defrule in-crece-en
=>
(printout t "Donde crece la fruta (arbol o planta): ")
(assert (crece (read)))
)
(defrule buscar-fruta
(color ?color)
(semilla ?semilla)
(tipo-piel ?tipo-piel)
(crece ?crece-en)
(fruta (nombre ?nombre) (color $? ?color $?) (semilla ?semilla) (tipo-piel $? ?tipo-piel $?) (crece-en ?crece-en))
=>
(printout t "La fruta a la que se refiere es: " ?nombre crlf)
)
(deffacts frutas
(fruta (nombre Melocoton) (color naranja) (semilla hueso) (tipo-piel aterciopelada) (crece-en arbol))
(fruta (nombre Albaricoque) (color amarillo) (semilla hueso) (tipo-piel aterciopelada) (crece-en arbol))
(fruta (nombre Ciruela) (color morado) (semilla hueso) (tipo-piel lisa) (crece-en arbol))
(fruta (nombre Cereza) (color rojo) (semilla hueso) (tipo-piel lisa) (crece-en arbol))
(fruta (nombre Aguacate) (color verde) (semilla hueso) (tipo-piel rugosa) (crece-en arbol))
(fruta (nombre Mandarina) (color naranja verde) (semilla multiple) (tipo-piel rugosa) (crece-en arbol))
(fruta (nombre Limon) (color verde amarillo) (semilla multiple) (tipo-piel rugosa lisa) (crece-en arbol))
(fruta (nombre Melon) (color naranja amarillo) (semilla multiple) (tipo-piel rugosa lisa) (crece-en planta))
(fruta (nombre Sandia) (color verde) (semilla multiple) (tipo-piel lisa) (crece-en planta))
)
(reset)
(run)
I havent found a way to create a rule for additional options the user may insert, and I would like to know if there's something like the underscore (_) used in visual prolog for these types of rule when working with a guessing program.
Use a not conditional element in another rule to determine that there is no matching fruit:
(defrule no-buscar-fruta
(color ?color)
(semilla ?semilla)
(tipo-piel ?tipo-piel)
(crece ?crece-en)
(not (fruta (nombre ?nombre) (color $? ?color $?) (semilla ?semilla) (tipo-piel $? ?tipo-piel $?) (crece-en ?crece-en)))
=>
(printout t "La fruta a la que te refieres no se encuentra." crlf)
)

CLIPS: How can I allow users to input sentences as answers? Jasmine Flower Guess

Im currently working on a CLIPS program that guesses the name of the jasmine flower based only on the flower color and season, but I don't know how to use sentences as possibles answers to be able to get answers like "spring to autumn"
Here's the code:
(deftemplate jazmin
(slot nombre)
(slot color-flor
(allowed-values blanca amarilla))
(slot temporada
(allowed-values primavera verano primavera-a-otoño verano-a-otoño invierno-a-primavera))
)
(defrule in-color-flor
=>
(printout t "Inserte el color de la flor: ")
(assert (color-flor (read)))
)
(defrule in-temporada
=>
(printout t "Inserte en que temporada florece: ")
(assert (temporada (read)))
)
(defrule buscar-jazmin
(color-flor ?color)
(temporada ?temporada)
(jazmin (nombre ?nombre) (color-flor ?color-flor) (temporada ?temporada))
=>
(printout t "El nombre del jazmin descrito es: " ?nombre crlf)
)
(defrule jazmin-no-encontrado
(color ?color-flor)
(temporada ?temporada)
(not (jazmin (nombre ?nombre) (color-flor ?color-flor) (temporada ?temporada)))
=>
(printout t "El jazmin descrito no se encuentra" crlf)
)
(deffacts jazmines
(jazmin (nombre Jazmin-Blanco) (color-flor blanca) (temporada primavera-a-otono))
(jazmin (nombre Jazmin-Chino) (color-flor blanca) (temporada primavera))
(jazmin (nombre Jazmin-Silvestre) (color-flor amarilla) (temporada verano))
(jazmin (nombre Jazmin-Azor) (color-flor amarilla) (temporada primavera))
(jazmin (nombre Jazmin-Espanol) (color-flor blanca) (temporada verano-a-otono))
(jazmin (nombre Jazmin-Amarillo) (color-flor amarilla) (temporada invierno-a-primavera))
)
Also I'm curious if there's a better way to optimize for options such as Spring to Autumn without having to put the whole sentences as one answer.
You can write rules to expand either the user's answer or the values in the temporada slot to include seasons between two other seasons:
CLIPS>
(deffacts seasons
(season-order primavera verano otono invierno primavera))
CLIPS>
(defrule expand-season-1
?f <- (seasons $?first ?s1 to ?s2)
(season-order $? ?s1 ?s2 $?)
=>
(retract ?f)
(assert (seasons ?first ?s1 ?s2)))
CLIPS>
(defrule expand-season-2
?f <- (seasons $?first ?s1 to ?s3)
(season-order $? ?s1 ?s2&~?s3 $?)
=>
(retract ?f)
(assert (seasons ?first ?s1 ?s2 to ?s3)))
CLIPS>
(defrule get-seasons
=>
(print "Seasons? ")
(assert (seasons (explode$ (readline)))))
CLIPS> (reset)
CLIPS> (run)
Seasons? invierno to verano
CLIPS> (facts)
f-1 (season-order primavera verano otono invierno primavera)
f-4 (seasons invierno primavera verano)
For a total of 2 facts.
CLIPS> (reset)
CLIPS> (run)
Seasons? otono primavera
CLIPS> (facts)
f-1 (season-order primavera verano otono invierno primavera)
f-2 (seasons otono primavera)
For a total of 2 facts.
CLIPS>

"Cannot read property 'cache' of undefined" when I check a member role

I want to make a mute command for my Discord bot but that create errors:
C:\Program Files\nodejs\node.exe .\index.js
|------ Bot on ------|
index.js:22
Uncaught TypeError: Cannot read property 'cache' of undefined
No debugger available, can not send 'variables'
Process exited with code 1
I want to check if the user who is mentionned has already the mute role and if the executor has an admin role. But that create this error.
My code:
bot.on("message", async message => {
if(message.content.startsWith(prefix + "mute")){
let User = message.mentions.users.first();
let time = message.content.split(" ").slice(2)
let reason = message.content.split(" ").slice(3)
if(!reason){ let reason = "aucune"}
if(!time || !User) return message.reply("Veuillez entrer une commande valide !\n" + prefix + "mute #user <temps> <raison>")
let dUser = User.id
if(dUser == message.author.id) return message.reply("Vous ne pouvez pas vous mute vous même !")
if(isNaN(time[0]) || time < 1) return message.reply("Veuillez entrer une valeur chiffrée et supérieur à 1 !")
let muterole = "793840735266013205"
che
if(User.roles.cache.has(muterole)) return message.reply("Ce membre est déjà mute !")
if(!message.author.roles.cache.has("783758067111428126" || "783758066138218577")) return message.reply("Vous n'avez pas la permission d'utiliser cette commande !")
if(User.roles.cache.has("783758067111428126" || "783758066138218577")) return message.reply("Vous ne pouvez pas mute un membre du staff !")
let emb = new Discord.MessageEmbed()
.setTitle(Mute)
.setDescription(User.username + " a bien été mute par " + message.author.username + " pendant " + time[0] + " secondes pour la raison suivante : " + reason)
.setColor("#E74C3C")
pendant " + time[0] + " secondes pour la raison suivante : " + reason)
User.roles.add(muterole)
setTimeout(() => {
User.roles.remove(muterole)
let reply = new Discord.MessageEmbed()
.setDescription(User + " a bien été unmute !")
.setColor("#E74C3C")
message.guild.channels.cache.get("795063422386569298").send(reply)
let mp = new Discord.MessageEmbed()
.setDescription("Vous avez été unmute de " + guild)
.setColor("#E74C3C")
message.author.send(mp)
}, time[0] = 60000
)}
})
Don’t worry about French words.
Your code is not going to do what you want it to do, because you messed up some parts. User will be the first mentioned user that can be found in your arguments. So if you mention the user right at the first position of your arguments, it will be at index 0. That is because the arguments get stored in an array and arrays always starts at index 0. That means now your following arguments have to be at index 1 and 2. So you can change your time and reason into:
let time = message.content.split(" ").slice(1);
let reason = message.content.split(" ").slice(2).join(" ");
Make sure you use .join(" ") at your reason, that will allow you to add multiple words for the reason. The next mistake is in the if-statement where you ask if there is no reason. You create a new variable inside the statement, which makes no sense. You just have to do:
if(!reason){ reason = "aucune"; }
Now if there is no reason provided the reason will be aucune.
If you want to ask if a user has the mute role already, you can use a GuildMember Object. That would look like this:
if(message.guild.member(User).roles.cache.has(muterole)) return message.reply("Ce membre est déjà mute !")
After that if-statement you ask if a user has certain roles and if he don't has this roles, he has no permission. Something like that should always be the first line of code of such a command and it should look like this:
if(!message.author.roles.cache.has("783758067111428126") || !message.author.roles.cache.has("783758066138218577")) return message.reply("Vous n'avez pas la permission d'utiliser cette commande !")
The same procedure with the following if-statement:
if(User.roles.cache.has("783758067111428126") || User.roles.cache.has("783758066138218577")) return message.reply("Vous ne pouvez pas mute un membre du staff !")
Then in your embed you are using time[0], although time is not an array. It just has to be time.
Your code should look like this now:
bot.on("message", async message => {
if(message.content.startsWith(prefix + "mute")){
if(!message.author.roles.cache.has("783758067111428126") || !message.author.roles.cache.has("783758066138218577")) return message.reply("Vous n'avez pas la permission d'utiliser cette commande !")
let User = message.mentions.users.first();
if(User.roles.cache.has("783758067111428126") || User.roles.cache.has("783758066138218577")) return message.reply("Vous ne pouvez pas mute un membre du staff !")
let time = message.content.split(" ").slice(2)
let reason = message.content.split(" ").slice(3)
if(!reason){ reason = "aucune"; }
if(!time || !User) return message.reply("Veuillez entrer une commande valide !\n" + prefix + "mute #user <temps> <raison>")
let dUser = User.id
if(dUser == message.author.id) return message.reply("Vous ne pouvez pas vous mute vous même !")
if(isNaN(time) || time < 1) return message.reply("Veuillez entrer une valeur chiffrée et supérieur à 1 !")
let muterole = "793840735266013205"
if(message.guild.member(User).roles.cache.has(muterole)) return message.reply("Ce membre est déjà mute !")
let emb = new Discord.MessageEmbed()
.setTitle(Mute)
.setDescription(User.username + " a bien été mute par " + message.author.username + " pendant " + time + " secondes pour la raison suivante : " + reason)
.setColor("#E74C3C")
User.roles.add(muterole)
setTimeout(() => {
User.roles.remove(muterole)
let reply = new Discord.MessageEmbed()
.setDescription(User + " a bien été unmute !")
.setColor("#E74C3C")
message.guild.channels.cache.get("795063422386569298").send(reply)
let mp = new Discord.MessageEmbed()
.setDescription("Vous avez été unmute de " + message.guild)
.setColor("#E74C3C")
message.author.send(mp)
}, time
)}
})

Datatables change interface language

I am currently using angular-datatables.
How can I see the interface of the table in other languages?
I mean the "Show entries", "Search:", "Showing 1 to 10 of 20 entries" literals fore example in Spanish.
You need to define a language struct like this (danish implementation, what I am using in my angular-datatables apps) :
var language = {
"sEmptyTable": "Ingen tilgængelige data (prøv en anden søgning)",
"sInfo": "Viser _START_ til _END_ af _TOTAL_ rækker",
"sInfoEmpty": "Viser 0 til 0 af 0 rækker",
"sInfoFiltered": "(filtreret ud af _MAX_ rækker ialt)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Vis _MENU_ rækker",
"sLoadingRecords": "Henter data...",
"sProcessing": "Processing...",
"sSearch": "Filter:",
"sZeroRecords": "Ingen rækker matchede filter",
"oPaginate": {
"sFirst": "Første",
"sLast": "Sidste",
"sNext": "Næste",
"sPrevious": "Forrige"
},
"oAria": {
"sSortAscending": ": activate to sort column ascending",
"sSortDescending": ": activate to sort column descending"
}
}
There is a bunch of languages here -> https://www.datatables.net/plug-ins/i18n/
And then you include the language using the withLanguage() option method
.withLanguage(language)
demo -> http://plnkr.co/edit/RCrqM3z7qwsUfFwy8HE6?p=preview
I created a .ts file like this:
export class LanguageApp {
public static spanish_datatables = {
processing: "Procesando...",
search: "Buscar:",
lengthMenu: "Mostrar _MENU_ &elementos",
info: "Mostrando desde _START_ al _END_ de _TOTAL_ elementos",
infoEmpty: "Mostrando ningún elemento.",
infoFiltered: "(filtrado _MAX_ elementos total)",
infoPostFix: "",
loadingRecords: "Cargando registros...",
zeroRecords: "No se encontraron registros",
emptyTable: "No hay datos disponibles en la tabla",
paginate: {
first: "Primero",
previous: "Anterior",
next: "Siguiente",
last: "Último"
},
aria: {
sortAscending: ": Activar para ordenar la tabla en orden ascendente",
sortDescending: ": Activar para ordenar la tabla en orden descendente"
}
}
}
Then in the component that was loading the DataTable just put that config inside dtOptions:
this.dtOptions = {
language: LanguageApp.spanish_datatables
};
In Angular2+ what worked for me is quite the same as mentioned by #davidkonrad, but without the starting letters (s and o), and adding the language as an attribute of the dtOptions. I.e.:
this.dtOptions = {
pagingType: 'full_numbers',
pageLength: 10,
dom: 'Bfrtip',
buttons: [
/*'print',
'csv'*/
],
responsive: true,
/* below is the relevant part, e.g. translated to spanish */
language: {
processing: "Procesando...",
search: "Buscar:",
lengthMenu: "Mostrar _MENU_ éléments",
info: "Mostrando desde _START_ al _END_ de _TOTAL_ elementos",
infoEmpty: "Mostrando ningún elemento.",
infoFiltered: "(filtrado _MAX_ elementos total)",
infoPostFix: "",
loadingRecords: "Cargando registros...",
zeroRecords: "No se encontraron registros",
emptyTable: "No hay datos disponibles en la tabla",
paginate: {
first: "Primero",
previous: "Anterior",
next: "Siguiente",
last: "Último"
},
aria: {
sortAscending: ": Activar para ordenar la tabla en orden ascendente",
sortDescending: ": Activar para ordenar la tabla en orden descendente"
}
}
};

What is wrong when I call this array from a variable?

I have been do it a template page for Wordpress Theme. In it, have to filter some tags from an user field.
But for test, I do it that:
$user_id = get_current_user_id();
$contexto = get_user_meta($user_id, 'contexto', true);
$contexto = '"' . $contexto . '"';
$array = array (
"Buscando mi nicho​" => "buscando-mi-nicho",
"Montando mi blog" => "montando-mi-plataforma",
"Buscando lectores" => "buscando-lectores",
"Construyendo mi lista de correo​" => "construyendo-mi-lista-de-correo",
"Vendiendo mi primer producto/servicio​" => "vendiendo-mi-primer-productoservicio",
"Buscando más clientes​​​" => "escalar-ventas",
"A punto de dar el gran salto (para vivir de mi blog)​" => "a-punto-de-dar-el-gran-salto-para-vivir-de-mi-blog",
"Ya soy Knowmada Full Time​" => "ya-soy-knowmada-full-time"
);
$etiqueta = $array[$contexto];
$user_first = get_user_meta( $user_id, 'first_name', true );
echo '<p>Hola '. $user_first . '. Queremos ayudarte a progresar, y tu etapa actual es <strong>' . $contexto . '</strong>, por eso, te recomendamos los siguientes contenidos con la etiqueta <b>' . $etiqueta . '</b></p>';
And I get:
Hola Javier. Queremos ayudarte a progresar, y tu etapa actual es "Montando mi blog", por eso, te recomendamos los siguientes contenidos con la etiqueta
You can see, that I don't get the variable $etiqueta.
If I put, for example:
$etiqueta = $array["Montando mi blog"];
I get:
Hola Javier. Queremos ayudarte a progresar, y tu etapa actual es "Montando mi blog", por eso, te recomendamos los siguientes contenidos con la etiqueta montando-mi-plataforma
So I get $etiqueta.
What is wrong whit:
$etiqueta = $array[$contexto];
It is because the keys in your array to not have the double quotes ("). Remove the line:
$contexto = '"' . $contexto . '"';
and it should work.

Resources