Page 1 of 1

How to approach fuzzy match

Posted: 3 Apr 2021 1:59
by dcgreenwood
Is there a simple way using backtracking to find a match between a set of variables and a database of facts where the match may not be perfect?
For example

Code: Select all

domains         myDomain : good; bad ; ok. class facts         myFactDB : (myDomain VarA, myDomain VarB, myDomain VarC, myDomain VarD).   %assume I have a database of myFactDB with different combinations of the variables, but not all possible combinations           predicates         findMatch(myDomain VarA, myDomain VarB,myDomain VarC,myDomain VarD).         clauses         findMatch(VarA,VarB,VarC,VarD):-         myFactDB(VarA,VarB,VarC,VarD.        
Assuming I got my syntax right, this should find the database entry that matches VarA,VarB,VarC,VarD. But how can I approach writing a clause that will find a match of 3 of the 4 variables, if there isn't a perfect match? I can think of how to do it with separate clauses with all combinations of one or more of the variable set as anonymous, but is there any other way? Should I try something other than a fact database, such as lists?

Re: How to approach fuzzy match

Posted: 3 Apr 2021 11:36
by Harrison Pratt

Code: Select all

domains     myDomain = good; bad; ok.     myDomainList = myDomain*.   class facts     myFactDB : (myDomain VarA, myDomain VarB, myDomain VarC, myDomain VarD).   class predicates     getMatchN_nd : (integer Count, myDomainList TestList) -> myDomainList MatchingValues nondeterm. clauses     getMatchN_nd(N, TestList) = FactValues :-         myFactDB(VarA, VarB, VarC, VarD),         FactValues = [VarA, VarB, VarC, VarD],         list::length(list::intersection(FactValues, TestList)) >= N.  % want at least N matches   clauses     run() :-         write("\n\n", "Testing", "\n\n"),         NumWant = 1,         ValuesWant = [good, good, ok],         assert(myFactDB(good, good, bad, ok)),         assert(myFactDB(bad, bad, bad, ok)),         assert(myFactDB(good, bad, good, bad)),         MM = getMatchN_nd(NumWant, ValuesWant),         stdio::write("\nWrite matched ", NumWant, " of ", MM),         fail.     run() :-         write("\nFAILED\n"),         _ = readLine().

Re: How to approach fuzzy match

Posted: 3 Apr 2021 13:43
by dcgreenwood
Thanks, I'll use that!

Re: How to approach fuzzy match

Posted: 3 Apr 2021 18:40
by Gukalov

Code: Select all

implement main     open core   domains     myDomain = good; bad; ok.   clauses     run() :-         L1 = [ good, good , bad, ok ],         L2 = [ bad, bad , good, ok ],           L3 = list::intersection(L1, L2),         console::write("Intersection12 = ", L3, "\n"),           L4 = list::intersection(L2, L1),         console::write("Intersection21 = ", L4, "\n"),           L5 = [ X || tuple(X, X) = list::zip_nd(L1, L2) ],         console::write("Real matches = ", L5, "\n"),           _ = console::readChar().   end implement main   goal     console::runUtf8(main::run).   %Intersection12 = [good,good,bad,ok] %Intersection21 = [bad,bad,good,ok] %Real matches = [ok]