Predicados
Table of Contents
- 1.
symbolp
: Teste de símbolo - 2.
eq
: Teste de identidade simbólica - 3.
nilp
: Teste de nulidade - 4.
consp
: Teste de célula cons - 5.
atomp
: Teste de atomicidade - 6.
charp
: Teste de caractere - 7.
char=
: Comparação de caracteres - 8.
streamp
: Teste de stream - 9.
numberp
: Teste de número - 10.
vectorp
: Teste de vetor - 11.
id
: Teste de identidade - 12.
proper-list-p
: Teste de lista adequada - 13.
stringp
: Teste de String - 14.
literalp
: Teste de literal - 15.
primitivep
: Teste de primitivas - 16.
closurep
: Teste de clausura - 17.
functionp
: Teste de função - 18.
macrop
: Teste de macro - 19.
errorp
: Teste de erro - 20.
zerop
: Teste de nulidade numérica - 21. Registro em contexto global
Arquivo: axioms/predicates.rs
.
use gc::Gc; use crate::maj_list; use crate::core::Maj; use crate::core::MajState; use super::primitives::{ maj_car, maj_cdr, maj_err };
1. symbolp
: Teste de símbolo
pub fn maj_symbolp(x: Gc<Maj>) -> Gc<Maj> { if let Maj::Sym(_) = *x { return Maj::t(); } Maj::nil() }
2. eq
: Teste de identidade simbólica
pub fn maj_eq(x: Gc<Maj>, y: Gc<Maj>) -> Gc<Maj> { if let Maj::Sym(idx) = *x { if let Maj::Sym(idy) = *y { if idx == idy { return Maj::t(); } } } Maj::nil() }
3. nilp
: Teste de nulidade
pub fn maj_nilp(x: Gc<Maj>) -> Gc<Maj> { maj_eq(x, Maj::nil()) }
4. consp
: Teste de célula cons
pub fn maj_consp(x: Gc<Maj>) -> Gc<Maj> { if let Maj::Cons { car: _, cdr: _ } = *x { return Maj::t(); } Maj::nil() }
5. atomp
: Teste de atomicidade
pub fn maj_atomp(x: Gc<Maj>) -> Gc<Maj> { if let Maj::Cons { car: _, cdr: _ } = *x { return Maj::nil() } Maj::t() }
6. charp
: Teste de caractere
pub fn maj_charp(x: Gc<Maj>) -> Gc<Maj> { if let Maj::Char(_) = *x { return Maj::t(); } Maj::nil() }
7. char=
: Comparação de caracteres
pub fn maj_char_equals(x: Gc<Maj>, y: Gc<Maj>) -> Gc<Maj> { if let Maj::Char(xc) = *x.clone() { if let Maj::Char(yc) = *y.clone() { if xc == yc { Maj::t() } else { Maj::nil() } } else { maj_err(Maj::string("{} is not a character"), maj_list!(y)) } } else { maj_err(Maj::string("{} is not a character"), maj_list!(x)) } }
8. streamp
: Teste de stream
pub fn maj_streamp(x: Gc<Maj>) -> Gc<Maj> { if let Maj::Stream(_) = *x { return Maj::t(); } Maj::nil() }
9. numberp
: Teste de número
pub fn maj_numberp(x: Gc<Maj>) -> Gc<Maj> { if let Maj::Number(_) = &*x { return Maj::t(); } Maj::nil() }
9.1. integerp
: Teste de número inteiro
pub fn maj_integerp(x: Gc<Maj>) -> Gc<Maj> { use crate::core::types::MajNumber; if let Maj::Number(num) = &*x { if let MajNumber::Integer(_) = num { return Maj::t(); } } Maj::nil() }
9.2. floatp
: Teste de ponto flutuante
pub fn maj_floatp(x: Gc<Maj>) -> Gc<Maj> { use crate::core::types::MajNumber; if let Maj::Number(num) = &*x { if let MajNumber::Float(_) = num { return Maj::t(); } } Maj::nil() }
9.3. fractionp
: Teste de fração
pub fn maj_fractionp(x: Gc<Maj>) -> Gc<Maj> { use crate::core::types::MajNumber; if let Maj::Number(num) = &*x { if let MajNumber::Fraction(_, _) = num { return Maj::t(); } } Maj::nil() }
9.4. complexp
: Teste de número complexo
pub fn maj_complexp(x: Gc<Maj>) -> Gc<Maj> { use crate::core::types::MajNumber; if let Maj::Number(num) = &*x { if let MajNumber::Complex { real: _, imag: _ } = num { return Maj::t(); } } Maj::nil() }
10. vectorp
: Teste de vetor
pub fn maj_vectorp(x: Gc<Maj>) -> Gc<Maj> { if let Maj::Vector(_) = &*x { Maj::t() } else { Maj::nil() } }
11. id
: Teste de identidade
pub fn maj_id(x: Gc<Maj>, y: Gc<Maj>) -> Gc<Maj> { match *x { Maj::Sym(_) => { if let Maj::Sym(_) = *y { return maj_eq(x, y); } }, Maj::Char(chrx) => { if let Maj::Char(chry) = *y { if chrx == chry { return Maj::t(); } } }, _ => { let x_ptr = Gc::into_raw(x); let y_ptr = Gc::into_raw(y); if x_ptr == y_ptr { return Maj::t(); } } } Maj::nil() }
12. proper-list-p
: Teste de lista adequada
Uma lista adequada é qualquer lista que termina com um símbolo nil
apropriado. Então, por exemplo, (1 2 3)
é uma lista adequada, mas
(1 2 3 . 4)
não é. Isto fica evidente quando comparamos a impressão de
ambas as respectivas listas com notação de pontos:
(1 . (2 . (3 . nil)))
(1 . (2 . (3 . 4)))
Uma lista vazia (ou seja, o próprio símbolo nil
) também é considerada
uma lista adequada.
pub fn maj_proper_list_p(x: Gc<Maj>) -> Gc<Maj> { let is_cons = maj_consp(x.clone()).to_bool(); let is_nil = maj_nilp(x.clone()).to_bool(); if !is_cons && !is_nil { return Maj::nil(); } let mut itr = x.clone(); while !maj_nilp(itr.clone()).to_bool() { if let Maj::Cons { car: _, cdr } = &*itr.clone() { itr = cdr.clone(); } else { return Maj::nil(); } } Maj::t() }
13. stringp
: Teste de String
Uma string é um vetor de caracteres. Portanto, qualquer vetor que
tenha char
como seu tipo será uma string.
pub fn maj_stringp(x: Gc<Maj>) -> Gc<Maj> { use crate::core::types::MajVector; if let Maj::Vector(v) = &*x { if let MajVector::Char(_) = &v { return Maj::t(); } } Maj::nil() }
14. literalp
: Teste de literal
Um literal é toda lista adequada que seja iniciada com o símbolo
lit
. Para tanto, basta que utilizemos car
, das funções primitivas,
para identificar tal símbolo, dado que a lista fornecida seja
adequada.
pub fn maj_literalp(x: Gc<Maj>) -> Gc<Maj> { if maj_proper_list_p(x.clone()).to_bool() && maj_eq(maj_car(x.clone()), Maj::lit()).to_bool() { return Maj::t(); } Maj::nil() }
15. primitivep
: Teste de primitivas
Uma primitiva não possui representação realmente. Todavia, utilizamos literais para representá-la no sistema; essas literais servirão para invocarmos tais primitivas, como se fossem clausuras, onde forem necessárias.
A representação literal de uma primitiva tem, como segundo elemento, o
símbolo prim
.
pub fn maj_primitivep(x: Gc<Maj>) -> Gc<Maj> { if maj_literalp(x.clone()).to_bool() { let sym = maj_car(maj_cdr(x)); if maj_eq(sym, Maj::prim()).to_bool() { return Maj::t(); } } Maj::nil() }
16. closurep
: Teste de clausura
Uma clausura é definida como uma literal, tal que seu segundo elemento
seja exatamente o símbolo closure
. Podemos utilizar car
e cdr
para
realizar essa comparação.
pub fn maj_closurep(x: Gc<Maj>) -> Gc<Maj> { if maj_literalp(x.clone()).to_bool() { let sym = maj_car(maj_cdr(x)); if maj_eq(sym, Maj::closure()).to_bool() { return Maj::t(); } } Maj::nil() }
17. functionp
: Teste de função
Uma função é um termo genérico que designa uma clausura ou uma primitiva. Sendo assim, qualquer desses dois será uma função.
pub fn maj_functionp(x: Gc<Maj>) -> Gc<Maj> { if maj_primitivep(x.clone()).to_bool() || maj_closurep(x).to_bool() { return Maj::t(); } Maj::nil() }
18. macrop
: Teste de macro
Um macro também é definido como um literal, tal que seu segundo elemento seja exatamente o símbolo macro, e seu terceiro elemento seja uma clausura.
pub fn maj_macrop(x: Gc<Maj>) -> Gc<Maj> { if maj_literalp(x.clone()).to_bool() { let sym = maj_car(maj_cdr(x)); if maj_eq(sym, Maj::macro_sym()).to_bool() { return Maj::t(); } } Maj::nil() }
19. errorp
: Teste de erro
Pela mesma lógica de closurep
e primitivep
, erros também são literais,
onde o segundo elemento precisa ser o símbolo error
. Demais elementos
serão a string de formato, e então demais objetos que ajudem a compor
esse formato.
pub fn maj_errorp(x: Gc<Maj>) -> Gc<Maj> { if maj_proper_list_p(x.clone()).to_bool() { let sym = maj_car(maj_cdr(x)); if maj_eq(sym, Maj::error()).to_bool() { return Maj::t(); } } Maj::nil() }
20. zerop
: Teste de nulidade numérica
(v. comparação numérica)
pub fn maj_zerop( mut state: &mut MajState, env: Gc<Maj>, x: Gc<Maj> ) -> Gc<Maj> { use crate::axioms::primitives::maj_arithm_eq; maj_arithm_eq(&mut state, env, Maj::integer(0), x, Maj::nil()) }
21. Registro em contexto global
De volta a axioms/predicates.rs
pub fn maj_gen_predicates(state: &mut MajState) { use crate::axioms::{ MajPrimFn, MajPrimArgs }; use crate::maj_destructure_args; let predicates: Vec<(&str, MajPrimArgs, MajPrimFn)> = vec![ ("symbolp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_symbolp(first) }), ("eq", MajPrimArgs::Required(2), |_, args, _| { maj_destructure_args!(args, first, rest, second); maj_eq(first, second) }), ("nilp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_nilp(first) }), ("consp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_consp(first) }), ("atomp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_atomp(first) }), ("charp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_charp(first) }), ("char=", MajPrimArgs::Required(2), |_, args, _| { maj_destructure_args!(args, first, rest, second); maj_char_equals(first, second) }), ("streamp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_streamp(first) }), ("numberp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_numberp(first) }), ("integerp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_integerp(first) }), ("floatp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_floatp(first) }), ("fractionp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_fractionp(first) }), ("complexp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_complexp(first) }), ("vectorp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_vectorp(first) }), ("id", MajPrimArgs::Required(2), |_, args, _| { maj_destructure_args!(args, first, rest, second); maj_id(first, second) }), ("proper-list-p", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_proper_list_p(first) }), ("stringp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_stringp(first) }), ("literalp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_literalp(first) }), ("primitivep", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_primitivep(first) }), ("closurep", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_closurep(first) }), ("functionp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_functionp(first) }), ("macrop", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_macrop(first) }), ("errorp", MajPrimArgs::Required(1), |_, args, _| { maj_destructure_args!(args, first); maj_errorp(first) }), ("zerop", MajPrimArgs::Required(1), |mut state, args, env| { maj_destructure_args!(args, first); maj_zerop(&mut state, env, first) }), ]; for predicate in predicates.iter() { let (name, arity, f) = predicate; state.register_primitive(name, *arity, *f); } }