From: Mark Thom Date: Sun, 28 Oct 2018 02:56:23 +0000 (-0600) Subject: update dcgs to handle ; and -> X-Git-Tag: v0.8.110~322 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=81f4128bc60768a8b378d361272f3ff24279e13c;p=scryer-prolog.git update dcgs to handle ; and -> --- diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index 50437cca..013684d8 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -4,6 +4,7 @@ use prolog_parser::tabled_rc::*; use std::cell::{Cell, RefCell}; use std::collections::{BTreeSet, HashMap, VecDeque}; use std::cmp::Ordering; +use std::fmt; use std::ops::{Add, AddAssign, Index, IndexMut, Sub}; use std::rc::Rc; @@ -660,6 +661,18 @@ pub enum Addr { Str(usize) } +impl fmt::Display for Addr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + &Addr::Con(ref c) => write!(f, "Addr::Con({})", c), + &Addr::Lis(l) => write!(f, "Addr::Lis({})", l), + &Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h), + &Addr::StackCell(fr, sc)=> write!(f, "Addr::StackCell({}, {})", fr, sc), + &Addr::Str(s) => write!(f, "Addr::Str({})", s) + } + } +} + impl PartialEq for Addr { fn eq(&self, r: &Ref) -> bool { self.as_var() == Some(*r) diff --git a/src/prolog/lib/dcgs.pl b/src/prolog/lib/dcgs.pl index d6d2f759..e3ac00a0 100644 --- a/src/prolog/lib/dcgs.pl +++ b/src/prolog/lib/dcgs.pl @@ -1,6 +1,7 @@ :- module(dcgs, [(-->)/2, phrase/2, phrase/3]). :- use_module(library(lists), [append/3]). +:- use_module(library(terms)). :- op(1200, xfx, -->). @@ -19,40 +20,51 @@ phrase(G, Ls0, Ls2) :- phrase(G, Ls0, Ls1) :- call(G, Ls0, Ls1). -term_expansion(Term0, (ModHead :- ModBody)) :- +term_expansion(Term0, Term) :- + numbervars(Term0, 0, N), + expand_dcgs(Term0, N, Term). + +expand_dcgs(Term0, N, (ModHead :- ModBody)) :- nonvar(Term0), Term0 = (Head, [SC | SCs] --> Body), !, nonvar(Head), Head =.. [RuleName | Args], - append([SC | SCs], '$VAR'(N), SemiContextArgs), - append(Args, ['$VAR'(0), SemiContextArgs], ModArgs), + append([SC | SCs], '$VAR'(N1), SemiContextArgs), + append(Args, ['$VAR'(N), SemiContextArgs], ModArgs), ModHead =.. [RuleName | ModArgs], nonvar(Body), - expand_body(Body, ModBody, 0, N). -term_expansion(Term0, (ModHead :- ModBody)) :- + expand_body(Body, ModBody, 0, N1). +expand_dcgs(Term0, N, (ModHead :- ModBody)) :- nonvar(Term0), Term0 = (Head --> Body), nonvar(Head), Head =.. [RuleName | Args], - append(Args, ['$VAR'(0), '$VAR'(N)], ModArgs), + append(Args, ['$VAR'(N), '$VAR'(N1)], ModArgs), ModHead =.. [RuleName | ModArgs], nonvar(Body), - expand_body(Body, ModBody, 0, N). + expand_body(Body, ModBody, N, N1). expand_body(Term0, (ModTerm, ModTerms), N0, N) :- nonvar(Term0), Term0 = (Term, Terms), !, nonvar(Term), expand_body_term(Term, ModTerm, N0, N1), expand_body(Terms, ModTerms, N1, N). -expand_body(Term0, ModTerm, N0, N) :- - nonvar(Term0), expand_body_term(Term0, ModTerm, N0, N). +expand_body(Term0, ModTerm, N0, N) :- + nonvar(Term0), + expand_body_term(Term0, ModTerm, N0, N). expand_body_term([], true, N, N) :- !. expand_body_term([Arg|Args], ModTerm, N0, N) :- !, N is N0 + 1, append([Arg|Args], '$VAR'(N), ModArgs), ModTerm = ('$VAR'(N0) = ModArgs). +expand_body_term((P -> Q), (PModTerm -> QModTerm), N0, N) :- + !, expand_body(P, PModTerm, N0, N1), + expand_body(Q, QModTerm, N1, N). +expand_body_term((P ; Q), (PModTerm ; QModTerm), N0, N) :- + !, expand_body(P, PModTerm, N0, N), + expand_body(Q, QModTerm, N0, N). expand_body_term(CommaTerm, ModTerm, N, N) :- CommaTerm =.. [{} | BodyTerms], !, comma_ify(BodyTerms, ModTerm).