Skip to content

Instantly share code, notes, and snippets.

@Anniepoo
Created January 31, 2020 20:58
Show Gist options
  • Save Anniepoo/1ddad55a9661ba37b3f6cde310004b08 to your computer and use it in GitHub Desktop.
Save Anniepoo/1ddad55a9661ba37b3f6cde310004b08 to your computer and use it in GitHub Desktop.
:- module(clpstr, [
cl_len/2,
cl_regex/2,
cl_insensitive/2,
cl_str/1
]).
/** <module> Constraint Logic Programming over strings
*
* constraints over 'real' strings
*/
:- use_module(library(chr)).
:- use_module(library(clpfd)).
:- chr_constraint cl_len/2, cl_regex/2, cl_insensitive/2, cl_str/1.
%! cl_len(+Str:text, +Len:integer) is semidet
%
% adds a constraint on Str to be Len
%
% only one length constraint
cl_len(Str, Len1) \ cl_len(Str, Len2) <=> Len1 #= Len2.
% we only test length once
cl_len(Str, Len) <=> ground(Str) |
(string(Str) ; is_list(Str) ; atom(Str)),
string_length(Str, X),
X #= Len.
% in a real library we'd try to figure out if there were
% length constraints inconsistent with shortest possible match, or
% impossible to satisfy between two regexs.
% we also might want to have a wrapper prolog that compiles the regex
% and have some extended copy_term that copies the constraints
cl_regex(Regex, Str) <=> ground(Str), ground(Regex) | re_match(Regex, Str).
cl_insensitive(A,B) <=> ground(A), ground(B) |
string_lower(A, L),
string_lower(B, L).
cl_str(A) <=> \+ var(A) | string(A).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment