]> Repositorios git - scryer-prolog.git/commitdiff
add op info to structures and atoms
authorMark Thom <[email protected]>
Sun, 20 Jan 2019 05:27:40 +0000 (22:27 -0700)
committerMark Thom <[email protected]>
Sun, 20 Jan 2019 05:27:40 +0000 (22:27 -0700)
Cargo.lock
Cargo.toml
src/prolog/heap_print.rs
src/prolog/instructions.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/read.rs
src/prolog/toplevel.rs
src/prolog/write.rs

index 3b053f79d4cdb397288e9918353979ead8170df7..4db77776db064b875e7c3d868e3ab6f0b32e6128 100644 (file)
@@ -86,7 +86,7 @@ dependencies = [
 
 [[package]]
 name = "prolog_parser"
-version = "0.7.19"
+version = "0.7.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -113,7 +113,7 @@ dependencies = [
  "downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "prolog_parser 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "prolog_parser 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -152,7 +152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
 "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
 "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
-"checksum prolog_parser 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "121df281a26fc692c1b8089bfdc0ba010a4af06379dec213446297c0c357713a"
+"checksum prolog_parser 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "68e88532e8eb09eb4606d47a53e0849643292bc253f14cb80b348f13591a050e"
 "checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
index d992eeaa67c91b378e60dc4e1f00940027b33f61..29bde88d23c884fcde672c4ae06db2b72fac740c 100644 (file)
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
 downcast = "0.9.1"
 num = "0.2"
 ordered-float = "0.5.0"
-prolog_parser = "0.7.19"
+prolog_parser = "0.7.20"
 
 [dependencies.termion]
 version = "1.4.0"
\ No newline at end of file
index 5e9a3968198157076fdff1bf519f651ed84d39bc..7ee7be26bed4bc1521a645ce54160caa69fb270e 100644 (file)
@@ -29,7 +29,7 @@ impl DirectedOp {
 #[derive(Clone)]
 pub enum TokenOrRedirect {
     Atom(ClauseName),
-    Op(ClauseName, Fixity),
+    Op(ClauseName, (usize, Specifier)),
     NumberedVar(String),
     CompositeRedirect(DirectedOp),
     Redirect,
@@ -298,25 +298,21 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         }
     }
 
-    fn enqueue_op(&mut self, ct: ClauseType, fixity: Fixity) {
-        match fixity {
-            Fixity::Post => {
-                self.state_stack.push(TokenOrRedirect::Op(ct.name(), fixity));
-                self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
-            },
-            Fixity::Pre => {
-                let left_directed_op = DirectedOp::Left(ct.name(), false);
-
-                self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
-                self.state_stack.push(TokenOrRedirect::Op(ct.name(), fixity));
-            },
-            Fixity::In => {
-                let left_directed_op = DirectedOp::Left(ct.name(), true);
-
-                self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
-                self.state_stack.push(TokenOrRedirect::Op(ct.name(), fixity));
-                self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
-            }
+    fn enqueue_op(&mut self, ct: ClauseType, spec: (usize, Specifier)) {        
+        if is_postfix!(spec.1) {
+            self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
+            self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
+        } else if is_prefix!(spec.1) {
+            let left_directed_op = DirectedOp::Left(ct.name(), false);
+
+            self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
+            self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
+        } else { // if is_infix!(spec.1)
+            let left_directed_op = DirectedOp::Left(ct.name(), true);
+
+            self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
+            self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
+            self.state_stack.push(TokenOrRedirect::CompositeRedirect(DirectedOp::Right(ct.name())));
         }
     }
 
@@ -337,9 +333,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
 
     fn format_clause(&mut self, iter: &mut HCPreOrderIterator, arity: usize, ct: ClauseType)
     {
-        if let Some(fixity) = ct.fixity() {
+        if let Some(spec) = ct.spec() {
             if !self.ignore_ops {
-                return self.enqueue_op(ct, fixity);
+                return self.enqueue_op(ct, spec);
             }
         } else if self.numbervars && is_numbered_var(&ct, arity) {
             let addr = iter.stack().last().cloned().unwrap();
@@ -410,11 +406,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         })
     }
 
-    fn print_atom(&mut self, atom: &ClauseName, fixity: Option<Fixity>) {
+    fn print_atom(&mut self, atom: &ClauseName, spec: Option<(usize, Specifier)>) {
         match atom.as_str() {
             "" => self.outputter.append("''"),
             ";" | "!" => self.outputter.append(atom.as_str()),
-            s => if fixity.is_some() || !self.quoted || non_quoted_token(s.chars()) {
+            s => if spec.is_some() || !self.quoted || non_quoted_token(s.chars()) {
                 self.outputter.append(atom.as_str())
             } else {
                 if self.quoted {
@@ -448,7 +444,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
 
     fn print_constant(&mut self, c: Constant, op: &Option<DirectedOp>) {
         match c {
-            Constant::Atom(ref atom, Some(fixity)) => {
+            Constant::Atom(ref atom, Some(spec)) => {
                 if let Some(ref op) = op {
                     if self.outputter.ends_with(&format!(" {}", op.as_str())) {
                         self.outputter.push_char(' ');
@@ -457,7 +453,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
                     self.outputter.push_char('(');
                 }
 
-                self.print_atom(atom, Some(fixity));
+                self.print_atom(atom, Some(spec));
 
                 if op.is_some() {
                     self.outputter.push_char(')');
@@ -545,12 +541,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
         };
 
         match heap_val {
-            HeapCellValue::NamedStr(arity, ref name, Some(fixity)) if name.as_str() != "," => {
+            HeapCellValue::NamedStr(arity, ref name, Some(spec)) if name.as_str() != "," => {
                 if op.is_some() {
                     self.state_stack.push(TokenOrRedirect::Close);
                 }
 
-                let ct = ClauseType::from(name.clone(), arity, Some(fixity));
+                let ct = ClauseType::from(name.clone(), arity, Some(spec));
                 self.format_clause(iter, arity, ct);
 
                 if let Some(ref op) = op {
@@ -612,8 +608,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
                 match loc_data {
                     TokenOrRedirect::Atom(atom) =>
                         self.print_atom(&atom, None),
-                    TokenOrRedirect::Op(atom, fixity) =>
-                        self.print_atom(&atom, Some(fixity)),
+                    TokenOrRedirect::Op(atom, spec) =>
+                        self.print_atom(&atom, Some(spec)),
                     TokenOrRedirect::NumberedVar(num_var) =>
                         self.outputter.append(num_var.as_str()),
                     TokenOrRedirect::CompositeRedirect(op) =>
@@ -637,9 +633,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
                             self.outputter.push_char(']');
                         },
                     TokenOrRedirect::HeadTailSeparator =>
-//                      if !self.ignore_ops {
-                            self.outputter.append(" | "),
-//                      },
+                        self.outputter.append(" | "),
                     TokenOrRedirect::Comma =>
                         self.outputter.append(", ")
                 }
index bd5e2f2cf09d062f582c00a2d4ee3ac97be97a7b..5eba3a97dd4fbe1666147933b0b86dd6825e6987 100644 (file)
@@ -270,10 +270,6 @@ pub enum SystemClauseType {
 }
 
 impl SystemClauseType {
-    pub fn fixity(&self) -> Option<Fixity> {
-        None
-    }
-
     pub fn name(&self) -> ClauseName {
         match self {
             &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
@@ -425,20 +421,11 @@ pub enum ClauseType {
     Hook(CompileTimeHook),
     Inlined(InlinedClauseType),
     Named(ClauseName, CodeIndex),
-    Op(ClauseName, Fixity, CodeIndex),
+    Op(OpDecl, CodeIndex),
     System(SystemClauseType)
 }
 
 impl BuiltInClauseType {
-    fn fixity(&self) -> Option<Fixity> {
-        match self {
-            &BuiltInClauseType::Compare | &BuiltInClauseType::CompareTerm(_)
-          | &BuiltInClauseType::NotEq   | &BuiltInClauseType::Is(..) | &BuiltInClauseType::Eq
-                => Some(Fixity::In),
-            _ => None
-        }
-    }
-
     pub fn name(&self) -> ClauseName {
         match self {
             &BuiltInClauseType::AcyclicTerm => clause_name!("acyclic_term"),
@@ -507,12 +494,16 @@ impl BuiltInClauseType {
 }
 
 impl ClauseType {
-    pub fn fixity(&self) -> Option<Fixity> {
-        match self {
-            &ClauseType::BuiltIn(ref built_in) => built_in.fixity(),
-            &ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) => Some(Fixity::In),
-            &ClauseType::Op(_, fixity, _) => Some(fixity),
-            &ClauseType::System(ref system) => system.fixity(),
+    pub fn spec(&self) -> Option<(usize, Specifier)> {
+        match self {            
+            &ClauseType::Op(ref op_decl, _) =>
+                Some((op_decl.0, op_decl.1)),
+            &ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
+          | &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
+          | &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))      
+          | &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
+          | &ClauseType::BuiltIn(BuiltInClauseType::Eq) =>
+                Some((700, XFX)),
             _ => None
         }
     }
@@ -523,13 +514,13 @@ impl ClauseType {
             &ClauseType::BuiltIn(ref built_in) => built_in.name(),
             &ClauseType::Hook(ref hook) => hook.name(),
             &ClauseType::Inlined(ref inlined) => clause_name!(inlined.name()),
-            &ClauseType::Op(ref name, ..) => name.clone(),
+            &ClauseType::Op(ref op_decl, ..) => op_decl.name(),
             &ClauseType::Named(ref name, ..) => name.clone(),
             &ClauseType::System(ref system) => system.name(),
         }
     }
 
-    pub fn from(name: ClauseName, arity: usize, fixity: Option<Fixity>) -> Self {
+    pub fn from(name: ClauseName, arity: usize, spec: Option<(usize, Specifier)>) -> Self {
         InlinedClauseType::from(name.as_str(), arity)
             .map(ClauseType::Inlined)
             .unwrap_or_else(|| {
@@ -539,8 +530,9 @@ impl ClauseType {
                         SystemClauseType::from(name.as_str(), arity)
                             .map(ClauseType::System)
                             .unwrap_or_else(|| {
-                                if let Some(fixity) = fixity {
-                                    ClauseType::Op(name, fixity, CodeIndex::default())
+                                if let Some(spec) = spec {
+                                    let op_decl = OpDecl(spec.0, spec.1, name);
+                                    ClauseType::Op(op_decl, CodeIndex::default())
                                 } else if name.as_str() == "call" {
                                     ClauseType::CallN
                                 } else {
@@ -844,7 +836,7 @@ impl Ref {
 #[derive(Clone, PartialEq)]
 pub enum HeapCellValue {
     Addr(Addr),
-    NamedStr(usize, ClauseName, Option<Fixity>), // arity, name, fixity if it has one.
+    NamedStr(usize, ClauseName, Option<(usize, Specifier)>), // arity, name, fixity if it has one.
 }
 
 impl HeapCellValue {
@@ -1098,9 +1090,10 @@ impl<'a> TermIterState<'a> {
         match term {
             &Term::AnonVar =>
                 TermIterState::AnonVar(lvl),
-            &Term::Clause(ref cell, ref name, ref subterms, fixity) => {
-                let ct = if let Some(fixity) = fixity {
-                    ClauseType::Op(name.clone(), fixity, CodeIndex::default())
+            &Term::Clause(ref cell, ref name, ref subterms, spec) => {
+                let ct = if let Some(spec) = spec {
+                    let op_decl = OpDecl(spec.0, spec.1, name.clone());
+                    ClauseType::Op(op_decl, CodeIndex::default())
                 } else {
                     ClauseType::Named(name.clone(), CodeIndex::default())
                 };
@@ -1503,6 +1496,11 @@ impl From<ParserError> for EvalSession {
 pub struct OpDecl(pub usize, pub Specifier, pub ClauseName);
 
 impl OpDecl {
+    #[inline]
+    pub fn name(&self) -> ClauseName {
+        self.2.clone()
+    }
+        
     pub fn submit(&self, module: ClauseName, op_dir: &mut OpDir) -> Result<(), SessionError>
     {
         let (prec, spec, name) = (self.0, self.1, self.2.clone());
index 641a103feb5192ed3bcdcd367c02e510c3ed7f51..909ad4cb9761806bd4fd8963cc4645ba9a5b7423 100644 (file)
@@ -22,7 +22,7 @@ pub(super) struct MachineError {
 impl MachineError {
     pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
         let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name, None)));
-        functor!("/", 2, [name, heap_integer!(arity)], Fixity::In)
+        functor!("/", 2, [name, heap_integer!(arity)], (400, YFX))
     }
 
     pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
@@ -47,8 +47,8 @@ impl MachineError {
 
         stub.append(&mut functor!("/", 2, [HeapCellValue::Addr(Addr::HeapCell(h + 2 + 3)),
                                            heap_integer!(arity)],
-                                  Fixity::In));
-        stub.append(&mut functor!(":", 2, [mod_name, name], Fixity::In));
+                                  (400, YFX)));
+        stub.append(&mut functor!(":", 2, [mod_name, name], (600, XFY)));
 
         MachineError { stub, from: ErrorProvenance::Constructed }
     }
@@ -258,7 +258,7 @@ impl MachineState {
                     loop {
                         match self.heap[new_l].clone() {
                             HeapCellValue::Addr(Addr::Str(l)) => new_l = l,
-                            HeapCellValue::NamedStr(2, ref name, Some(Fixity::In))
+                            HeapCellValue::NamedStr(2, ref name, Some(_))
                                 if name.as_str() == "-" => break,
                             HeapCellValue::Addr(Addr::HeapCell(_)) => break,
                             HeapCellValue::Addr(Addr::StackCell(..)) => break,
@@ -278,7 +278,7 @@ impl MachineState {
 
     // see 8.4.4 of Draft Technical Corrigendum 2.
     pub(super) fn check_keysort_errors(&self) -> CallResult {
-        let stub   = MachineError::functor_stub(clause_name!("keysort"), 2);
+        let stub   = MachineError::functor_stub(clause_name!("keysort"), 2);        
         let pairs  = self.store(self.deref(self[temp_v!(1)].clone()));
         let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
 
index 16881958be31a6fccaf7a6bd4cd230c783848287..d709540a330c97bd6ddf990504d936efa16eebd8 100644 (file)
@@ -567,7 +567,7 @@ impl MachineState {
 
         for heap_val in self.post_order_iter(a) {
             match heap_val {
-                HeapCellValue::NamedStr(2, name, Some(Fixity::In)) => {
+                HeapCellValue::NamedStr(2, name, Some(_)) => {
                     let a2 = interms.pop().unwrap();
                     let a1 = interms.pop().unwrap();
 
@@ -597,7 +597,7 @@ impl MachineState {
                                                             caller))
                     }
                 },
-                HeapCellValue::NamedStr(1, name, Some(Fixity::Pre)) => {
+                HeapCellValue::NamedStr(1, name, Some(_)) => {
                     let a1 = interms.pop().unwrap();
 
                     match name.as_str() {
@@ -1033,7 +1033,7 @@ impl MachineState {
                         let h = self.heap.h;
 
                         self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1)));
-                        self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.fixity()));
+                        self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
 
                         self.bind(addr.as_var().unwrap(), Addr::HeapCell(h));
 
@@ -1214,7 +1214,7 @@ impl MachineState {
             &QueryInstruction::PutStructure(ref ct, arity, reg) => {
                 let h = self.heap.h;
 
-                self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.fixity()));
+                self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
                 self[reg] = Addr::Str(h);
             },
             &QueryInstruction::PutUnsafeValue(n, arg) => {
@@ -1969,7 +1969,7 @@ impl MachineState {
                 Err(self.error_form(MachineError::instantiation_error(), stub)),
             Addr::Str(s) =>
                 match self.heap[s].clone() {
-                    HeapCellValue::NamedStr(2, ref name, Some(Fixity::In))
+                    HeapCellValue::NamedStr(2, ref name, Some(_))
                         if *name == clause_name!("-") =>
                            Ok(Addr::HeapCell(s+1)),
                     _ => Err(self.error_form(MachineError::type_error(ValidType::Pair,
@@ -2164,7 +2164,7 @@ impl MachineState {
                 try_or_fail!(self, call_policy.compile_hook(self, hook)),
             &ClauseType::Inlined(ref ct) =>
                 self.execute_inlined(ct),
-            &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) =>
+            &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(OpDecl(.., ref name), ref idx) =>
                 try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
                                                             indices)),
             &ClauseType::System(ref ct) =>
index cde0834626accbdb8e6bba3d3a8c6bcebf352246..3b6053c0485e42568d42e6fc7165d4ae3afba55c 100644 (file)
@@ -105,7 +105,7 @@ pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) ->
             },
             &TermRef::Clause(lvl, _, ref ct, subterms) => {
                 queue.push_back((subterms.len(), h+1));
-                let named = HeapCellValue::NamedStr(subterms.len(), ct.name(), ct.fixity());
+                let named = HeapCellValue::NamedStr(subterms.len(), ct.name(), ct.spec());
 
                 machine_st.heap.push(named);
 
index ee1fe25f2f2ff70be29ecff5055c325e7d3b225f..cc8be68e67858b18c1967e2a2cff53e85c38fa76 100644 (file)
@@ -55,16 +55,16 @@ impl<'a, 'b> CompositeIndices<'a, 'b>
         }
     }
 
-    fn get_clause_type(&mut self, name: ClauseName, arity: usize, fixity: Option<Fixity>) -> ClauseType
+    fn get_clause_type(&mut self, name: ClauseName, arity: usize, spec: Option<(usize, Specifier)>) -> ClauseType
     {
-        match ClauseType::from(name, arity, fixity) {
+        match ClauseType::from(name, arity, spec) {
             ClauseType::Named(name, _) => {
                 let idx = self.get_code_index(name.clone(), arity);
                 ClauseType::Named(name, idx.clone())
             },
-            ClauseType::Op(name, fixity, _) => {
-                let idx = self.get_code_index(name.clone(), arity);
-                ClauseType::Op(name, fixity, idx.clone())
+            ClauseType::Op(op_decl, _) => {
+                let idx = self.get_code_index(op_decl.2.clone(), arity);
+                ClauseType::Op(op_decl, idx.clone())
             },
             ct => ct
         }
@@ -158,7 +158,7 @@ fn setup_op_decl(mut terms: Vec<Box<Term>>) -> Result<OpDecl, ParserError>
 fn setup_predicate_export(mut term: Term) -> Result<PredicateKey, ParserError>
 {
     match term {
-        Term::Clause(_, ref name, ref mut terms, Some(Fixity::In))
+        Term::Clause(_, ref name, ref mut terms, Some(_))
             if name.as_str() == "/" && terms.len() == 2 => {
                 let arity = *terms.pop().unwrap();
                 let name  = *terms.pop().unwrap();
index 956b221c306a3a40403eea3703f1a6b5685a8cec..798e0ff10f8df2d931822d6fb6047d5275ec4539 100644 (file)
@@ -117,7 +117,8 @@ impl fmt::Display for CompareTermQT {
 impl fmt::Display for ClauseType {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) => {
+            &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(OpDecl(.., ref name), ref idx) =>
+            {
                 let idx = idx.0.borrow();
                 write!(f, "{}:{}/{}", idx.1, name, idx.0)
             },
@@ -296,7 +297,7 @@ pub fn print(wam: &mut Machine, result: EvalSession) {
                 println!("true.");
                 return;
             }
-            
+
             if !wam.or_stack_is_empty() {
                 println!("true .");
             }